1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.aequo.gui;
14
15 import java.awt.Point;
16 import java.awt.Rectangle;
17 import java.awt.event.MouseEvent;
18 import java.awt.event.MouseListener;
19 import java.awt.event.MouseMotionListener;
20
21 import javax.swing.JList;
22 import javax.swing.JPopupMenu;
23 import javax.swing.ListSelectionModel;
24 import javax.swing.event.MouseInputListener;
25
26 import org.abstracthorizon.aequo.CompareModel;
27 import org.abstracthorizon.aequo.ListModelAdapter;
28
29
30
31
32
33
34 public class CompareList extends JList {
35
36
37 protected CompareModel<?, ?> model;
38
39
40 protected int focusedIndex;
41
42
43
44
45
46 public CompareList(final CompareModel<?, ?> model) {
47 super(new ListModelAdapter(model));
48 adjustMouseListeners();
49 }
50
51
52
53
54
55 public int getFocusedIndex() {
56 return focusedIndex;
57 }
58
59
60
61
62
63 public CompareModel<?, ?> getCompareModel() {
64 return model;
65 }
66
67
68
69
70
71 protected void adjustMouseListeners() {
72 MouseListener[] mls = getMouseListeners();
73 for (MouseListener ml : mls) {
74 removeMouseListener(ml);
75 }
76 MouseMotionListener[] mmls = getMouseMotionListeners();
77 for (MouseMotionListener mml : mmls) {
78 removeMouseMotionListener(mml);
79 }
80 MouseHandler mouseInputHandler = new MouseHandler();
81 addMouseListener(mouseInputHandler);
82 addMouseMotionListener(mouseInputHandler);
83 }
84
85
86
87
88 public class MouseHandler implements MouseInputListener {
89
90 private int startIndex = -1;
91 private int lastIndex = -1;
92 private int[] startIndices;
93 private boolean select = false;
94
95 public MouseHandler() {
96 }
97
98 public void mouseClicked(MouseEvent e) {}
99
100 public void mouseEntered(MouseEvent e) {}
101
102 public void mouseExited(MouseEvent e) {}
103
104 public void mousePressed(MouseEvent e) {
105 int i = selectedIndex(e.getPoint());
106 focusedIndex = i;
107 if ((e.getButton() == MouseEvent.BUTTON1) || ((i >= 0) && !isSelectedIndex(i))) {
108 startIndex = i;
109 lastIndex = -1;
110 if (e.isControlDown()) {
111 if (isSelectedIndex(i)) {
112 select = false;
113 removeSelectionInterval(i, i);
114 } else {
115 select = true;
116 getSelectionModel().addSelectionInterval(i, i);
117 }
118 startIndices = getSelectedIndices();
119 } else {
120 select = true;
121 startIndices = null;
122 setSelectedIndex(i);
123 }
124 } else if ((e.getButton() == MouseEvent.BUTTON2) && !isSelectedIndex(i)) {
125 getSelectionModel().addSelectionInterval(i, i);
126 } else {
127 startIndex = -1;
128 }
129 e.getComponent().requestFocus();
130 }
131
132
133 public void mouseDragged(MouseEvent e) {
134 int i = selectedIndex(e.getPoint());
135 focusedIndex = i;
136
137
138 ListSelectionModel selectionModel = getSelectionModel();
139 if (i >= 0) {
140 boolean ok = false;
141 if (lastIndex < 0) {
142 if (select) {
143 selectionModel.addSelectionInterval(startIndex, i);
144 } else {
145 selectionModel.removeSelectionInterval(startIndex, i);
146 }
147 ok = true;
148 } else if (startIndex <= lastIndex) {
149 if (lastIndex < i) {
150 if (select) {
151 selectionModel.addSelectionInterval(lastIndex, i);
152 } else {
153 selectionModel.removeSelectionInterval(lastIndex, i);
154 }
155 } else if (i < lastIndex) {
156 restoreSelection(i + 1, lastIndex);
157 }
158 ok = true;
159 } else if (lastIndex < startIndex) {
160 if (i < lastIndex) {
161 if (select) {
162 selectionModel.addSelectionInterval(i, lastIndex);
163 } else {
164 selectionModel.removeSelectionInterval(i, lastIndex);
165 }
166 } else if (lastIndex < i) {
167 restoreSelection(lastIndex, i - 1);
168 }
169 ok = true;
170 }
171
172
173 lastIndex = i;
174 if (ok) {
175 scrollRectToVisible(getUI().getCellBounds(CompareList.this, i, i));
176 }
177 }
178 }
179
180 public void mouseMoved(MouseEvent e) {
181 }
182
183 public void mouseReleased(MouseEvent e) {
184 startIndex = -1;
185 startIndices = null;
186 if (e.getButton() == MouseEvent.BUTTON3) {
187 JPopupMenu menu = getComponentPopupMenu();
188 if (menu != null) {
189 Point p = getPopupLocation(e);
190 if (p != null) {
191 menu.show(CompareList.this, p.x, p.y);
192 }
193 }
194 }
195 }
196
197
198
199
200
201 protected int[] getSelectedIndices() {
202 ListSelectionModel selectionModel = getSelectionModel();
203 int min = selectionModel.getMinSelectionIndex();
204 int max = selectionModel.getMaxSelectionIndex();
205
206 if ((min >= 0) && (max >= 0)) {
207
208 int size = 0;
209 int[] res = new int[(max - min) + 1];
210 for (int i = min; i <= max; i++) {
211 if (selectionModel.isSelectedIndex(i)) {
212 res[size] = i;
213 size = size + 1;
214 }
215 }
216 int[] r = new int[size];
217 System.arraycopy(res, 0, r, 0, size);
218 return r;
219 } else {
220 return null;
221 }
222 }
223
224
225
226
227
228
229 protected void restoreSelection(int from, int to) {
230 if (startIndices == null) {
231 removeSelectionInterval(from, to);
232 } else {
233
234
235 ListSelectionModel selectionModel = getSelectionModel();
236 selectionModel.setValueIsAdjusting(true);
237 selectionModel.removeSelectionInterval(from, to);
238
239 int i = 0;
240 while ((i < startIndices.length) && (startIndices[i] <= to)) {
241 int ind = startIndices[i];
242 if (ind >= from) {
243 selectionModel.addSelectionInterval(ind,ind);
244 }
245 i = i + 1;
246 }
247 selectionModel.setValueIsAdjusting(false);
248 }
249 }
250
251 }
252
253
254
255
256
257
258
259 public int selectedIndex(Point p) {
260 int i = getUI().locationToIndex(CompareList.this, p);
261 Rectangle r = getUI().getCellBounds(CompareList.this, i, i);
262 if (r != null) {
263 if (r.contains(p)) {
264 return i;
265 }
266 }
267 return -1;
268 }
269 }