1
+ package org .baderlab .csplugins .enrichmentmap .task .tunables ;
2
+
3
+ import static javax .swing .GroupLayout .DEFAULT_SIZE ;
4
+ import static javax .swing .GroupLayout .PREFERRED_SIZE ;
5
+ import static javax .swing .GroupLayout .Alignment .CENTER ;
6
+ import static org .cytoscape .util .swing .LookAndFeelUtil .isAquaLAF ;
7
+
8
+ import java .util .ArrayList ;
9
+ import java .util .Collections ;
10
+ import java .util .List ;
11
+ import java .util .stream .Collectors ;
12
+
13
+ import javax .swing .GroupLayout ;
14
+ import javax .swing .JButton ;
15
+ import javax .swing .JPanel ;
16
+ import javax .swing .JScrollPane ;
17
+ import javax .swing .event .ListDataEvent ;
18
+ import javax .swing .event .ListDataListener ;
19
+
20
+ import org .baderlab .csplugins .enrichmentmap .view .util .CheckboxData ;
21
+ import org .baderlab .csplugins .enrichmentmap .view .util .CheckboxList ;
22
+ import org .baderlab .csplugins .enrichmentmap .view .util .CheckboxListModel ;
23
+ import org .cytoscape .util .swing .LookAndFeelUtil ;
24
+
25
+ @ SuppressWarnings ("serial" )
26
+ public class GeneListPanel <T > extends JPanel {
27
+
28
+ private CheckboxList <T > checkboxList ;
29
+ private CheckboxListModel <T > checkboxListModel ;
30
+ private JButton selectAllButton ;
31
+ private JButton selectNoneButton ;
32
+
33
+
34
+ public GeneListPanel () {
35
+ checkboxListModel = new CheckboxListModel <>();
36
+ checkboxList = new CheckboxList <>(checkboxListModel );
37
+
38
+ JScrollPane scrollPane = new JScrollPane ();
39
+ scrollPane .setViewportView (checkboxList );
40
+
41
+ selectAllButton = new JButton ("Select All" );
42
+ selectNoneButton = new JButton ("Select None" );
43
+
44
+ selectAllButton .addActionListener (e -> {
45
+ List <CheckboxData <T >> oldValue = getSelectedData ();
46
+ checkboxListModel .forEach (cb -> cb .setSelected (true ));
47
+ checkboxList .invalidate ();
48
+ checkboxList .repaint ();
49
+ updateSelectionButtons ();
50
+ firePropertyChange ("selectedData" , oldValue , getSelectedData ());
51
+ });
52
+ selectNoneButton .addActionListener (e -> {
53
+ List <CheckboxData <T >> oldValue = getSelectedData ();
54
+ checkboxListModel .forEach (cb -> cb .setSelected (false ));
55
+ checkboxList .invalidate ();
56
+ checkboxList .repaint ();
57
+ updateSelectionButtons ();
58
+ firePropertyChange ("selectedData" , oldValue , Collections .emptyList ());
59
+ });
60
+
61
+
62
+ selectAllButton .setEnabled (false );
63
+ selectNoneButton .setEnabled (false );
64
+
65
+ checkboxListModel .addListDataListener (new ListDataListener () {
66
+ @ Override
67
+ public void intervalRemoved (ListDataEvent e ) {
68
+ updateSelectionButtons ();
69
+ }
70
+ @ Override
71
+ public void intervalAdded (ListDataEvent e ) {
72
+ updateSelectionButtons ();
73
+ }
74
+ @ Override
75
+ public void contentsChanged (ListDataEvent e ) {
76
+ updateSelectionButtons ();
77
+ }
78
+ });
79
+
80
+ checkboxList .addListSelectionListener (evt -> {
81
+ if (!evt .getValueIsAdjusting ()) {
82
+ updateSelectionButtons ();
83
+ firePropertyChange ("selectedData" , null , getSelectedData ());
84
+ }
85
+ });
86
+
87
+ if (isAquaLAF ()) {
88
+ selectAllButton .putClientProperty ("JButton.buttonType" , "gradient" );
89
+ selectAllButton .putClientProperty ("JComponent.sizeVariant" , "small" );
90
+ selectNoneButton .putClientProperty ("JButton.buttonType" , "gradient" );
91
+ selectNoneButton .putClientProperty ("JComponent.sizeVariant" , "small" );
92
+ }
93
+
94
+ LookAndFeelUtil .equalizeSize (selectAllButton , selectNoneButton );
95
+
96
+ final GroupLayout layout = new GroupLayout (this );
97
+ setLayout (layout );
98
+ layout .setAutoCreateContainerGaps (false );
99
+ layout .setAutoCreateGaps (!LookAndFeelUtil .isAquaLAF ());
100
+
101
+ layout .setHorizontalGroup (layout .createSequentialGroup ()
102
+ .addComponent (scrollPane , DEFAULT_SIZE , DEFAULT_SIZE , Short .MAX_VALUE )
103
+ .addGroup (layout .createParallelGroup (CENTER , true )
104
+ .addComponent (selectAllButton , PREFERRED_SIZE , DEFAULT_SIZE , PREFERRED_SIZE )
105
+ .addComponent (selectNoneButton , PREFERRED_SIZE , DEFAULT_SIZE , PREFERRED_SIZE )
106
+ )
107
+ );
108
+ layout .setVerticalGroup (layout .createParallelGroup ()
109
+ .addComponent (scrollPane , DEFAULT_SIZE , DEFAULT_SIZE , Short .MAX_VALUE )
110
+ .addGroup (layout .createSequentialGroup ()
111
+ .addComponent (selectAllButton )
112
+ .addComponent (selectNoneButton )
113
+ )
114
+ );
115
+
116
+ if (LookAndFeelUtil .isAquaLAF ())
117
+ setOpaque (false );
118
+ }
119
+
120
+
121
+ private void updateSelectionButtons () {
122
+ boolean enabled = isEnabled () && !checkboxListModel .isEmpty ();
123
+ List <CheckboxData <T >> selectedData = getSelectedData ();
124
+
125
+ selectAllButton .setEnabled (enabled && selectedData .size () < checkboxListModel .size ());
126
+ selectNoneButton .setEnabled (enabled && selectedData .size () > 0 );
127
+ }
128
+
129
+ public CheckboxList <T > getCheckboxList () {
130
+ return checkboxList ;
131
+ }
132
+
133
+ public CheckboxListModel <T > getModel () {
134
+ return checkboxListModel ;
135
+ }
136
+
137
+ public List <T > getSelectedDataItems () {
138
+ return checkboxListModel .stream ()
139
+ .filter (CheckboxData ::isSelected )
140
+ .map (CheckboxData ::getData )
141
+ .collect (Collectors .toList ());
142
+ }
143
+
144
+ @ Override
145
+ public void setEnabled (boolean enabled ) {
146
+ super .setEnabled (enabled );
147
+ checkboxList .setEnabled (enabled );
148
+ updateSelectionButtons ();
149
+ }
150
+
151
+ public List <CheckboxData <T >> getSelectedData () {
152
+ List <CheckboxData <T >> list = new ArrayList <>();
153
+ int size = getModel ().getSize ();
154
+
155
+ for (int i = 0 ; i < size ; i ++) {
156
+ CheckboxData <T > data = (CheckboxData <T >) getModel ().getElementAt (i );
157
+
158
+ if (data .isSelected ())
159
+ list .add (data );
160
+ }
161
+
162
+ return list ;
163
+ }
164
+ }
0 commit comments