1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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.TernaryVennModel;
51
52
53
54
55
56
57
58
59 public final class TernaryVennList<E>
60 extends AbstractTernaryVennDiagram<E>
61 {
62
63 private final JList first = new JList();
64
65
66 private final JList second = new JList();
67
68
69 private final JList third = new JList();
70
71
72 private final JList firstOnly = new JList();
73
74
75 private final JList secondOnly = new JList();
76
77
78 private final JList thirdOnly = new JList();
79
80
81 private final JList firstSecond = new JList();
82
83
84 private final JList firstThird = new JList();
85
86
87 private final JList secondThird = new JList();
88
89
90 private final JList intersection = new JList();
91
92
93 private final JList union = new JList();
94
95
96 private ObservableSetEventListAdapter<E> firstAdapter;
97
98
99 private ObservableSetEventListAdapter<E> secondAdapter;
100
101
102 private ObservableSetEventListAdapter<E> thirdAdapter;
103
104
105 private SetEventListAdapter<E> firstOnlyAdapter;
106
107
108 private SetEventListAdapter<E> secondOnlyAdapter;
109
110
111 private SetEventListAdapter<E> thirdOnlyAdapter;
112
113
114 private SetEventListAdapter<E> firstSecondAdapter;
115
116
117 private SetEventListAdapter<E> firstThirdAdapter;
118
119
120 private SetEventListAdapter<E> secondThirdAdapter;
121
122
123 private SetEventListAdapter<E> intersectionAdapter;
124
125
126 private SetEventListAdapter<E> unionAdapter;
127
128
129 private final PropertyChangeListener modelChange = new PropertyChangeListener()
130 {
131
132 public void propertyChange(final PropertyChangeEvent event)
133 {
134 uninstallListModels((TernaryVennModel<E>) event.getOldValue());
135 installListModels();
136 }
137 };
138
139
140 private final SetChangeListener<E> updateListModels = new SetChangeListener<E>()
141 {
142
143 public void setChanged(final SetChangeEvent<E> event)
144 {
145 updateListModels();
146 }
147 };
148
149
150 private final SetChangeListener<E> updateSelection = new SetChangeListener<E>()
151 {
152
153 public void setChanged(final SetChangeEvent<E> event)
154 {
155 updateSelection();
156 }
157 };
158
159
160
161
162
163 public TernaryVennList()
164 {
165 super();
166 installListModels();
167 installSelectionListeners();
168 layoutComponents();
169 addPropertyChangeListener("model", modelChange);
170 }
171
172
173
174
175
176
177
178
179
180
181
182 public TernaryVennList(final String firstLabelText, final Set<? extends E> first,
183 final String secondLabelText, final Set<? extends E> second,
184 final String thirdLabelText, final Set<? extends E> third)
185 {
186 super(firstLabelText, first, secondLabelText, second, thirdLabelText, third);
187 installListModels();
188 installSelectionListeners();
189 layoutComponents();
190 addPropertyChangeListener("model", modelChange);
191 }
192
193
194
195
196
197
198 public TernaryVennList(final TernaryVennModel<E> model)
199 {
200 super(model);
201 installListModels();
202 installSelectionListeners();
203 layoutComponents();
204 addPropertyChangeListener("model", modelChange);
205 }
206
207
208
209
210
211 public void clearSelection()
212 {
213 union.requestFocusInWindow();
214 getModel().selection().clear();
215 }
216
217
218
219
220 public void selectAll()
221 {
222 union.requestFocusInWindow();
223
224 getModel().selection().addAll(getModel().union());
225 }
226
227
228
229
230 private void installListModels()
231 {
232 firstAdapter = new ObservableSetEventListAdapter<E>(getModel().first());
233 first.setModel(new EventListModel<E>(firstAdapter));
234 secondAdapter = new ObservableSetEventListAdapter<E>(getModel().second());
235 second.setModel(new EventListModel<E>(secondAdapter));
236 thirdAdapter = new ObservableSetEventListAdapter<E>(getModel().third());
237 third.setModel(new EventListModel<E>(thirdAdapter));
238
239 firstOnlyAdapter = new SetEventListAdapter<E>(getModel().firstOnly());
240 firstOnly.setModel(new EventListModel<E>(firstOnlyAdapter));
241 secondOnlyAdapter = new SetEventListAdapter<E>(getModel().secondOnly());
242 secondOnly.setModel(new EventListModel<E>(secondOnlyAdapter));
243 thirdOnlyAdapter = new SetEventListAdapter<E>(getModel().thirdOnly());
244 thirdOnly.setModel(new EventListModel<E>(thirdOnlyAdapter));
245 firstSecondAdapter = new SetEventListAdapter<E>(getModel().firstSecond());
246 firstSecond.setModel(new EventListModel<E>(firstSecondAdapter));
247 firstThirdAdapter = new SetEventListAdapter<E>(getModel().firstThird());
248 firstThird.setModel(new EventListModel<E>(firstThirdAdapter));
249 secondThirdAdapter = new SetEventListAdapter<E>(getModel().secondThird());
250 secondThird.setModel(new EventListModel<E>(secondThirdAdapter));
251 intersectionAdapter = new SetEventListAdapter<E>(getModel().intersection());
252 intersection.setModel(new EventListModel<E>(intersectionAdapter));
253 unionAdapter = new SetEventListAdapter<E>(getModel().union());
254 union.setModel(new EventListModel<E>(unionAdapter));
255
256 getModel().first().addSetChangeListener(updateListModels);
257 getModel().second().addSetChangeListener(updateListModels);
258 getModel().third().addSetChangeListener(updateListModels);
259 getModel().first().addSetChangeListener(updateSelection);
260 getModel().second().addSetChangeListener(updateSelection);
261 getModel().third().addSetChangeListener(updateSelection);
262 getModel().selection().addSetChangeListener(updateSelection);
263 }
264
265
266
267
268 private void updateListModels()
269 {
270 firstOnlyAdapter.updateEventList();
271 secondOnlyAdapter.updateEventList();
272 thirdOnlyAdapter.updateEventList();
273 firstSecondAdapter.updateEventList();
274 firstThirdAdapter.updateEventList();
275 secondThirdAdapter.updateEventList();
276 intersectionAdapter.updateEventList();
277 unionAdapter.updateEventList();
278 }
279
280
281
282
283
284
285 private void uninstallListModels(final TernaryVennModel<E> oldModel)
286 {
287 firstAdapter.dispose();
288 secondAdapter.dispose();
289 thirdAdapter.dispose();
290 ((EventListModel<E>) first.getModel()).dispose();
291 ((EventListModel<E>) second.getModel()).dispose();
292 ((EventListModel<E>) third.getModel()).dispose();
293 ((EventListModel<E>) firstOnly.getModel()).dispose();
294 ((EventListModel<E>) secondOnly.getModel()).dispose();
295 ((EventListModel<E>) thirdOnly.getModel()).dispose();
296 ((EventListModel<E>) firstSecond.getModel()).dispose();
297 ((EventListModel<E>) firstThird.getModel()).dispose();
298 ((EventListModel<E>) secondThird.getModel()).dispose();
299 ((EventListModel<E>) intersection.getModel()).dispose();
300 ((EventListModel<E>) union.getModel()).dispose();
301 oldModel.first().removeSetChangeListener(updateListModels);
302 oldModel.second().removeSetChangeListener(updateListModels);
303 oldModel.third().removeSetChangeListener(updateListModels);
304 oldModel.first().removeSetChangeListener(updateSelection);
305 oldModel.second().removeSetChangeListener(updateSelection);
306 oldModel.third().removeSetChangeListener(updateSelection);
307 oldModel.selection().removeSetChangeListener(updateSelection);
308 }
309
310
311
312
313 private void installSelectionListeners()
314 {
315 first.addListSelectionListener(new UpdateSelectionView());
316 second.addListSelectionListener(new UpdateSelectionView());
317 third.addListSelectionListener(new UpdateSelectionView());
318 firstOnly.addListSelectionListener(new UpdateSelectionView());
319 secondOnly.addListSelectionListener(new UpdateSelectionView());
320 thirdOnly.addListSelectionListener(new UpdateSelectionView());
321 firstSecond.addListSelectionListener(new UpdateSelectionView());
322 firstThird.addListSelectionListener(new UpdateSelectionView());
323 secondThird.addListSelectionListener(new UpdateSelectionView());
324 intersection.addListSelectionListener(new UpdateSelectionView());
325 union.addListSelectionListener(new UpdateSelectionView());
326 }
327
328
329 protected void updateContents()
330 {
331
332 }
333
334
335
336
337 private void layoutComponents()
338 {
339 addFinalField(createMainPanel());
340 }
341
342
343
344
345
346
347 private JPanel createMainPanel()
348 {
349 JPanel panel = new JPanel();
350 panel.setLayout(new GridLayout(3, 5, 12, 12));
351
352 LabelFieldPanel f = new LabelFieldPanel();
353 f.addLabel(getFirstLabel());
354 f.addFinalField(new JScrollPane(first));
355 panel.add(f);
356
357 LabelFieldPanel s = new LabelFieldPanel();
358 s.addLabel(getSecondLabel());
359 s.addFinalField(new JScrollPane(second));
360 panel.add(s);
361
362 LabelFieldPanel t = new LabelFieldPanel();
363 t.addLabel(getThirdLabel());
364 t.addFinalField(new JScrollPane(third));
365 panel.add(t);
366
367 panel.add(Box.createGlue());
368 panel.add(Box.createGlue());
369
370 LabelFieldPanel fo = new LabelFieldPanel();
371 fo.addLabel(getFirstOnlyLabel());
372 fo.addFinalField(new JScrollPane(firstOnly));
373 panel.add(fo);
374
375 LabelFieldPanel so = new LabelFieldPanel();
376 so.addLabel(getSecondOnlyLabel());
377 so.addFinalField(new JScrollPane(secondOnly));
378 panel.add(so);
379
380 LabelFieldPanel to = new LabelFieldPanel();
381 to.addLabel(getThirdOnlyLabel());
382 to.addFinalField(new JScrollPane(thirdOnly));
383 panel.add(to);
384
385 panel.add(Box.createGlue());
386 panel.add(Box.createGlue());
387
388 LabelFieldPanel fs = new LabelFieldPanel();
389 fs.addLabel(getFirstSecondLabel());
390 fs.addFinalField(new JScrollPane(firstSecond));
391 panel.add(fs);
392
393 LabelFieldPanel ft = new LabelFieldPanel();
394 ft.addLabel(getFirstThirdLabel());
395 ft.addFinalField(new JScrollPane(firstThird));
396 panel.add(ft);
397
398 LabelFieldPanel st = new LabelFieldPanel();
399 st.addLabel(getSecondThirdLabel());
400 st.addFinalField(new JScrollPane(secondThird));
401 panel.add(st);
402
403 LabelFieldPanel n = new LabelFieldPanel();
404 n.addLabel(getIntersectionLabel());
405 n.addFinalField(new JScrollPane(intersection));
406 panel.add(n);
407
408 LabelFieldPanel u = new LabelFieldPanel();
409 u.addLabel(getUnionLabel());
410 u.addFinalField(new JScrollPane(union));
411 panel.add(u);
412 return panel;
413 }
414
415
416
417
418 private void updateSelection()
419 {
420 if (getModel().selection().isEmpty())
421 {
422 clearSelection(first);
423 clearSelection(second);
424 clearSelection(third);
425 clearSelection(firstOnly);
426 clearSelection(secondOnly);
427 clearSelection(thirdOnly);
428 clearSelection(firstSecond);
429 clearSelection(firstThird);
430 clearSelection(secondThird);
431 clearSelection(intersection);
432 clearSelection(union);
433 }
434 else
435 {
436
437 for (E e : getModel().selection())
438 {
439 addToSelection(getModel().first(), first, firstAdapter, e);
440 addToSelection(getModel().second(), second, secondAdapter, e);
441 addToSelection(getModel().third(), third, thirdAdapter, e);
442 addToSelection(getModel().firstOnly(), firstOnly, firstOnlyAdapter, e);
443 addToSelection(getModel().secondOnly(), secondOnly, secondOnlyAdapter, e);
444 addToSelection(getModel().thirdOnly(), thirdOnly, thirdOnlyAdapter, e);
445 addToSelection(getModel().firstSecond(), firstSecond, firstSecondAdapter, e);
446 addToSelection(getModel().firstThird(), firstThird, firstThirdAdapter, e);
447 addToSelection(getModel().secondThird(), secondThird, secondThirdAdapter, e);
448 addToSelection(getModel().intersection(), intersection, intersectionAdapter, e);
449 addToSelection(getModel().union(), union, unionAdapter, e);
450 }
451
452 removeFromSelection(getModel().first(), first, firstAdapter);
453 removeFromSelection(getModel().second(), second, secondAdapter);
454 removeFromSelection(getModel().third(), third, thirdAdapter);
455 removeFromSelection(getModel().firstOnly(), firstOnly, firstOnlyAdapter);
456 removeFromSelection(getModel().secondOnly(), secondOnly, secondOnlyAdapter);
457 removeFromSelection(getModel().thirdOnly(), thirdOnly, thirdOnlyAdapter);
458 removeFromSelection(getModel().firstSecond(), firstSecond, firstSecondAdapter);
459 removeFromSelection(getModel().firstThird(), firstThird, firstThirdAdapter);
460 removeFromSelection(getModel().secondThird(), secondThird, secondThirdAdapter);
461 removeFromSelection(getModel().intersection(), intersection, intersectionAdapter);
462 removeFromSelection(getModel().union(), union, unionAdapter);
463 }
464 }
465
466
467
468
469
470
471 private void clearSelection(final JList list)
472 {
473 if (!list.isFocusOwner())
474 {
475 list.clearSelection();
476 }
477 }
478
479
480
481
482
483
484
485
486
487
488 private void addToSelection(final Set<E> model, final JList list, final List<E> adapter, final E e)
489 {
490 if (!list.isFocusOwner() && model.contains(e))
491 {
492 int index = adapter.indexOf(e);
493 list.getSelectionModel().addSelectionInterval(index, index);
494 }
495 }
496
497
498
499
500
501
502
503
504
505 private void removeFromSelection(final Set<E> model, final JList list, final List<E> adapter)
506 {
507 if (!list.isFocusOwner())
508 {
509
510 for (E e : model)
511 {
512 if (!getModel().selection().contains(e))
513 {
514 int index = adapter.indexOf(e);
515 list.getSelectionModel().removeSelectionInterval(index, index);
516 }
517 }
518 }
519 }
520
521
522
523
524
525
526
527
528 public JList getFirst()
529 {
530 return first;
531 }
532
533
534
535
536
537
538
539
540 public JList getSecond()
541 {
542 return second;
543 }
544
545
546
547
548
549
550
551
552 public JList getThird()
553 {
554 return third;
555 }
556
557
558
559
560
561
562
563
564 public JList getFirstOnly()
565 {
566 return firstOnly;
567 }
568
569
570
571
572
573
574
575
576 public JList getSecondOnly()
577 {
578 return secondOnly;
579 }
580
581
582
583
584
585
586
587
588 public JList getThirdOnly()
589 {
590 return thirdOnly;
591 }
592
593
594
595
596
597
598
599
600 public JList getFirstSecond()
601 {
602 return firstSecond;
603 }
604
605
606
607
608
609
610
611
612 public JList getFirstThird()
613 {
614 return firstThird;
615 }
616
617
618
619
620
621
622
623
624 public JList getSecondThird()
625 {
626 return secondThird;
627 }
628
629
630
631
632
633
634
635
636 public JList getIntersection()
637 {
638 return intersection;
639 }
640
641
642
643
644
645
646
647
648 public JList getUnion()
649 {
650 return union;
651 }
652
653
654
655
656 private class UpdateSelectionView implements ListSelectionListener
657 {
658
659 public void valueChanged(final ListSelectionEvent event)
660 {
661 JList list = (JList) event.getSource();
662 if (list.isFocusOwner() && !event.getValueIsAdjusting())
663 {
664 ListSelectionModel selectionModel = list.getSelectionModel();
665 for (int index = event.getFirstIndex(); index < (event.getLastIndex() + 1); index++)
666 {
667 E e = (E) list.getModel().getElementAt(index);
668 if (selectionModel.isSelectedIndex(index))
669 {
670 if (!getModel().selection().contains(e))
671 {
672 getModel().selection().add(e);
673 }
674 }
675 else
676 {
677 if (getModel().selection().contains(e))
678 {
679 getModel().selection().remove(e);
680 }
681 }
682 }
683 }
684
685
686
687 }
688 }
689 }