View Javadoc

1   /*
2   
3       dsh-venn  Lightweight components for venn diagrams.
4       Copyright (c) 2009-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.venn.swing;
25  
26  import java.awt.GridLayout;
27  
28  import java.beans.PropertyChangeEvent;
29  import java.beans.PropertyChangeListener;
30  
31  import java.util.List;
32  import java.util.Set;
33  
34  import javax.swing.Box;
35  import javax.swing.JList;
36  import javax.swing.JPanel;
37  import javax.swing.JScrollPane;
38  import javax.swing.ListSelectionModel;
39  
40  import javax.swing.event.ListSelectionEvent;
41  import javax.swing.event.ListSelectionListener;
42  
43  import ca.odell.glazedlists.swing.EventListModel;
44  
45  import org.dishevelled.layout.LabelFieldPanel;
46  
47  import org.dishevelled.observable.event.SetChangeEvent;
48  import org.dishevelled.observable.event.SetChangeListener;
49  
50  import org.dishevelled.venn.QuaternaryVennModel;
51  
52  /**
53   * Quaternary venn diagram list.
54   *
55   * @param <E> value type
56   * @author  Michael Heuer
57   * @version $Revision$ $Date$
58   */
59  public final class QuaternaryVennList<E>
60      extends AbstractQuaternaryVennDiagram<E>
61  {
62      /** Contents of the first set. */
63      private final JList first = new JList();
64  
65      /** Contents of the second set. */
66      private final JList second = new JList();
67  
68      /** Contents of the third set. */
69      private final JList third = new JList();
70  
71      /** Contents of the fourth set. */
72      private final JList fourth = new JList();
73  
74      /** Contents of the first only view. */
75      private final JList firstOnly = new JList();
76  
77      /** Contents for the second only view. */
78      private final JList secondOnly = new JList();
79  
80      /** Contents for the third only view. */
81      private final JList thirdOnly = new JList();
82  
83      /** Contents for the fourth only view. */
84      private final JList fourthOnly = new JList();
85  
86      /** Contents for the first second view. */
87      private final JList firstSecond = new JList();
88  
89      /** Contents for the first third view. */
90      private final JList firstThird = new JList();
91  
92      /** Contents for the second third view. */
93      private final JList secondThird = new JList();
94  
95      /** Contents for the first fourth view. */
96      private final JList firstFourth = new JList();
97  
98      /** Contents for the second fourth view. */
99      private final JList secondFourth = new JList();
100 
101     /** Contents for the third fourth view. */
102     private final JList thirdFourth = new JList();
103 
104     /** Contents for the first second third view. */
105     private final JList firstSecondThird = new JList();
106 
107     /** Contents for the first second fourth view. */
108     private final JList firstSecondFourth = new JList();
109 
110     /** Contents for the first third fourth view. */
111     private final JList firstThirdFourth = new JList();
112 
113     /** Contents for the second third fourth view. */
114     private final JList secondThirdFourth = new JList();
115 
116     /** Contents of the intersection view. */
117     private final JList intersection = new JList();
118 
119     /** Contents of the union view. */
120     private final JList union = new JList();
121 
122     /** Adapter for the first list model. */
123     private ObservableSetEventListAdapter<E> firstAdapter;
124 
125     /** Adapter for the second list model. */
126     private ObservableSetEventListAdapter<E> secondAdapter;
127 
128     /** Adapter for the third list model. */
129     private ObservableSetEventListAdapter<E> thirdAdapter;
130 
131     /** Adapter for the fourth list model. */
132     private ObservableSetEventListAdapter<E> fourthAdapter;
133 
134     /** Adapter for the first only list model. */
135     private SetEventListAdapter<E> firstOnlyAdapter;
136 
137     /** Adapter for the second only list model. */
138     private SetEventListAdapter<E> secondOnlyAdapter;
139 
140     /** Adapter for the third only list model. */
141     private SetEventListAdapter<E> thirdOnlyAdapter;
142 
143     /** Adapter for the fourth only list model. */
144     private SetEventListAdapter<E> fourthOnlyAdapter;
145 
146     /** Adapter for the first second list model. */
147     private SetEventListAdapter<E> firstSecondAdapter;
148 
149     /** Adapter for the first third list model. */
150     private SetEventListAdapter<E> firstThirdAdapter;
151 
152     /** Adapter for the second third list model. */
153     private SetEventListAdapter<E> secondThirdAdapter;
154 
155     /** Adapter for the first fourth list model. */
156     private SetEventListAdapter<E> firstFourthAdapter;
157 
158     /** Adapter for the second fourth list model. */
159     private SetEventListAdapter<E> secondFourthAdapter;
160 
161     /** Adapter for the third fourth list model. */
162     private SetEventListAdapter<E> thirdFourthAdapter;
163 
164     /** Adapter for the first second third list model. */
165     private SetEventListAdapter<E> firstSecondThirdAdapter;
166 
167     /** Adapter for the first second fourth list model. */
168     private SetEventListAdapter<E> firstSecondFourthAdapter;
169 
170     /** Adapter for the first third fourth list model. */
171     private SetEventListAdapter<E> firstThirdFourthAdapter;
172 
173     /** Adapter for the second third fourth list model. */
174     private SetEventListAdapter<E> secondThirdFourthAdapter;
175 
176     /** Adapter for the intersection list model. */
177     private SetEventListAdapter<E> intersectionAdapter;
178 
179     /** Adapter for the union list model. */
180     private SetEventListAdapter<E> unionAdapter;
181 
182     /** Model change listener. */
183     private final PropertyChangeListener modelChange = new PropertyChangeListener()
184     {
185         /** {@inheritDoc} */
186         public void propertyChange(final PropertyChangeEvent event)
187         {
188             uninstallListModels((QuaternaryVennModel<E>) event.getOldValue());
189             installListModels();
190         }
191     };
192 
193     /** Update list models from model. */
194     private final SetChangeListener<E> updateListModels = new SetChangeListener<E>()
195     {
196         /** {@inheritDoc} */
197         public void setChanged(final SetChangeEvent<E> event)
198         {
199             updateListModels();
200         }
201     };
202 
203     /** Update list selection from model. */
204     private final SetChangeListener<E> updateSelection = new SetChangeListener<E>()
205     {
206         /** {@inheritDoc} */
207         public void setChanged(final SetChangeEvent<E> event)
208         {
209             updateSelection();
210         }
211     };
212 
213 
214     /**
215      * Create a new empty quaternary venn list.
216      */
217     public QuaternaryVennList()
218     {
219         super();
220         installListModels();
221         installSelectionListeners();
222         layoutComponents();
223         addPropertyChangeListener("model", modelChange);
224     }
225 
226     /**
227      * Create a new quaternary venn list with the specified sets.
228      *
229      * @param firstLabelText label text for the first set
230      * @param first first set, must not be null
231      * @param secondLabelText label text for the second set
232      * @param second second set, must not be null
233      * @param thirdLabelText label text for the third set
234      * @param third third set, must not be null
235      * @param fourthLabelText label text for the fourth set
236      * @param fourth fourth set, must not be null
237      */
238     public QuaternaryVennList(final String firstLabelText, final Set<? extends E> first,
239                                final String secondLabelText, final Set<? extends E> second,
240                                final String thirdLabelText, final Set<? extends E> third,
241                                final String fourthLabelText, final Set<? extends E> fourth)
242     {
243         super(firstLabelText, first, secondLabelText, second, thirdLabelText, third, fourthLabelText, fourth);
244         installListModels();
245         installSelectionListeners();
246         layoutComponents();
247         addPropertyChangeListener("model", modelChange);
248     }
249 
250     /**
251      * Create a new quaternary venn list with the specified model.
252      *
253      * @param model model for this quaternary venn list, must not be null
254      */
255     public QuaternaryVennList(final QuaternaryVennModel<E> model)
256     {
257         super(model);
258         installListModels();
259         installSelectionListeners();
260         layoutComponents();
261         addPropertyChangeListener("model", modelChange);
262     }
263 
264     /**
265      * Create a new quaternary venn list with the specified model.
266      *
267      * @param firstLabelText label text for the first set
268      * @param secondLabelText label text for the second set
269      * @param thirdLabelText label text for the third set
270      * @param fourthLabelText label text for the fourth set
271      * @param model model for this abstract quaternary venn diagram, must not be null
272      */
273     public QuaternaryVennList(final String firstLabelText,
274                                final String secondLabelText,
275                                final String thirdLabelText,
276                                final String fourthLabelText,
277                                final QuaternaryVennModel<E> model)
278     {
279         super(firstLabelText,
280               secondLabelText,
281               thirdLabelText,
282               fourthLabelText,
283               model);
284 
285         installListModels();
286         installSelectionListeners();
287         layoutComponents();
288         addPropertyChangeListener("model", modelChange);
289     }
290 
291 
292     /**
293      * Clear selection.
294      */
295     public void clearSelection()
296     {
297         union.requestFocusInWindow();
298         getModel().selection().clear();
299     }
300 
301     /**
302      * Select all.
303      */
304     public void selectAll()
305     {
306         union.requestFocusInWindow();
307         // todo:  dreadfully inefficient
308         getModel().selection().addAll(getModel().union());
309     }
310 
311     /**
312      * Install list models.
313      */
314     private void installListModels()
315     {
316         firstAdapter = new ObservableSetEventListAdapter<E>(getModel().first());
317         first.setModel(new EventListModel<E>(firstAdapter));
318         secondAdapter = new ObservableSetEventListAdapter<E>(getModel().second());
319         second.setModel(new EventListModel<E>(secondAdapter));
320         thirdAdapter = new ObservableSetEventListAdapter<E>(getModel().third());
321         third.setModel(new EventListModel<E>(thirdAdapter));
322         fourthAdapter = new ObservableSetEventListAdapter<E>(getModel().fourth());
323         fourth.setModel(new EventListModel<E>(fourthAdapter));
324 
325         firstOnlyAdapter = new SetEventListAdapter<E>(getModel().firstOnly());
326         firstOnly.setModel(new EventListModel<E>(firstOnlyAdapter));
327         secondOnlyAdapter = new SetEventListAdapter<E>(getModel().secondOnly());
328         secondOnly.setModel(new EventListModel<E>(secondOnlyAdapter));
329         thirdOnlyAdapter = new SetEventListAdapter<E>(getModel().thirdOnly());
330         thirdOnly.setModel(new EventListModel<E>(thirdOnlyAdapter));
331         fourthOnlyAdapter = new SetEventListAdapter<E>(getModel().fourthOnly());
332         fourthOnly.setModel(new EventListModel<E>(fourthOnlyAdapter));
333         firstSecondAdapter = new SetEventListAdapter<E>(getModel().firstSecond());
334         firstSecond.setModel(new EventListModel<E>(firstSecondAdapter));
335         firstThirdAdapter = new SetEventListAdapter<E>(getModel().firstThird());
336         firstThird.setModel(new EventListModel<E>(firstThirdAdapter));
337         secondThirdAdapter = new SetEventListAdapter<E>(getModel().secondThird());
338         secondThird.setModel(new EventListModel<E>(secondThirdAdapter));
339         firstFourthAdapter = new SetEventListAdapter<E>(getModel().firstFourth());
340         firstFourth.setModel(new EventListModel<E>(firstFourthAdapter));
341         secondFourthAdapter = new SetEventListAdapter<E>(getModel().secondFourth());
342         secondFourth.setModel(new EventListModel<E>(secondFourthAdapter));
343         thirdFourthAdapter = new SetEventListAdapter<E>(getModel().thirdFourth());
344         thirdFourth.setModel(new EventListModel<E>(thirdFourthAdapter));
345         firstSecondThirdAdapter = new SetEventListAdapter<E>(getModel().firstSecondThird());
346         firstSecondThird.setModel(new EventListModel<E>(firstSecondThirdAdapter));
347         firstSecondFourthAdapter = new SetEventListAdapter<E>(getModel().firstSecondFourth());
348         firstSecondFourth.setModel(new EventListModel<E>(firstSecondFourthAdapter));
349         firstThirdFourthAdapter = new SetEventListAdapter<E>(getModel().firstThirdFourth());
350         firstThirdFourth.setModel(new EventListModel<E>(firstThirdFourthAdapter));
351         secondThirdFourthAdapter = new SetEventListAdapter<E>(getModel().secondThirdFourth());
352         secondThirdFourth.setModel(new EventListModel<E>(secondThirdFourthAdapter));
353         intersectionAdapter = new SetEventListAdapter<E>(getModel().intersection());
354         intersection.setModel(new EventListModel<E>(intersectionAdapter));
355         unionAdapter = new SetEventListAdapter<E>(getModel().union());
356         union.setModel(new EventListModel<E>(unionAdapter));
357 
358         getModel().first().addSetChangeListener(updateListModels);
359         getModel().second().addSetChangeListener(updateListModels);
360         getModel().third().addSetChangeListener(updateListModels);
361         getModel().fourth().addSetChangeListener(updateListModels);
362         getModel().first().addSetChangeListener(updateSelection);
363         getModel().second().addSetChangeListener(updateSelection);
364         getModel().third().addSetChangeListener(updateSelection);
365         getModel().fourth().addSetChangeListener(updateSelection);
366         getModel().selection().addSetChangeListener(updateSelection);
367     }
368 
369     /**
370      * Update list models.
371      */
372     private void updateListModels()
373     {
374         firstOnlyAdapter.updateEventList();
375         secondOnlyAdapter.updateEventList();
376         thirdOnlyAdapter.updateEventList();
377         fourthOnlyAdapter.updateEventList();
378         firstSecondAdapter.updateEventList();
379         firstThirdAdapter.updateEventList();
380         secondThirdAdapter.updateEventList();
381         firstFourthAdapter.updateEventList();
382         secondFourthAdapter.updateEventList();
383         thirdFourthAdapter.updateEventList();
384         firstSecondThirdAdapter.updateEventList();
385         firstSecondFourthAdapter.updateEventList();
386         firstThirdFourthAdapter.updateEventList();
387         secondThirdFourthAdapter.updateEventList();
388         intersectionAdapter.updateEventList();
389         unionAdapter.updateEventList();
390     }
391 
392     /**
393      * Uninstall list models.
394      *
395      * @param oldModel old model
396      */
397     private void uninstallListModels(final QuaternaryVennModel<E> oldModel)
398     {
399         firstAdapter.dispose();
400         secondAdapter.dispose();
401         thirdAdapter.dispose();
402         fourthAdapter.dispose();
403         ((EventListModel<E>) first.getModel()).dispose();
404         ((EventListModel<E>) second.getModel()).dispose();
405         ((EventListModel<E>) third.getModel()).dispose();
406         ((EventListModel<E>) fourth.getModel()).dispose();
407         ((EventListModel<E>) firstOnly.getModel()).dispose();
408         ((EventListModel<E>) secondOnly.getModel()).dispose();
409         ((EventListModel<E>) thirdOnly.getModel()).dispose();
410         ((EventListModel<E>) fourthOnly.getModel()).dispose();
411         ((EventListModel<E>) firstSecond.getModel()).dispose();
412         ((EventListModel<E>) firstThird.getModel()).dispose();
413         ((EventListModel<E>) secondThird.getModel()).dispose();
414         ((EventListModel<E>) firstFourth.getModel()).dispose();
415         ((EventListModel<E>) secondFourth.getModel()).dispose();
416         ((EventListModel<E>) thirdFourth.getModel()).dispose();
417         ((EventListModel<E>) firstSecondThird.getModel()).dispose();
418         ((EventListModel<E>) firstSecondFourth.getModel()).dispose();
419         ((EventListModel<E>) firstThirdFourth.getModel()).dispose();
420         ((EventListModel<E>) secondThirdFourth.getModel()).dispose();
421         ((EventListModel<E>) intersection.getModel()).dispose();
422         ((EventListModel<E>) union.getModel()).dispose();
423         oldModel.first().removeSetChangeListener(updateListModels);
424         oldModel.second().removeSetChangeListener(updateListModels);
425         oldModel.third().removeSetChangeListener(updateListModels);
426         oldModel.fourth().removeSetChangeListener(updateListModels);
427         oldModel.first().removeSetChangeListener(updateSelection);
428         oldModel.second().removeSetChangeListener(updateSelection);
429         oldModel.third().removeSetChangeListener(updateSelection);
430         oldModel.selection().removeSetChangeListener(updateSelection);
431     }
432 
433      /**
434      * Install selection listeners.
435      */
436     private void installSelectionListeners()
437     {
438         first.addListSelectionListener(new UpdateSelectionView());
439         second.addListSelectionListener(new UpdateSelectionView());
440         third.addListSelectionListener(new UpdateSelectionView());
441         fourth.addListSelectionListener(new UpdateSelectionView());
442         firstOnly.addListSelectionListener(new UpdateSelectionView());
443         secondOnly.addListSelectionListener(new UpdateSelectionView());
444         thirdOnly.addListSelectionListener(new UpdateSelectionView());
445         fourthOnly.addListSelectionListener(new UpdateSelectionView());
446         firstSecond.addListSelectionListener(new UpdateSelectionView());
447         firstThird.addListSelectionListener(new UpdateSelectionView());
448         secondThird.addListSelectionListener(new UpdateSelectionView());
449         firstFourth.addListSelectionListener(new UpdateSelectionView());
450         secondFourth.addListSelectionListener(new UpdateSelectionView());
451         thirdFourth.addListSelectionListener(new UpdateSelectionView());
452         firstSecondThird.addListSelectionListener(new UpdateSelectionView());
453         firstSecondFourth.addListSelectionListener(new UpdateSelectionView());
454         firstThirdFourth.addListSelectionListener(new UpdateSelectionView());
455         secondThirdFourth.addListSelectionListener(new UpdateSelectionView());
456         intersection.addListSelectionListener(new UpdateSelectionView());
457         union.addListSelectionListener(new UpdateSelectionView());
458     }
459 
460    /** {@inheritDoc} */
461     protected void updateContents()
462     {
463         // empty
464     }
465 
466     /**
467      * Layout components.
468      */
469     private void layoutComponents()
470     {
471         addFinalField(createMainPanel());
472     }
473 
474     /**
475      * Create and return the main panel.
476      *
477      * @return the main panel
478      */
479     private JPanel createMainPanel()
480     {
481         JPanel panel = new JPanel();
482         panel.setLayout(new GridLayout(4, 6, 12, 12));
483 
484         LabelFieldPanel f = new LabelFieldPanel();
485         f.addLabel(getFirstLabel());
486         f.addFinalField(new JScrollPane(first));
487         panel.add(f);
488 
489         LabelFieldPanel s = new LabelFieldPanel();
490         s.addLabel(getSecondLabel());
491         s.addFinalField(new JScrollPane(second));
492         panel.add(s);
493 
494         LabelFieldPanel t = new LabelFieldPanel();
495         t.addLabel(getThirdLabel());
496         t.addFinalField(new JScrollPane(third));
497         panel.add(t);
498 
499         LabelFieldPanel r = new LabelFieldPanel();
500         r.addLabel(getFourthLabel());
501         r.addFinalField(new JScrollPane(fourth));
502         panel.add(r);
503 
504         panel.add(Box.createGlue());
505         panel.add(Box.createGlue());
506 
507         LabelFieldPanel fo = new LabelFieldPanel();
508         fo.addLabel(getFirstOnlyLabel());
509         fo.addFinalField(new JScrollPane(firstOnly));
510         panel.add(fo);
511 
512         LabelFieldPanel so = new LabelFieldPanel();
513         so.addLabel(getSecondOnlyLabel());
514         so.addFinalField(new JScrollPane(secondOnly));
515         panel.add(so);
516 
517         LabelFieldPanel to = new LabelFieldPanel();
518         to.addLabel(getThirdOnlyLabel());
519         to.addFinalField(new JScrollPane(thirdOnly));
520         panel.add(to);
521 
522         LabelFieldPanel ro = new LabelFieldPanel();
523         ro.addLabel(getFourthOnlyLabel());
524         ro.addFinalField(new JScrollPane(fourthOnly));
525         panel.add(ro);
526 
527         panel.add(Box.createGlue());
528         panel.add(Box.createGlue());
529 
530         LabelFieldPanel fs = new LabelFieldPanel();
531         fs.addLabel(getFirstSecondLabel());
532         fs.addFinalField(new JScrollPane(firstSecond));
533         panel.add(fs);
534 
535         LabelFieldPanel ft = new LabelFieldPanel();
536         ft.addLabel(getFirstThirdLabel());
537         ft.addFinalField(new JScrollPane(firstThird));
538         panel.add(ft);
539 
540         LabelFieldPanel st = new LabelFieldPanel();
541         st.addLabel(getSecondThirdLabel());
542         st.addFinalField(new JScrollPane(secondThird));
543         panel.add(st);
544 
545         LabelFieldPanel fr = new LabelFieldPanel();
546         fr.addLabel(getFirstFourthLabel());
547         fr.addFinalField(new JScrollPane(firstFourth));
548         panel.add(fr);
549 
550         LabelFieldPanel sr = new LabelFieldPanel();
551         sr.addLabel(getSecondFourthLabel());
552         sr.addFinalField(new JScrollPane(secondFourth));
553         panel.add(sr);
554 
555         LabelFieldPanel tr = new LabelFieldPanel();
556         tr.addLabel(getThirdFourthLabel());
557         tr.addFinalField(new JScrollPane(thirdFourth));
558         panel.add(tr);
559 
560         LabelFieldPanel fst = new LabelFieldPanel();
561         fst.addLabel(getFirstSecondThirdLabel());
562         fst.addFinalField(new JScrollPane(firstSecondThird));
563         panel.add(fst);
564 
565         LabelFieldPanel fsr = new LabelFieldPanel();
566         fsr.addLabel(getFirstSecondFourthLabel());
567         fsr.addFinalField(new JScrollPane(firstSecondFourth));
568         panel.add(fsr);
569 
570         LabelFieldPanel ftr = new LabelFieldPanel();
571         ftr.addLabel(getFirstThirdFourthLabel());
572         ftr.addFinalField(new JScrollPane(firstThirdFourth));
573         panel.add(ftr);
574 
575         LabelFieldPanel str = new LabelFieldPanel();
576         str.addLabel(getSecondThirdFourthLabel());
577         str.addFinalField(new JScrollPane(secondThirdFourth));
578         panel.add(str);
579 
580         LabelFieldPanel n = new LabelFieldPanel();
581         n.addLabel(getIntersectionLabel());
582         n.addFinalField(new JScrollPane(intersection));
583         panel.add(n);
584 
585         LabelFieldPanel u = new LabelFieldPanel();
586         u.addLabel(getUnionLabel());
587         u.addFinalField(new JScrollPane(union));
588         panel.add(u);
589         return panel;
590     }
591 
592     /**
593      * Update list selection from the selection view in the model.
594      */
595     private void updateSelection()
596     {
597         if (getModel().selection().isEmpty())
598         {
599             clearSelection(first);
600             clearSelection(second);
601             clearSelection(third);
602             clearSelection(fourth);
603             clearSelection(firstOnly);
604             clearSelection(secondOnly);
605             clearSelection(thirdOnly);
606             clearSelection(fourthOnly);
607             clearSelection(firstSecond);
608             clearSelection(firstThird);
609             clearSelection(secondThird);
610             clearSelection(firstFourth);
611             clearSelection(secondFourth);
612             clearSelection(thirdFourth);
613             clearSelection(firstSecondThird);
614             clearSelection(firstSecondFourth);
615             clearSelection(firstThirdFourth);
616             clearSelection(secondThirdFourth);
617             clearSelection(intersection);
618             clearSelection(union);
619         }
620         else
621         {
622             // todo:  need element(s) that were added from set change event
623             for (E e : getModel().selection())
624             {
625                 addToSelection(getModel().first(), first, firstAdapter, e);
626                 addToSelection(getModel().second(), second, secondAdapter, e);
627                 addToSelection(getModel().third(), third, thirdAdapter, e);
628                 addToSelection(getModel().fourth(), fourth, fourthAdapter, e);
629                 addToSelection(getModel().firstOnly(), firstOnly, firstOnlyAdapter, e);
630                 addToSelection(getModel().secondOnly(), secondOnly, secondOnlyAdapter, e);
631                 addToSelection(getModel().thirdOnly(), thirdOnly, thirdOnlyAdapter, e);
632                 addToSelection(getModel().fourthOnly(), fourthOnly, fourthOnlyAdapter, e);
633                 addToSelection(getModel().firstSecond(), firstSecond, firstSecondAdapter, e);
634                 addToSelection(getModel().firstThird(), firstThird, firstThirdAdapter, e);
635                 addToSelection(getModel().secondThird(), secondThird, secondThirdAdapter, e);
636                 addToSelection(getModel().firstFourth(), firstFourth, firstFourthAdapter, e);
637                 addToSelection(getModel().secondFourth(), secondFourth, secondFourthAdapter, e);
638                 addToSelection(getModel().thirdFourth(), thirdFourth, thirdFourthAdapter, e);
639                 addToSelection(getModel().firstSecondThird(), firstSecondThird, firstSecondThirdAdapter, e);
640                 addToSelection(getModel().firstSecondFourth(), firstSecondFourth, firstSecondFourthAdapter, e);
641                 addToSelection(getModel().firstThirdFourth(), firstThirdFourth, firstThirdFourthAdapter, e);
642                 addToSelection(getModel().secondThirdFourth(), secondThirdFourth, secondThirdFourthAdapter, e);
643                 addToSelection(getModel().intersection(), intersection, intersectionAdapter, e);
644                 addToSelection(getModel().union(), union, unionAdapter, e);
645             }
646 
647             removeFromSelection(getModel().first(), first, firstAdapter);
648             removeFromSelection(getModel().second(), second, secondAdapter);
649             removeFromSelection(getModel().third(), third, thirdAdapter);
650             removeFromSelection(getModel().fourth(), fourth, fourthAdapter);
651             removeFromSelection(getModel().firstOnly(), firstOnly, firstOnlyAdapter);
652             removeFromSelection(getModel().secondOnly(), secondOnly, secondOnlyAdapter);
653             removeFromSelection(getModel().thirdOnly(), thirdOnly, thirdOnlyAdapter);
654             removeFromSelection(getModel().fourthOnly(), fourthOnly, fourthOnlyAdapter);
655             removeFromSelection(getModel().firstSecond(), firstSecond, firstSecondAdapter);
656             removeFromSelection(getModel().firstThird(), firstThird, firstThirdAdapter);
657             removeFromSelection(getModel().secondThird(), secondThird, secondThirdAdapter);
658             removeFromSelection(getModel().firstFourth(), firstFourth, firstFourthAdapter);
659             removeFromSelection(getModel().secondFourth(), secondFourth, secondFourthAdapter);
660             removeFromSelection(getModel().thirdFourth(), thirdFourth, thirdFourthAdapter);
661             removeFromSelection(getModel().firstSecondThird(), firstSecondThird, firstSecondThirdAdapter);
662             removeFromSelection(getModel().firstSecondFourth(), firstSecondFourth, firstSecondFourthAdapter);
663             removeFromSelection(getModel().firstThirdFourth(), firstThirdFourth, firstThirdFourthAdapter);
664             removeFromSelection(getModel().secondThirdFourth(), secondThirdFourth, secondThirdFourthAdapter);
665             removeFromSelection(getModel().intersection(), intersection, intersectionAdapter);
666             removeFromSelection(getModel().union(), union, unionAdapter);
667         }
668     }
669 
670     /**
671      * Clear the selection for the specified list if it is not a focus owner.
672      *
673      * @param list list
674      */
675     private void clearSelection(final JList list)
676     {
677         if (!list.isFocusOwner())
678         {
679             list.clearSelection();
680         }
681     }
682 
683     /**
684      * Add the specified element to the list selection if it is contained
685      * in the specified model and the list is not a focus owner.
686      *
687      * @param model model
688      * @param list list
689      * @param adapter adapter
690      * @param e element
691      */
692     private void addToSelection(final Set<E> model, final JList list, final List<E> adapter, final E e)
693     {
694         if (!list.isFocusOwner() && model.contains(e))
695         {
696             int index = adapter.indexOf(e);
697             list.getSelectionModel().addSelectionInterval(index, index);
698         }
699     }
700 
701     /**
702      * Remove elements from the list selection if they are not present in
703      * the specified model and the list is not a focus owner.
704      *
705      * @param model model
706      * @param list list
707      * @param adapter adapter
708      */
709     private void removeFromSelection(final Set<E> model, final JList list, final List<E> adapter)
710     {
711         if (!list.isFocusOwner())
712         {
713             // todo:  need element(s) that were removed from set change event
714             for (E e : model)
715             {
716                 if (!getModel().selection().contains(e))
717                 {
718                     int index = adapter.indexOf(e);
719                     list.getSelectionModel().removeSelectionInterval(index, index);
720                 }
721             }
722         }
723     }
724 
725     /**
726      * Return the contents of the first set.  The model for the returned
727      * JList should not be changed, as the current model implementation is
728      * synchronized to the quaternary venn model backing this venn diagram.
729      *
730      * @return the contents of the first set
731      */
732     public JList getFirst()
733     {
734         return first;
735     }
736 
737     /**
738      * Return the contents of the second set.  The model for the returned
739      * JList should not be changed, as the current model implementation is
740      * synchronized to the quaternary venn model backing this venn diagram.
741      *
742      * @return the contents of the second set
743      */
744     public JList getSecond()
745     {
746         return second;
747     }
748 
749     /**
750      * Return the contents of the third set.  The model for the returned
751      * JList should not be changed, as the current model implementation is
752      * synchronized to the quaternary venn model backing this venn diagram.
753      *
754      * @return the contents of the third set
755      */
756     public JList getThird()
757     {
758         return third;
759     }
760 
761     /**
762      * Return the contents of the fourth set.  The model for the returned
763      * JList should not be changed, as the current model implementation is
764      * synchronized to the quaternary venn model backing this venn diagram.
765      *
766      * @return the contents of the fourth set
767      */
768     public JList getFourth()
769     {
770         return fourth;
771     }
772 
773     /**
774      * Return the contents of the first only view.  The model for the returned
775      * JList should not be changed, as the current model implementation is
776      * synchronized to the quaternary venn model backing this venn diagram.
777      *
778      * @return the contents of the first only view
779      */
780     public JList getFirstOnly()
781     {
782         return firstOnly;
783     }
784 
785     /**
786      * Return the contents of the second only view.  The model for the returned
787      * JList should not be changed, as the current model implementation is
788      * synchronized to the quaternary venn model backing this venn diagram.
789      *
790      * @return the contents of the second only view
791      */
792     public JList getSecondOnly()
793     {
794         return secondOnly;
795     }
796 
797     /**
798      * Return the contents of the third only view.  The model for the returned
799      * JList should not be changed, as the current model implementation is
800      * synchronized to the quaternary venn model backing this venn diagram.
801      *
802      * @return the contents of the third only view
803      */
804     public JList getThirdOnly()
805     {
806         return thirdOnly;
807     }
808 
809     /**
810      * Return the contents of the fourth only view.  The model for the returned
811      * JList should not be changed, as the current model implementation is
812      * synchronized to the quaternary venn model backing this venn diagram.
813      *
814      * @return the contents of the fourth only view
815      */
816     public JList getFourthOnly()
817     {
818         return fourthOnly;
819     }
820 
821     /**
822      * Return the contents of the first second view.  The model for the returned
823      * JList should not be changed, as the current model implementation is
824      * synchronized to the quaternary venn model backing this venn diagram.
825      *
826      * @return the contents of the first second view
827      */
828     public JList getFirstSecond()
829     {
830         return firstSecond;
831     }
832 
833     /**
834      * Return the contents of the first third view.  The model for the returned
835      * JList should not be changed, as the current model implementation is
836      * synchronized to the quaternary venn model backing this venn diagram.
837      *
838      * @return the contents of the first third view
839      */
840     public JList getFirstThird()
841     {
842         return firstThird;
843     }
844 
845     /**
846      * Return the contents of the second third view.  The model for the returned
847      * JList should not be changed, as the current model implementation is
848      * synchronized to the quaternary venn model backing this venn diagram.
849      *
850      * @return the contents of the second third view
851      */
852     public JList getSecondThird()
853     {
854         return secondThird;
855     }
856 
857     /**
858      * Return the contents of the first fourth view.  The model for the returned
859      * JList should not be changed, as the current model implementation is
860      * synchronized to the quaternary venn model backing this venn diagram.
861      *
862      * @return the contents of the first fourth view
863      */
864     public JList getFirstFourth()
865     {
866         return firstFourth;
867     }
868 
869     /**
870      * Return the contents of the second fourth view.  The model for the returned
871      * JList should not be changed, as the current model implementation is
872      * synchronized to the quaternary venn model backing this venn diagram.
873      *
874      * @return the contents of the second fourth view
875      */
876     public JList getSecondFourth()
877     {
878         return secondFourth;
879     }
880 
881     /**
882      * Return the contents of the third fourth view.  The model for the returned
883      * JList should not be changed, as the current model implementation is
884      * synchronized to the quaternary venn model backing this venn diagram.
885      *
886      * @return the contents of the third fourth view
887      */
888     public JList getThirdFourth()
889     {
890         return thirdFourth;
891     }
892 
893     /**
894      * Return the contents of the first second third view.  The model for the returned
895      * JList should not be changed, as the current model implementation is
896      * synchronized to the quaternary venn model backing this venn diagram.
897      *
898      * @return the contents of the first second third view
899      */
900     public JList getFirstSecondThird()
901     {
902         return firstSecondThird;
903     }
904 
905     /**
906      * Return the contents of the first second fourth view.  The model for the returned
907      * JList should not be changed, as the current model implementation is
908      * synchronized to the quaternary venn model backing this venn diagram.
909      *
910      * @return the contents of the first second fourth view
911      */
912     public JList getFirstSecondFourth()
913     {
914         return firstSecondFourth;
915     }
916 
917     /**
918      * Return the contents of the first third fourth view.  The model for the returned
919      * JList should not be changed, as the current model implementation is
920      * synchronized to the quaternary venn model backing this venn diagram.
921      *
922      * @return the contents of the first third fourth view
923      */
924     public JList getFirstThirdFourth()
925     {
926         return firstThirdFourth;
927     }
928 
929     /**
930      * Return the contents of the second third fourth view.  The model for the returned
931      * JList should not be changed, as the current model implementation is
932      * synchronized to the quaternary venn model backing this venn diagram.
933      *
934      * @return the contents of the second third fourth view
935      */
936     public JList getSecondThirdFourth()
937     {
938         return secondThirdFourth;
939     }
940 
941     /**
942      * Return the contents of the intersection view.  The model for the returned
943      * JList should not be changed, as the current model implementation is
944      * synchronized to the quaternary venn model backing this venn diagram.
945      *
946      * @return the contents of the intersection view
947      */
948     public JList getIntersection()
949     {
950         return intersection;
951     }
952 
953     /**
954      * Return the contents of the union view.  The model for the returned
955      * JList should not be changed, as the current model implementation is
956      * synchronized to the quaternary venn model backing this venn diagram.
957      *
958      * @return the contents of the union view
959      */
960     public JList getUnion()
961     {
962         return union;
963     }
964 
965     /**
966      * Update selection view.
967      */
968     private class UpdateSelectionView implements ListSelectionListener
969     {
970         /** {@inheritDoc} */
971         public void valueChanged(final ListSelectionEvent event)
972         {
973             JList list = (JList) event.getSource();
974             if (list.isFocusOwner() && !event.getValueIsAdjusting())
975             {
976                 ListSelectionModel selectionModel = list.getSelectionModel();
977                 for (int index = event.getFirstIndex(); index < (event.getLastIndex() + 1); index++)
978                 {
979                     E e = (E) list.getModel().getElementAt(index);
980                     if (selectionModel.isSelectedIndex(index))
981                     {
982                         if (!getModel().selection().contains(e))
983                         {
984                             getModel().selection().add(e);
985                         }
986                     }
987                     else
988                     {
989                         if (getModel().selection().contains(e))
990                         {
991                             getModel().selection().remove(e);
992                         }
993                     }
994                 }
995             }
996             // todo:  may need to remove from selection view those
997             //    elements not present in model for focused list
998             //    e.g.  say "bar" is selected, select "foo" in First only
999         }
1000     }
1001 }