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.eventlist.view;
25
26 import static org.dishevelled.iconbundle.tango.TangoProject.EDIT_COPY;
27 import static org.dishevelled.iconbundle.tango.TangoProject.EDIT_CUT;
28 import static org.dishevelled.iconbundle.tango.TangoProject.EDIT_PASTE;
29 import static org.dishevelled.iconbundle.tango.TangoProject.EDIT_SELECT_ALL;
30 import static org.dishevelled.iconbundle.tango.TangoProject.EXTRA_SMALL;
31 import static org.dishevelled.iconbundle.tango.TangoProject.LIST_ADD;
32 import static org.dishevelled.iconbundle.tango.TangoProject.LIST_REMOVE;
33 import static org.dishevelled.iconbundle.tango.TangoProject.SIZES;
34
35 import java.awt.event.ActionEvent;
36
37 import java.util.ArrayList;
38 import java.util.List;
39
40 import javax.swing.AbstractAction;
41 import javax.swing.Box;
42 import javax.swing.BoxLayout;
43 import javax.swing.JCheckBoxMenuItem;
44 import javax.swing.JLabel;
45 import javax.swing.JPanel;
46 import javax.swing.JPopupMenu;
47 import javax.swing.ListSelectionModel;
48
49 import javax.swing.border.EmptyBorder;
50
51 import javax.swing.event.EventListenerList;
52 import javax.swing.event.ListSelectionEvent;
53 import javax.swing.event.ListSelectionListener;
54
55 import ca.odell.glazedlists.EventList;
56 import ca.odell.glazedlists.ListSelection;
57
58 import ca.odell.glazedlists.event.ListEvent;
59 import ca.odell.glazedlists.event.ListEventListener;
60
61 import org.dishevelled.iconbundle.IconSize;
62
63 import org.dishevelled.identify.ContextMenuButton;
64 import org.dishevelled.identify.ContextMenuListener;
65 import org.dishevelled.identify.IdPopupMenu;
66 import org.dishevelled.identify.IdToolBar;
67 import org.dishevelled.identify.IdentifiableAction;
68
69
70
71
72
73
74
75 public abstract class AbstractEventListView<E>
76 extends JPanel
77 implements EventListView<E>
78 {
79
80 private final EventListViewSupport<E> eventListViewSupport;
81
82
83 private final JLabel label;
84
85
86 private final IdToolBar toolBar;
87
88
89 private final IdPopupMenu contextMenu;
90
91
92 private final JPopupMenu toolBarContextMenu;
93
94
95 private final ContextMenuButton contextMenuButton;
96
97
98 private final ListSelectionModelAdapter listSelectionModelAdapter;
99
100
101 private final IdentifiableAction selectAllAction = new IdentifiableAction("Select all", EDIT_SELECT_ALL)
102 {
103 @Override
104 public void actionPerformed(final ActionEvent event)
105 {
106 selectAll();
107 }
108 };
109
110
111 private final AbstractAction clearSelectionAction = new AbstractAction("Clear selection")
112 {
113 @Override
114 public void actionPerformed(final ActionEvent event)
115 {
116 clearSelection();
117 }
118 };
119
120
121 private final AbstractAction invertSelectionAction = new AbstractAction("Invert selection")
122 {
123 @Override
124 public void actionPerformed(final ActionEvent event)
125 {
126 invertSelection();
127 }
128 };
129
130
131 private final IdentifiableAction cutAction = new IdentifiableAction("Cut", EDIT_CUT)
132 {
133 @Override
134 public void actionPerformed(final ActionEvent event)
135 {
136 cut();
137 }
138 };
139
140
141 private final IdentifiableAction copyAction = new IdentifiableAction("Copy", EDIT_COPY)
142 {
143 @Override
144 public void actionPerformed(final ActionEvent event)
145 {
146 copy();
147 }
148 };
149
150
151 private final IdentifiableAction pasteAction = new IdentifiableAction("Paste", EDIT_PASTE)
152 {
153 @Override
154 public void actionPerformed(final ActionEvent event)
155 {
156 paste();
157 }
158 };
159
160
161 private final IdentifiableAction addAction = new IdentifiableAction("Add", LIST_ADD)
162 {
163 @Override
164 public void actionPerformed(final ActionEvent event)
165 {
166 add();
167 }
168 };
169
170
171 private final IdentifiableAction removeAction = new IdentifiableAction("Remove", LIST_REMOVE)
172 {
173 @Override
174 public void actionPerformed(final ActionEvent event)
175 {
176 remove();
177 }
178 };
179
180
181 private final AbstractAction removeAllAction = new AbstractAction("Remove all")
182 {
183 @Override
184 public void actionPerformed(final ActionEvent event)
185 {
186 clear();
187 }
188 };
189
190
191 private ListEventListener<E> listener = new ListEventListener<E>()
192 {
193 @Override
194 public void listChanged(final ListEvent<E> event)
195 {
196 updateListActions();
197 }
198 };
199
200
201 private ListSelection.Listener selectionListener = new ListSelection.Listener()
202 {
203 @Override
204 public void selectionChanged(final int index0, final int index1)
205 {
206 updateSelectionActions();
207 }
208 };
209
210
211
212
213
214
215
216 protected AbstractEventListView(final EventList<E> model)
217 {
218 super();
219 setOpaque(false);
220 eventListViewSupport = new EventListViewSupport<E>(model);
221 getModel().addListEventListener(listener);
222 getSelectionModel().addSelectionListener(selectionListener);
223 updateListActions();
224 updateSelectionActions();
225
226 label = new JLabel();
227 label.setAlignmentY(-1.0f);
228 label.setBorder(new EmptyBorder(0, 2, 2, 0));
229
230 contextMenu = new IdPopupMenu();
231 contextMenu.add(getCutAction(), EXTRA_SMALL);
232 contextMenu.add(getCopyAction(), EXTRA_SMALL);
233 contextMenu.add(getPasteAction(), EXTRA_SMALL);
234 contextMenu.addSeparator();
235 contextMenu.add(getSelectAllAction(), EXTRA_SMALL);
236 contextMenu.add(getClearSelectionAction());
237 contextMenu.add(getInvertSelectionAction());
238 contextMenu.addSeparator();
239 contextMenu.add(getAddAction(), EXTRA_SMALL);
240 contextMenu.add(getRemoveAction(), EXTRA_SMALL);
241 contextMenu.add(getRemoveAllAction());
242
243 toolBar = new IdToolBar();
244 toolBar.setOpaque(false);
245 toolBar.setBorder(new EmptyBorder(0, 0, 0, 0));
246 toolBar.add(getAddAction());
247 toolBar.add(getRemoveAction());
248 contextMenuButton = toolBar.add(contextMenu);
249
250 toolBarContextMenu = new JPopupMenu();
251 for (Object menuItem : toolBar.getDisplayMenuItems())
252 {
253 toolBarContextMenu.add((JCheckBoxMenuItem) menuItem);
254 }
255 toolBarContextMenu.addSeparator();
256 for (Object iconSize : SIZES)
257 {
258 toolBarContextMenu.add(toolBar.createIconSizeMenuItem((IconSize) iconSize));
259 }
260 toolBar.setIconSize(EXTRA_SMALL);
261 toolBar.addMouseListener(new ContextMenuListener(toolBarContextMenu));
262
263 listSelectionModelAdapter = new ListSelectionModelAdapter();
264 }
265
266
267
268
269
270 private void updateListActions()
271 {
272 selectAllAction.setEnabled(!isEmpty());
273 invertSelectionAction.setEnabled(!isEmpty());
274 removeAllAction.setEnabled(!isEmpty());
275 }
276
277
278
279
280 private void updateSelectionActions()
281 {
282 copyAction.setEnabled(!isSelectionEmpty());
283 cutAction.setEnabled(!isSelectionEmpty());
284 removeAction.setEnabled(!isSelectionEmpty());
285 clearSelectionAction.setEnabled(!isSelectionEmpty());
286 }
287
288
289
290
291
292
293 public final boolean isEmpty()
294 {
295 return getModel().isEmpty();
296 }
297
298
299
300
301
302
303 public final boolean isSelectionEmpty()
304 {
305 return getSelectionModel().getSelected().isEmpty();
306 }
307
308
309
310
311 public final void selectAll()
312 {
313 getSelectionModel().selectAll();
314 }
315
316
317
318
319 public final void clearSelection()
320 {
321 getSelectionModel().deselectAll();
322 }
323
324
325
326
327 public final void invertSelection()
328 {
329 getSelectionModel().invertSelection();
330 }
331
332
333
334
335 public final void cut()
336 {
337 if (!isSelectionEmpty())
338 {
339 cut(new ArrayList<E>(getSelectionModel().getSelected()));
340 }
341 }
342
343
344
345
346 public final void copy()
347 {
348 if (!isSelectionEmpty())
349 {
350 copy(new ArrayList<E>(getSelectionModel().getSelected()));
351 }
352 }
353
354
355
356
357
358
359 protected abstract void cut(List<E> toCut);
360
361
362
363
364
365
366 protected abstract void copy(List<E> toCopy);
367
368
369
370
371 public abstract void add();
372
373
374
375
376 public abstract void paste();
377
378
379
380
381 public final void remove()
382 {
383 getSelectionModel().getSelected().clear();
384 }
385
386
387
388
389 public final void clear()
390 {
391 getModel().clear();
392 }
393
394
395
396
397
398
399 protected final IdentifiableAction getSelectAllAction()
400 {
401 return selectAllAction;
402 }
403
404
405
406
407
408
409 protected final AbstractAction getClearSelectionAction()
410 {
411 return clearSelectionAction;
412 }
413
414
415
416
417
418
419 protected final AbstractAction getInvertSelectionAction()
420 {
421 return invertSelectionAction;
422 }
423
424
425
426
427
428
429 protected final IdentifiableAction getCutAction()
430 {
431 return cutAction;
432 }
433
434
435
436
437
438
439 protected final IdentifiableAction getCopyAction()
440 {
441 return copyAction;
442 }
443
444
445
446
447
448
449 protected final IdentifiableAction getPasteAction()
450 {
451 return pasteAction;
452 }
453
454
455
456
457
458
459 protected final IdentifiableAction getAddAction()
460 {
461 return addAction;
462 }
463
464
465
466
467
468
469 protected final IdentifiableAction getRemoveAction()
470 {
471 return removeAction;
472 }
473
474
475
476
477
478
479 protected final AbstractAction getRemoveAllAction()
480 {
481 return removeAllAction;
482 }
483
484
485
486
487
488
489 protected final JLabel getLabel()
490 {
491 return label;
492 }
493
494
495
496
497
498
499 protected final IdToolBar getToolBar()
500 {
501 return toolBar;
502 }
503
504
505
506
507
508
509 protected final IdPopupMenu getContextMenu()
510 {
511 return contextMenu;
512 }
513
514
515
516
517
518
519 protected final JPopupMenu getToolBarContextMenu()
520 {
521 return toolBarContextMenu;
522 }
523
524
525
526
527
528
529 protected final ContextMenuButton getContextMenuButton()
530 {
531 return contextMenuButton;
532 }
533
534
535
536
537
538
539 protected final JPanel createToolBarPanel()
540 {
541 JPanel panel = new JPanel();
542 panel.setOpaque(false);
543 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
544 panel.add(getLabel());
545 panel.add(Box.createGlue());
546 panel.add(Box.createGlue());
547 panel.add(getToolBar());
548 panel.addMouseListener(new ContextMenuListener(getToolBarContextMenu()));
549 return panel;
550 }
551
552
553
554
555
556
557 protected ListSelectionModelAdapter getListSelectionModelAdapter()
558 {
559 return listSelectionModelAdapter;
560 }
561
562 @Override
563 public final EventList<E> getModel()
564 {
565 return eventListViewSupport.getModel();
566 }
567
568 @Override
569 public final ListSelection<E> getSelectionModel()
570 {
571 return eventListViewSupport.getSelectionModel();
572 }
573
574
575
576
577
578
579 public void dispose()
580 {
581 getModel().removeListEventListener(listener);
582 getSelectionModel().removeSelectionListener(selectionListener);
583 getSelectionModel().removeSelectionListener(listSelectionModelAdapter.getSelectionListener());
584 }
585
586
587
588
589 protected final class ListSelectionModelAdapter implements ListSelectionModel
590 {
591
592 private final EventListenerList listenerList;
593
594
595 private boolean valueIsAdjusting = false;
596
597
598 private int fullIndex0 = -1;
599
600
601 private int fullIndex1 = -1;
602
603
604 private final ListSelection.Listener listSelectionListener = new ListSelection.Listener()
605 {
606 @Override
607 public void selectionChanged(final int index0, final int index1)
608 {
609 fireSelectionChanged(index0, index1);
610 }
611 };
612
613
614
615
616
617 private ListSelectionModelAdapter()
618 {
619 listenerList = new EventListenerList();
620 getSelectionModel().addSelectionListener(listSelectionListener);
621 }
622
623
624 @Override
625 public void setSelectionInterval(final int index0, final int index1)
626 {
627 getSelectionModel().setSelection(index0, index1);
628 }
629
630 @Override
631 public void addSelectionInterval(final int index0, final int index1)
632 {
633 getSelectionModel().select(index0, index1);
634 }
635
636 @Override
637 public void removeSelectionInterval(final int index0, final int index1)
638 {
639 getSelectionModel().deselect(index0, index1);
640 }
641
642 @Override
643 public int getMinSelectionIndex()
644 {
645 return getSelectionModel().getMinSelectionIndex();
646 }
647
648 @Override
649 public int getMaxSelectionIndex()
650 {
651 return getSelectionModel().getMaxSelectionIndex();
652 }
653
654 @Override
655 public boolean isSelectedIndex(final int index)
656 {
657 return getSelectionModel().isSelected(index);
658 }
659
660 @Override
661 public int getAnchorSelectionIndex()
662 {
663 return getSelectionModel().getAnchorSelectionIndex();
664 }
665
666 @Override
667 public void setAnchorSelectionIndex(final int index)
668 {
669 getSelectionModel().setAnchorSelectionIndex(index);
670 }
671
672 @Override
673 public int getLeadSelectionIndex()
674 {
675 return getSelectionModel().getLeadSelectionIndex();
676 }
677
678 @Override
679 public void setLeadSelectionIndex(final int index)
680 {
681 getSelectionModel().setLeadSelectionIndex(index);
682 }
683
684 @Override
685 public void clearSelection()
686 {
687 getSelectionModel().deselectAll();
688 }
689
690 @Override
691 public boolean isSelectionEmpty()
692 {
693 return getSelectionModel().getSelected().isEmpty();
694 }
695
696 @Override
697 public void insertIndexInterval(final int index, final int length, final boolean before)
698 {
699
700 }
701
702 @Override
703 public void removeIndexInterval(final int index0, final int index1)
704 {
705
706 }
707
708 @Override
709 public void setValueIsAdjusting(final boolean valueIsAdjusting)
710 {
711 if (!valueIsAdjusting)
712 {
713 if ((fullIndex0 != -1) && (fullIndex1 != -1))
714 {
715 fireSelectionChanged(fullIndex0, fullIndex1);
716 fullIndex0 = -1;
717 fullIndex1 = -1;
718 }
719 }
720 this.valueIsAdjusting = valueIsAdjusting;
721 }
722
723 @Override
724 public boolean getValueIsAdjusting()
725 {
726 return valueIsAdjusting;
727 }
728
729 @Override
730 public void setSelectionMode(final int selectionMode)
731 {
732 getSelectionModel().setSelectionMode(selectionMode);
733 }
734
735 @Override
736 public int getSelectionMode()
737 {
738 return getSelectionModel().getSelectionMode();
739 }
740
741 @Override
742 public void addListSelectionListener(final ListSelectionListener listener)
743 {
744 listenerList.add(ListSelectionListener.class, listener);
745 }
746
747 @Override
748 public void removeListSelectionListener(final ListSelectionListener listener)
749 {
750 listenerList.remove(ListSelectionListener.class, listener);
751 }
752
753
754
755
756
757
758
759 private void fireSelectionChanged(final int index0, final int index1)
760 {
761 if (valueIsAdjusting)
762 {
763 if ((fullIndex0 == -1) || (index0 < fullIndex0))
764 {
765 fullIndex0 = index0;
766 }
767 if ((fullIndex1 == -1) || (index1 > fullIndex1))
768 {
769 fullIndex1 = index1;
770 }
771 }
772 Object[] listeners = listenerList.getListenerList();
773 ListSelectionEvent e = null;
774
775 for (int i = listeners.length - 2; i >= 0; i -= 2)
776 {
777 if (listeners[i] == ListSelectionListener.class)
778 {
779
780 if (e == null)
781 {
782 e = new ListSelectionEvent(this, index0, index1, valueIsAdjusting);
783 }
784 ((ListSelectionListener) listeners[i + 1]).valueChanged(e);
785 }
786 }
787 }
788
789
790
791
792
793
794 private ListSelection.Listener getSelectionListener()
795 {
796 return listSelectionListener;
797 }
798 }
799 }