summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.html
blob: 124c62e3726596d3a50dada994f53a4e20226b2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>

<head>
	<title>wotonomy ui user guide</title>
	<meta name="author" content="">
	<meta name="GENERATOR" content="Almost Free Text v5.06; Copyright 1996-2000 Todd Coram. All rights reserved.">
</head>

<body>

	<br>
	<h1><a name="AFT-top">
			<center>wotonomy ui user guide</center>
		</a></h1>
	<!--  AFT Table of Contents (auto generated) -->
	<ul>
		<li> <a href="#Introduction">Introduction</a></li>
		<ul>
			<li> <a href="#Scope">Scope</a></li>
			<li> <a href="#Overview">Overview</a></li>
			<ul>
				<li> <a href="#Where does it fit in?">Where does it fit in?</a></li>
				<li> <a href="#A Typical MVC Java application">A Typical MVC Java application</a></li>
				<li> <a href="#A Typical wotonomy Application">A Typical wotonomy Application</a></li>
				<li> <a href="#Expanded Framework">Expanded Framework</a></li>
			</ul>
		</ul>
		<li> <a href="#Using wotonomy">Using wotonomy</a></li>
		<ul>
			<li> <a href="#Designing Data Objects">Designing Data Objects</a></li>
			<ul>
				<li> <a href="#Java Bean Conventions">Java Bean Conventions</a></li>
				<li> <a href="#Change Notification">Change Notification</a></li>
			</ul>
			<li> <a href="#Display Groups">Display Groups</a></li>
			<ul>
				<li> <a href="#Creating a Display Group">Creating a Display Group</a></li>
				<li> <a href="#Populating a Display Group">Populating a Display Group</a></li>
				<li> <a href="#Qualifying Displayed Objects">Qualifying Displayed Objects</a></li>
				<li> <a href="#Handling Selection">Handling Selection</a></li>
				<li> <a href="#Handling Insertions and Deletions">Handling Insertions and Deletions</a></li>
				<li> <a href="#Delegate">Delegate</a></li>
			</ul>
			<li> <a href="#Associations">Associations</a></li>
			<ul>
				<li> <a href="#Creating Associations">Creating Associations</a></li>
				<li> <a href="#Kinds of Associations">Kinds of Associations</a></li>
				<li> <a href="#Master-Detail Associations">Master-Detail Associations</a></li>
				<li> <a href="#Binding Aspects and Establishing Connections">Binding Aspects and Establishing
						Connections</a></li>
			</ul>
			<li> <a href="#Editing Contexts">Editing Contexts</a></li>
			<ul>
				<li> <a href="#Object Stores">Object Stores</a></li>
				<li> <a href="#Creating an Editing Context">Creating an Editing Context</a></li>
			</ul>
		</ul>
		<li> <a href="#What's next?">What's next?</a>

		</li>
	</ul>
	<h2><a name="Introduction">Introduction</a></h2>
	<h3><a name="Scope">Scope</a></h3>
	<p>
		This document is intended to serve as a Java developer's introduction to the wotonomy user interface framework
		and how to use it to build a graphical user interface application with Swing.
	</p>
	<!--End Section h3-->
	<h3><a name="Overview">Overview</a></h3>
	<p>
		The wotonomy user interface package contained in net.wotonomy.ui provides a design pattern that further
		abstracts and decouples the model, view, and controller portions of a graphical user interface application. It
		lets you do more with less code.
	</p>
	<h4><a name="Where does it fit in?">Where does it fit in?</a></h4>
	<p>
		Let's begin by looking at the standard model-view-controller (MVC) architecture, and then we'll look at how the
		design changes with wotonomy.
	</p>
	<!--End Section h4-->
	<h4><a name="A Typical MVC Java application">A Typical MVC Java application</a></h4>
	<p>
		A typical Java application can be described in a very high-level way as simply reading a bunch of data objects
		into memory from the file system or JDBC or elsewhere and rendering a graphical representation of the data for
		the user. Additionally, the user may be allowed to edit some or all the data represented, and in that case the
		modifications are copied back from whence they were read.
	</p>
	<img src="images/standard-mvc.gif" alt="" align=bottom>
	<p>
		In MVC parlance, the model is an object-oriented representation of your data and business logic. In the typical
		application example, the data objects are the model. To afford maximum reuse, these data objects have no
		knowledge of and no dependencies on the view or controller portions of your application. In the Enterprise Java
		Bean (EJB) world, entity beans are usually good examples of data objects.
	</p>
	<p>
		The view is the user interface of your application, where the data objects are represented on screen using
		labels, text fields, sliders, and the like. While you might need to know a little bit about the data you are
		trying to visualize when constructing the user interface, the view classes have no code dependencies on the data
		object classes in the model. And the view similarly has no code dependencies on the controller. To afford
		maximum flexibility, the view consists only of the Swing components arranged in the proper layouts and nothing
		more.
	</p>
	<p>
		The controller, on the other hand, contains the logic specific to the Java Swing application you are writing,
		and it is tightly coupled with and has deep code dependencies on the model and view.
	</p>
	<p>
		The controller is responsible for fetching the data objects that will be viewed or edited, and is responsible
		for populating each user interface component in the view with data from the data objects. This means that the
		controller directly calls methods on both the model's data objects and the view's user interface components.
	</p>
	<p>
		If the application supports editing, the controller is responsible for even more. It must detect changes to the
		view, like edited text fields or moved sliders, and update the model to reflect the changes. And it must detect
		changes in the model and update the view components accordingly (especially for side-effect changes like a
		task's status changing in the data model when the user assigns a worker). These responsibilities deepen the
		couplings with both the model and the view.
	</p>
	<p>
		Furthermore, the controller must track commits and reverts of sets of changes to the data model, and it must
		track lists of edited, added, and deleted objects to efficiently update the persistent data store. And these
		responsibilities deepen the complexity of the logic contained in the controller.
	</p>
	<!--End Section h4-->
	<h4><a name="A Typical wotonomy Application">A Typical wotonomy Application</a></h4>
	<p>
		Because so much code resides in the controller portion of an application, and because the controller is the
		least generic and therefore least reusable code in an application, wotonomy is designed to abstract and simplify
		the responsibilities of the controller to reduce the cost of writing and maintaining it.
	</p>
	<img src="images/wotonomy-mvc.gif" alt="" align=bottom>
	<p>
		With wotonomy, the only requirement on the model portion of your application is that the data objects adhere to
		Java Bean naming conventions for properties. Wotonomy further decouples your model from the rest of your
		application by working with it only through the use of bean properties.
	</p>
	<p>
		The view portion of your application remains the same. The controller portion, however, is vastly simplified.
	</p>
	<p>
		The fetched data objects are placed into an EditingContext. The editing context monitors the objects for
		changes, and tracks insertions and deletions, and handles commits and reverts. The controller is only
		responsible for providing the glue to allow the editing context to talk to whatever persistent object storage is
		used for the application. If your data is read only or if your data model is fairly simple, then the editing
		context can be omitted and your job is even easier.
	</p>
	<p>
		A DisplayGroup then retrieves some or all of those objects from the EditingContext. A display group maintains an
		ordered collection of objects, monitoring them for changes. The display group additionally tracks the concept of
		selection: a subset of objects in the display group are selected, and the selection might contain zero, one,
		many, or all objects in the group. The display group broadcasts notifications of changes to the data object or
		to the selection to interested listeners. The controller is only responsible for creating the display group and
		deciding what objects from the editing context should be placed in the group.
	</p>
	<p>
		An Association is then created for each user interface component in the view. Each association is bound to the
		display group as a listener for change notifications. Different types of associations correspond to different
		kinds of user interface objects: a JTextField with a TextAssociation will display the value of a property for
		the selected object in the bound display group, while a TableColumn with a TableColumnAssociation will display
		the value of a property for all objects in the bound display group, highlighting those objects that are
		selected. The controller is only responsible for creating the associations, connecting them to the user
		interface components, and binding them to the display group.
	</p>
	<p>
		Your controller will not need to directly touch any data objects, and will only need to access the view to get
		references to the user interface components and pass them on to the associations. After all the pieces are
		connected, they'll just work and it's pretty much fire and forget.
	</p>
	<!--End Section h4-->
	<h4><a name="Expanded Framework">Expanded Framework</a></h4>
	<p>
		On the whole, an application may have one or more editing contexts, each of which may be used by one or more
		display groups, each of which is observed by one or more associations, each of which is connected to a single
		user interface component. But there's a little more to this story.
	</p>
	<img src="images/wotonomy-er.gif" alt="" align=bottom>
	<p>
		As the diagram shows, a display group actually has a data source which has an editing context, and editing
		contexts have object stores which can in turn be editing contexts. This means that editing contexts can be
		nested within one another. And there are associations that can control a display group instead of a Swing
		component, which means that display groups can also be nested.
	</p>
	<p>
		However, you can write a fully-functional application using just display groups and associations, skipping the
		editing contexts and data sources completely.
	</p>
	<p>
		Wotonomy makes the simple things easy while still making complex things possible.
	</p>
	<!--End Section h4-->
	<!--End Section h3-->
	<!--End Section h2-->
	<h2><a name="Using wotonomy">Using wotonomy</a></h2>
	<p>
		Wotonomy is a design pattern as well as a Java library, so you'll want to understand how to structure your
		application to best leverage the framework.
	</p>
	<h3><a name="Designing Data Objects">Designing Data Objects</a></h3>
	<p>
		In short, any objects that have getter and setter methods can be used in a display group. Your objects probably
		have those already. Even better are objects that use Java Bean naming conventions to define properties. You
		probably do that too. For change notifications, extending java.util.Observable is helpful, but since your
		objects probably don't already do that, there is an alternate way to post change notifications. Or you can
		choose to not post notifications at all. The requirements of wotonomy on your data model are minimal.
	</p>
	<h4><a name="Java Bean Conventions">Java Bean Conventions</a></h4>
	<p>
		A java bean property is defined by having a method of the form getProperty() where Property is the name of the
		property, for example, a name property is defined by the method getName(). The get method can have no parameters
		and the return type defines the type of the property. (The alternate form for getters that omits the get in the
		method name, e.g. property(), is also supported.)
	</p>
	<p>
		An editable property is defined by additionally having a method of the form setProperty( Object aProperty )
		where the return value is void and the type of the parameter matches the type of the getter method. (When a
		property has a getter method but no setter method, that property is considered-read only.)
	</p>
	<p>
		An indexed property works the same way but the type is either an Array (like Object[] or String[]) or a
		Collection (like Set or List). Indexed properties typically define one-to-many relationships in your data model.
		Indexed properties are useful for nested display groups and recursive tree associations.
	</p>
	<!--End Section h4-->
	<h4><a name="Change Notification">Change Notification</a></h4>
	<p>
		The Java way for objects to post change notifications is to extend java.util.Observable and call
		notifyObservers() after your change has taken place. If your data object extends Observable, DisplayGroups will
		register themselves as observers and expect notifications for changes that occur to the object, whether from
		user interaction or from external influence.
	</p>
	<p>
		The Observable approach may be undesirable if you need to subclass a third party object that does not extend
		Observable or if you don't want a strong reference to an observer from your data object that may need to be
		manually cleared later.
	</p>
	<p>
		For objects that do not extend Observer, you can get much the same effect by calling the static method <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html#notifyObserversObjectWillChange">EOObserverCenter.notifyObserversObjectWillChange()</a>
		before your change takes place.
	</p>
	<p>
		Wotonomy uses <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html">EOObserverCenter</a>
		exclusively within the framework and it presents a preferrable alternative to Observable because it uses weak
		references to track objects and it relaxes the requirement that observed objects extend a particular class by
		requiring that observing objects implement the EOObserving interface. The EOObserverCenter can also coalesce
		change events if the observing object extends <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODelayedObserver.html">EODelayedObserver</a>.
	</p>
	<p>
		Please note that if your object does not post change notifications, most of wotonomy will continue to work. The
		only problem will then be that changes external to wotonomy - changes made to your data model by your data model
		or by a timed refresh or something similar - will not be automatically reflected in the user interface. Manually
		calling <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html#updateDisplayedObjects">EODisplayGroup.updateDisplayedObjects()</a>
		can refresh the display.
	</p>
	<!--End Section h4-->
	<!--End Section h3-->
	<h3><a name="Display Groups">Display Groups</a></h3>
	<p>
		<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html">Display groups</a> are
		objects that manage an ordered list of data objects. Of this list, a subset are considered to be
		&quot;displayed&quot; objects that are visible to the user. Of the displayed objects, a subset are considered
		&quot;selected&quot;. In common usage, all of the objects are displayed, but only one object and sometimes no
		objects are selected.
	</p>
	<p>
		Display groups monitor changes to the list, changes to what objects are in the list, changes to which objects
		are selected, as well as changes to the properties of the objects themselves, and notify any bound associations
		of these changes.
	</p>
	<p>
		If the display group has a delegate, the delegate is informed of these changes and more so that the delegate can
		fine-tune the behavior of the display group.
	</p>
	<h4><a name="Creating a Display Group">Creating a Display Group</a></h4>
	<p>
		A display group is created very simply with the default constructor.
		This creates a display group with no data source, no delegate, and no objects to manage.
	</p>
	<pre>
    EODisplayGroup displayGroup = new EODisplayGroup();
</pre>
	<!--End Section h4-->
	<h4><a name="Populating a Display Group">Populating a Display Group</a></h4>
	<p>
		You can populate the display group with objects in two ways.
	</p>
	<p>
		The direct way is easiest. Simply pass in a List containing the objects to be managed in the order they should
		appear.
	</p>
	<pre>
    List objectList = new LinkedList();
    objectList.add( new TestObject() );
    displayGroup.setObjectArray( objectList );
</pre>
	<p>
		Alternately, you can specify a data source for the display group to use to retrieve objects.
	</p>
	<p>
		<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODataSource.html">EODataSource</a> is an
		abstract class that you will extend with methods to create, insert, and delete objects from whatever persistent
		object store you are using. This class is particularly useful for rendering recursive tree-like object
		relationships that the data objects do not explicitly model.
	</p>
	<p>
		If you will be using an editing context, you will need to use a data source.
	</p>
	<pre>
    EODataSource dataSource = new MyDataSource();
    displayGroup.setDataSource( dataSource );
    displayGroup.fetch();
</pre>
	<!--End Section h4-->
	<h4><a name="Qualifying Displayed Objects">Qualifying Displayed Objects</a></h4>
	<p>
		The displayed objects are a subset of the list of objects that the display group manages. By default all objects
		are displayed.
	</p>
	<p>
		You can change this behavior by specifying a qualifier for the display group. This is an instance of <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOQualifier.html">EOQualifier</a> and it
		will have evaluateWithObject called for every object in the display group. Only those objects for which the
		return value is true will be in the displayed objects list. Call updateDisplayedObjects() on the display group
		to apply the qualifier.
	</p>
	<p>
		You would typically use this feature when you want to preload a large number of data objects into the display
		group so that the user can quickly and repeatedly apply different filters to sift through the data.
	</p>
	<pre>
    // show only Powers in San Antonio

    Map matchValues = new HashMap();
    matchValues.put( &quot;lastName&quot;, &quot;Powers&quot; );
    matchValues.put( &quot;city&quot;, &quot;San Antonio&quot; );

    EOQualifier qualifier = 
	EOQualifier.qualifierToMatchAllValues( matchValues );
    displayGroup.setQualifier( qualifier );
    displayGroup.updateDisplayedObjects();
</pre>
	<!--End Section h4-->
	<h4><a name="Handling Selection">Handling Selection</a></h4>
	<p>
		Display groups also track which of the displayed objects are selected. By default no objects are selected, but
		you can change the selection programmatically. Certain associations allow the user to change the selection as
		well.
	</p>
	<p>
		If you do not provide the user with an association that can change the selection, you should make sure to set
		the selection to some object.
	</p>
	<pre>
    // select all objects
    displayGroup.setSelectedObjects( 
	displayGroup.displayedObjects() );

    // select the third object
    List selectionList = new LinkedList();
    selectionList.add( new Integer( 2 ) );
    displayGroup.setSelectedIndexes( selectionList );

    // select the next object
    displayGroup.selectNext();

    // clear the selection
    displayGroup.clearSelection();
</pre>
	<!--End Section h4-->
	<h4><a name="Handling Insertions and Deletions">Handling Insertions and Deletions</a></h4>
	<p>
		You can programmatically insert or delete objects from a display group, although only if they are displayed. Any
		associations that display all of the displayed objects (like TableColumns) will be updated automatically.
	</p>
	<p>
		Deleted objects that were selected are removed from the selection. Inserted objects are not selected, so you
		will need to select them manually if desired. Default values for inserted objects can be specified with
		setInsertedObjectDefaultValues().
	</p>
	<p>
		If a data source is used, the data source will be informed of the insertion or deletion, which will notify the
		editing context if it has one, which would update the persistent store on commit.
	</p>
	<p>
		Also, if a data source is used, the display group can be asked to simply create an object to be inserted into
		the group, which will call createObject() on the data source.
	</p>
	<pre>
    // insert an object
    displayGroup.insertObjectAtIndex( new TestObject(), 0 );

    // delete that object
    displayGroup.deleteObjectAtIndex();

    // select the next object
    displayGroup.selectNext();

    // delete that object
    displayGroup.deleteSelection();

    // insert a new object
    displayGroup.insertNewObjectAtIndex( 0 );
</pre>
	<!--End Section h4-->
	<h4><a name="Delegate">Delegate</a></h4>
	<p>
		Display groups check with their delegate before performing almost any operation, you can easily customize the
		behavior of a display group by providing a class that implements the <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.Delegate.html">DisplayGroup.Delegate</a>
		interface.
	</p>
	<p>
		Display groups ask their delegate for permission to fetch, insert, delete, edit, create, and change selection,
		and then notify their delegate after each of these operations has taken place. Wotonomy provides a
		DelegateAdapter class that you can easily subclass to implement the required interface.
	</p>
	<!--End Section h4-->
	<!--End Section h3-->
	<h3><a name="Associations">Associations</a></h3>
	<p>
		<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EOAssociation.html">Associations</a> are the
		bridge between the controller and the view. An association has exactly one &quot;controlled object&quot;, which
		is usually a user interface component. They also have one or sometimes more &quot;aspects&quot;, each of which
		has a name, like ValueAspect or EnabledAspect.
		You bind an aspect of an association with a display group and/or a key. Then you establish the connection
		between the association and the controlled object and you're done and you can forget about it. The association
		will keep the user interface object synchronized with the objects in the display group.
	</p>
	<h4><a name="Creating Associations">Creating Associations</a></h4>
	<p>
		You create an association by calling the constructor of the subclass of EOAssociation that is appropriate for
		the controlled object. Most associations are applicable to many kinds of objects, so the constructor is expected
		to take an Object. (This means that if you specify the wrong kind of object for the association, you won't hear
		about it until runtime.)
	</p>
	<pre>
    EOAssociation association = new TextAssociation( textField );
</pre>
	<!--End Section h4-->
	<h4><a name="Kinds of Associations">Kinds of Associations</a></h4>
	<p>
		Associations fall into one of two categories: overview associations and detail associations. Almost all
		associations are used to control some kind of user interface component.
	</p>
	<p>
		Overview associations show some property of all the items in the display group. Overview associations usually
		allow the user to select and deselect objects in the display group.
	</p>
	<p>
		For example, a JList might be used with a <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/ListAssociation.html">ListAssociation</a>
		to show the &quot;name&quot; property of all of the displayed objects in the display group, in the same order.
		Clicking the fourth name in the list would cause the fourth object in the display group to be selected, and -
		depending on the JList's selection model - cause whatever was previously selected to become unselected.
	</p>
	<p>
		Detail associations show some property of only the first selected object in the display group. If there is no
		selection, the detail association causes the controlled component to be blank or otherwise empty. If multiple
		objects are selected, the detail association shows the property of only the first object in the selected objects
		list.
	</p>
	<p>
		In our example, a JTextField might be used with a <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html">TextAssociation</a>
		to display the &quot;email&quot; property of the selected item in the display group. Clicking the fourth name in
		the list causes the fourth item in the display group to be selected, which populates the text field with the
		value of the email property for that object. Changing the value in the text field changes the value of that
		object's email property automatically.
	</p>
	<!--End Section h4-->
	<h4><a name="Master-Detail Associations">Master-Detail Associations</a></h4>
	<p>
		While nearly all associations control user interface components, the <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/MasterDetailAssociation.html">MasterDetailAssociation</a>
		is worthy of note because it does not.
	</p>
	<p>
		A MasterDetailAssociation controls a display group and binds to an indexed property of the objects in another
		display group. It is a detail association, with the bound display group as the &quot;master&quot; and the
		controlled display group as the &quot;detail&quot; component.
	</p>
	<p>
		Again using our example, another JList might be used with a ListAssociation to show all the dependents of the
		person selected in the first JList.
	</p>
	<p>
		First we would create a new display group and then create a MasterDetailAssociation with our new display group
		as the parameter to the constructor. Then we would bind that association to our original master display group
		with the &quot;dependents&quot; property (assuming there is a method on our data object called getDependents()
		that returns an array or a collection of objects). Then we would create our new ListAssociation controlling our
		new JList, and bind that to our new display group with the &quot;name&quot; property. Seeing the source might
		make this clearer - that's coming in the next section.
	</p>
	<p>
		Clicking on a name in the name list would then display the email address in the text field and a list of names
		of all the dependents.
	</p>
	<!--End Section h4-->
	<h4><a name="Binding Aspects and Establishing Connections">Binding Aspects and Establishing Connections</a></h4>
	<p>
		An association has one or more aspects. Most of the time, you'll just need one aspect, sometimes called the
		&quot;primary aspect&quot;. Aspects are referred to by name, like ValueAspect, and the names of an association's
		aspects are static members of that association's class.
	</p>
	<p>
		The primary aspect is usually responsible for populating the controlled object with data from the display group.
		The other aspects are useful, but they'll do different things depending on the nature of the association, so you
		should consult the documentation for the association you will be using.
	</p>
	<p>
		To bind an aspect, you call bindAspect() with the name of the aspect, a display group and a string
		&quot;key&quot;.
	</p>
	<p>
		Usually, all three are specified, and the key is a property name. The association will display or edit the value
		of this property for the objects in the display group.
	</p>
	<p>
		The key may be an empty string, and this is considered the &quot;identity property&quot;, and the value of the
		actual object in the display group will be used instead of a property on that object. This is sometimes useful
		for view components like JTrees for which you want to write custom renderers: with the identity property, the
		renderer receives the value of the actual object.
	</p>
	<p>
		The display group may be left null, in which case the key is treated as a value, acting as if all objects in the
		display group for the given property returned that value. This is useful for certain aspects of certain
		associations, like the EnabledAspect of <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html">TextAssociation</a>,
		or the EditableAspect of <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TableColumnAssociation.html">TableColumnAssociation</a>.
	</p>
	<p>
		After all the aspects have been bound, you need to call establishConnection() to put the association to work.
		Importantly, you do not need to retain a reference to the associations you create - they will exist as long as
		their controlled components exist, and when the controlled component is garbage collected, the association will
		be garbage collected.
	</p>
	<pre>
    // set up the master display group
    EODisplayGroup masterGroup = new EODisplayGroup();
    masterGroup.setObjectArray( getMyUsers() );
    
    EOAssociation association;

    // set up names list
    association = new ListAssociation( usersList );
    association.bindAspect( 
	EOAssociation.TitlesAspect, masterGroup, &quot;name&quot; );
    association.establishConnection();

    // set up email field and for fun make it non-editable
    association = new TextAssociation( emailField );
    association.bindAspect( 
	EOAssociation.ValueAspect, masterGroup, &quot;email&quot; );
    association.bindAspect( 
	EOAssociation.EditableAspect, null, &quot;false&quot; );
    association.establishConnection();

    // set up detail display group
    EODisplayGroup detailGroup = new EODisplayGroup();
    association = new MasterDetailAssociation( detailGroup );
    association.bindAspect( 
	EOAssociation.ParentAspect, masterGroup, &quot;dependents&quot; );
    association.establishConnection();

    // set up dependents' names list
    association = new ListAssociation( dependentsList );
    association.bindAspect( 
	EOAssociation.TitlesAspect, detailGroup, &quot;name&quot; );
    association.establishConnection();

    // we're done!
</pre>
	<!--End Section h4-->
	<!--End Section h3-->
	<h3><a name="Editing Contexts">Editing Contexts</a></h3>
	<p>
		<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOEditingContext.html">Editing contexts</a>
		allow multiple display groups to manipulate the same set of objects, such that objects edited in one display
		group are updated in the associations of all other display groups that contain that object.
	</p>
	<p>
		Editing contexts monitor all inserts, edits, and deletes in the display groups that use them, allowing these
		sets of changes to be committed or rolled-back as a single transaction.
	</p>
	<p>
		Furthermore, editing contexts can be nested, so that a new editing context will reflect the existing state of
		another editing context, but all changes made to the new context are not applied to the parent context until
		they have been committed in the child context.
	</p>
	<h4><a name="Object Stores">Object Stores</a></h4>
	<p>
		Two concepts are critical to an understanding of editing contexts: (1) An editing context must have an object
		store, and (2) an editing context is an object store.
	</p>
	<p>
		Because you need an object store to instantiate an editing context, there must be some implementation of <a
			href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObjectStore.html">EOObjectStore</a> that
		is not an editing context. That object store will be responsible for directly reading and writing to the
		persistent storage.
	</p>
	<p>
		Because editing contexts do implement object stores, you can then create other editing contexts that use the
		first editing context, which uses the first object store. This is what allows editing contexts to be nest.
	</p>
	<!--End Section h4-->
	<h4><a name="Creating an Editing Context">Creating an Editing Context</a></h4>
	<p>
		To use an editing context in your application, you must create an object store. Your implementation of
		EOObjectStore will act as the glue between wotonomy and whatever persistent storage mechanism your application
		uses.
	</p>
	<p>
		You will then create your primary editing context, specifying your object store as the parameter to the
		constructor. You will probably have only one object store per application, and one primary editing context that
		uses it. Any other editing contexts you create will use your primary context as their object store.
	</p>
	<pre>
    // initial application setup
    EOObjectStore objectStore = new MyObjectStore();
    EOEditingContext mainContext = new EOEditingContext( objectStore );

    // set up a child display group
    EOEditingContext childContext = new EOEditingContext( mainContext );
    EODataSource dataSource = new MyDataSource( childContext );
    EODisplayGroup displayGroup = new EODisplayGroup();
    displayGroup.setDataSource( dataSource );
    displayGroup.fetch();
</pre>
	<!--End Section h4-->
	<!--End Section h3-->
	<!--End Section h2-->
	<h2><a name="What's next?">What's next?</a></h2>
	<p>
		This document gives you a very basic overview and brief introduction to the major players in the wotonomy user
		interface framework. You'll probably want to check out the <a href="http://wotonomy.sourceforge.net/docs">API
			Reference</a>
		next
	</p>
	<!--End Section h2-->
	<br>
	<hr>
	<center><small><em>
				This document was generated using <a href="http://www.maplefish.com/todd/aft.html">AFT v5.06</a>
			</em></small></center>
</body>

</html>