Source code: org/mitre/cvw/SortedNameDescMultiList.java
1 /*
2 * Copyright (c) 1996-2000. The MITRE Corporation (http://www.mitre.org/).
3 * All rights reserved.
4 * CVW comes with ABSOLUTELY NO WARRANTY. See license for details.
5 */
6
7 package org.mitre.cvw;
8
9 import javax.swing.*;
10 import javax.swing.table.*;
11 import java.awt.*;
12 import java.awt.event.*;
13 import java.awt.dnd.*;
14 import java.awt.datatransfer.*;
15 import java.util.*;
16
17 /**
18 * This is a panel which implements a specific type of MultiList. It contains
19 * two columns, the first is the name of the object and the second is a
20 * detailed name. It is specifically used for listing users and groups
21 * within the Permissions, Access and Members tab of the Get Information
22 * dialogs, as well as in the Group Manager.
23 * @version
24 * @author Deb Ercolini
25 * @see MultiList
26 */
27 public class SortedNameDescMultiList extends JPanel implements DropTargetListener {
28 // class variable declarations
29 int currentSort = 0;
30 Vector rows;
31 String[] title;
32 MultiList listPanel;
33 boolean processing = false;
34 boolean needsUpdating = false;
35 boolean allowDrop = false;
36
37 long debugTime;
38
39 /**
40 * Constructor
41 * @param widths the widths of the columns
42 * @param names the titles of the columns
43 */
44 SortedNameDescMultiList(int[] widths, String names[]) {
45 this(widths, names, false);
46 }
47
48 /**
49 * Constructor
50 * @param widths the widths of the columns
51 * @param names the titles of the columns
52 * @param perm whether the list is editable
53 */
54 SortedNameDescMultiList(int[] widths, String names[], boolean perm) {
55 //System.err.println("sorted name desc list constructor" + names[0]);
56 setLayout(new BorderLayout());
57
58 setSize(400,290);
59
60 // make and initialize panel for content
61 listPanel = new MultiList(widths);
62
63 // local variable declarations
64 setTitle(names);
65
66 setEditability(perm);
67 listPanel.getTable().getTableHeader().addMouseListener(new MouseAdapter() {
68 public void mouseClicked(MouseEvent e) {
69 TableColumnModel columnModel = listPanel.getTable().getColumnModel();
70 int viewColumn = columnModel.getColumnIndexAtX(e.getX());
71 int column = listPanel.getTable().convertColumnIndexToModel(viewColumn);
72 if (column != -1) {
73 if (CVWCoordinator.DEBUG) System.out.println("Sorting column..." + column);
74 sortRowsBy(column);
75 }
76 }
77 });
78
79 add("Center", listPanel.getScrollTable());
80
81 }
82
83
84 /**
85 * Sets the title of the columns.
86 * @param names the titles of the columns
87 */
88 public void setTitle(String[] names) {
89 // local variable declarations
90 title = new String[names.length];
91 for (int i = 0; i<names.length;i++) {
92 title[i] = names[i];
93 }
94 listPanel.setSortableTitle(title);
95 }
96
97 /**
98 * Sets the editability of the panel.
99 * @param perm whether this panel is editable
100 */
101 public void setEditability(boolean perm) {
102 if (perm) {
103 listPanel.setPanelBackground(Color.white);
104 this.setOpaque(true);
105 this.setBackground(Color.white);
106 } else
107 listPanel.setPanelBackground(getBackground());
108 }
109
110 /**
111 * Clears the current multi list widget.
112 */
113 public void clearList() {
114 listPanel.clearRows();
115 rows = new Vector(0); //set to empty vector?
116 }
117
118 /**
119 * Updates the current multiList with a new set of CVWObjects.
120 * @param objs a vector of CVWObjects
121 */
122 public void updateList(Vector objs) {
123 int temp;
124 String[] strlist = new String[3];
125
126 //System.err.println("entered updated list " + objs.size() + processing);
127 if (processing)
128 return;
129 listPanel.clearRows();
130 if (objs.size() == 0) {
131 //listPanel.clearRows();
132 rows = objs;
133 return;
134 }
135
136 //rows = (Vector)objs.clone();
137 rows = objs;
138 debugTime = System.currentTimeMillis();
139 //System.err.println("created rows " + rows.size()+" 0" );
140 //printRows(rows);
141 temp = currentSort;
142 currentSort = -1;
143 sortRowsBy(temp);
144 listPanel.dataUpdated();
145 }
146
147 /**
148 * FOR DEBUG PURPOSES ONLY
149 * @param vector a vector to print
150 */
151 public void printRows(Vector vector) {
152 if (vector == null) {
153 //System.err.println("vector is null");
154 return; }
155 if (vector.size() < 0) {
156 //System.err.println("vector is empty");
157 return; }
158
159 CVWObject obj;
160 int i = 0;
161 for (Enumeration e = vector.elements() ; e.hasMoreElements() ;) {
162 obj = (CVWObject)e.nextElement();
163 //System.err.print(i + " " + obj.getName() + " " + obj.getDetailName());
164 i++;
165 }
166 //System.err.println(i);
167 }
168
169 /**
170 * FOR DEBUG PURPOSES ONLY
171 * @param keyword a debug string
172 */
173 public void printRows(String keyword) {
174 //System.err.println(keyword);
175 //printRows(rows);
176 }
177
178 /* 5/27/98 dage - used a shellsort routine by merging code
179 * from book "Using C", authors L & M Atkinson 1990 Que Corparation
180 * and from Carleton College Math and Computer Science Department
181 * found at url:
182 * http://www.mathcs.carleton.edu/courses/course_resources/cs227_w96/swanjorg/code.html
183 * 5/30/98 dage - because of dividing by 9, if the size of the vector is 9 or less,
184 * the sorting doesnt happen. So if the size of the vector is 9 or less, then
185 * dont divide by 9.
186 */
187 /**
188 * Sorts the rows of objects given a field.
189 * @param field the int value of the field to sort on
190 */
191 public synchronized void sortRowsBy(int field) {
192 //int i,j;
193 boolean sorted = false;
194 CVWObject next;
195 //Vector tempRows= new Vector(rows.size());
196
197 CVWObject obj;
198 //System.err.println(currentSort + " " + field + " " );
199 JFrame par = CVWCoordinator.findFrame(this);
200 //System.err.println("list widget setting wait cursor " + par);
201 if (par != null)
202 par.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
203 if (currentSort==field) {
204 //do nothing
205 } else {
206 int i, j, h;
207 CVWObject vObj, jhObj;
208 String vString, jhString;
209 boolean stillGreaterThan;
210 int size = rows.size();
211 /* 5/30/98 dage - debuggin purposes
212 System.err.println(size + " size - 1 by 9 " + ((size-1)/9));
213 for (h=1; h<=(size-1)/9; h = (3*h+1))
214 System.err.print("- " + h);
215 System.err.println();
216 System.err.println(size + " size - 1");
217 for (h=1; h<=(size-1); h = (3*h+1))
218 System.err.print("- " + h);
219 System.err.println();
220 */
221 // clear the table first
222 listPanel.clearRows();
223
224 int hSize;
225 if (size<10)
226 hSize = size-1;
227 else
228 hSize = (size-1)/9;
229 //System.err.println("hSize" + hSize);
230 for (h=1; h<=hSize; h = (3*h+1));
231 do {
232 h /=3;
233 for(i=h; i<size; i++) {
234 vObj = (CVWObject)rows.elementAt(i);
235 vString = getSortString(vObj, field);
236 j = i;
237 stillGreaterThan = true;
238 while (j >= h && stillGreaterThan) {
239 jhObj = (CVWObject)rows.elementAt(j-h);
240 jhString = getSortString(jhObj, field);
241 if (jhString.compareTo(vString) > 0) {
242 rows.setElementAt(jhObj, j);
243 j -= h;
244 }
245 else
246 stillGreaterThan = false;
247 }
248 rows.setElementAt(vObj, j);
249 }
250 } while (h > 0);
251 //System.err.println("done sorting by field==" + field);
252 //printRows(tempRows);
253 sorted = true;
254 }
255
256 //long time = System.currentTimeMillis()-debugTime;
257 //System.err.println("done sorting" + sorted+time);
258 //rows = tempRows;
259 //printRows(rows);
260
261 // reset the current sorted order
262 currentSort = field;
263 //System.err.println("list widget setting default cursor " + par);
264 if (par != null)
265 par.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
266 if (sorted) updateRows();
267 }
268
269 /**
270 * Returns the string value for the CVWObject given a field.
271 * @param obj the cvw object used
272 * @param field the field to be returned
273 * @return the value of the CVWObject specified with the field
274 */
275 public String getSortString(CVWObject obj, int field) {
276 if (field == 0)
277 return obj.getName().toLowerCase();
278 if (field == 1)
279 return obj.getDetailName().toLowerCase();
280 return obj.getName().toLowerCase();
281 }
282
283 /**
284 * Updates the row information in the MultiList widget.
285 */
286 public void updateRows() {
287 //if (sorted)
288
289 JFrame par = CVWCoordinator.findFrame(this);
290 if (par != null)
291 par.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
292 CVWObject obj;
293 int total = rows.size();
294 //System.err.println("list widget in update rows " + total);
295 // clean up any old list elements and put in new orderd list
296 // listPanel.clearRows();
297 int count = listPanel.countRows();
298 listPanel.setSortableTitle(title);
299 if (total==0) { //System.err.println("no rows but title");
300 String[] strlist= {"", ""};
301 listPanel.addRow(strlist);
302 if (par != null)
303 par.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
304 return;
305 }
306
307 if (count <= total) {
308 //System.err.println("list widget count <= total " + count);
309 for (int a = 0; a < total; a++) {
310 obj = (CVWObject)rows.elementAt(a);
311 String[] strlist= {obj.getName(), obj.getDetailName()};
312 if (a < count) {
313 listPanel.setRow(strlist,a);
314 } else {
315 listPanel.addRow(strlist);
316 }
317 }
318 } else {
319 //System.err.println("list widget count > total " + count);
320 for (int a = count-1; a >= 0; a--) {
321 if (a < total) {
322 obj = (CVWObject)rows.elementAt(a);
323 String[] strlist= {obj.getName(), obj.getDetailName()};
324 listPanel.setRow(strlist,a);
325 } else {
326 listPanel.removeRow(a);
327 }
328 }
329 }
330 long time = System.currentTimeMillis()-debugTime;
331 //System.err.println("list widget done update " + time);
332
333 if (par != null)
334 par.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
335 }
336
337 /**
338 * Returns the vector of CVWObjects.
339 * @return the vector of CVWObjects.
340 */
341 public Vector getObjects() {
342 return rows;
343 }
344
345 /**
346 * Returns the selected CVWObject.
347 * @return the selected CVWObject.
348 */
349 public CVWObject getSelectedObject() {
350 processing = true;
351 //System.err.println("in get selected object " + listPanel);
352 int i = listPanel.getSelectedRow();
353 if (i < 0 || i > rows.size()) {
354 processing = false;
355 return null;
356 }
357 //System.err.println("i " +i);
358 //System.err.println("vector " + rows.size());
359 //printRows(rows);
360 CVWObject obj;
361 obj = (CVWObject)rows.elementAt(i);
362 processing = false;
363 return obj;
364 }
365
366 /**
367 * Returns the index of the selected row.
368 * @return the index of the selected row
369 */
370 public int getSelectedRow() {
371 return listPanel.getSelectedRow();
372 }
373
374 /**
375 * Removes the specified row from the MultiList widget and the vector of objects.
376 * @param the row to be removed
377 */
378 public void removeRow(int i) {
379 rows.removeElementAt(i);
380 listPanel.removeRow(i);
381 }
382
383
384 /**
385 * Adds the CVWObject to the row of objects at the end and then resorts the entire
386 * vector.
387 * @param obj the CVWObject to be added.
388 */
389 public void addRow(CVWObject obj) {
390 if (rows.contains(obj)) {
391 //System.err.println("already in there");
392 return;
393 }
394 rows.addElement(obj);
395 int temp = currentSort;
396 currentSort = -1;
397 sortRowsBy(temp);
398 }
399
400 /**
401 * Selects a row given a index.
402 * @param i the row to be selected
403 */
404 public void select(int i) {
405 listPanel.select(i);
406 }
407
408 /* 8/25/98 dage -- added to support Drag & Drop
409 */
410 /**
411 * Selects the row during a drag operation.
412 * @param y the index of the row to be selected
413 */
414 public void selectDragRow(int y) {
415 //listPanel.selectDragRow(y);
416 }
417
418 /**
419 * Sets the MultiList widget to be draggable.
420 * @param b whether the MultiList widget should be draggable
421 */
422 public void setDraggable(boolean b) {
423 //listPanel.setDraggable(b);
424 }
425
426 /**
427 * Sets the MultiList widget to be draggable.
428 * @param b whether the MultiList widget should be draggable
429 */
430 public void setDroppable(boolean b) {
431 allowDrop = b;
432 if (allowDrop) {
433 // override the drop targets
434 setDropTargetListener((DropTargetListener)this);
435 }
436 }
437
438 // DropTargetListener methods
439 public void dragEnter(DropTargetDragEvent dtde) {
440 if (allowDrop &&
441 dtde.isDataFlavorSupported(DetailObjectTransferable.OBJECT_FLAVOR))
442 dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
443 else
444 dtde.rejectDrag();
445 }
446
447 public void dropActionChanged(DropTargetDragEvent dtde) {}
448 public void dragExit(DropTargetEvent dte) {}
449
450 public void dragOver(DropTargetDragEvent dtde) {
451 if (!allowDrop) { dtde.rejectDrag(); return; }
452 int row = listPanel.getRowIndex(dtde.getLocation().y);
453 CVWObject cvwObj = (CVWObject)rows.elementAt(row);
454 if (cvwObj != null)
455 listPanel.select(row);
456 else
457 listPanel.select(-1);
458 }
459
460 public void drop(DropTargetDropEvent dtde) {
461 if (!allowDrop) { dtde.rejectDrop(); return; }
462 try {
463 if (dtde.isLocalTransfer()) {
464 Transferable tr = dtde.getTransferable();
465 DataFlavor objFlavor = DetailObjectTransferable.OBJECT_FLAVOR;
466 if (tr.isDataFlavorSupported(objFlavor)) {
467 dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
468 CVWObject dropObject = (CVWObject)tr.getTransferData(objFlavor);
469
470 int row = listPanel.getRowIndex(dtde.getLocation().y);
471 if (row > -1) {
472 CVWObject target = (CVWObject)rows.elementAt(row);
473 if (target != null)
474 dropObject.moveObject(target);
475 dtde.getDropTargetContext().dropComplete(true);
476 return;
477 }
478 dtde.rejectDrop();
479 }
480 }
481 else { // not local drop
482 int action = dtde.getSourceActions();
483 System.err.println("hey, you dropped something! action = " + action);
484 dtde.rejectDrop();
485 }
486 }
487 catch (Exception e) {
488 System.err.println("Error during drop: " + e);
489 dtde.rejectDrop();
490 }
491 }
492
493 public void setDropTargetListener(DropTargetListener listener) {
494 listPanel.setDropTarget(listener);
495 }
496
497 }
498