Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mitre/cvw/DetailList.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.event.*;
11  import javax.swing.table.*;
12  import java.awt.*;
13  import java.awt.event.*;
14  import java.util.*;
15  
16  import java.awt.dnd.*;
17  import java.awt.datatransfer.*;
18  
19  /**
20   * This is the gui widget which displays the contents of the room and all
21   * folders.
22   * @version  1.2
23   * @author Dee Goepel
24   * @author Stephen Jones
25   */
26  public class DetailList extends JPanel implements ObjectValues, Observer, DropTargetListener {
27    // class variable declarations
28    private final int[] initialSize = {80,10,7,9,7,9}; //1/19/98 dage
29    //private final int[] initialSize = {15,10,7,9,7,9}; //1/19/98 dage
30    private final String[] titles = {"Name", "Type", "Created", "Originator", "Modified", "Modified By"};
31  
32    public final static int NO_MENU = -1;
33  
34    //  DetailObject[] contents, new_contents;
35    MultiListData contents;
36    int total, curMenu = NO_MENU, menuHeight = 4, currentSort = 0;
37    MultiList listPanel;
38    int[] types = {USER, DOC, URL, NOTE, PROXY, FOLDER, RECORDER, WHITEBOARD, UNKNOWN};
39    ObjectMenu menu;
40    String dropOrTake = "take";  // can be "drop" or "take"
41    JPanel headingPanel;
42    JLabel headingLabel, sizeLabel;
43    JLabel docServIcon = null;
44    Point menuPt;
45  
46  /**
47   * Constructor
48   * @param cvwObj
49   * @param dOT
50   * @param title2
51   */
52    DetailList(CVWObject[] cvwObj, String dOT, String title2) {
53      setLayout(new BorderLayout());
54      setSize(1000, 1000);
55      
56      dropOrTake = dOT;
57  
58      // make and fill panels for content
59      //System.err.println("heading is "+title2);
60      headingPanel = new JPanel();
61      headingPanel.setLayout(new BorderLayout());
62  
63      if (title2.equals("null"))
64        headingLabel = new JLabel("                                              ");
65      else
66        headingLabel = new JLabel(" "+title2);
67  
68      //Font f = getFont();
69      //if (f != null)
70        //headingLabel.setFont(new Font(f.getName(), Font.BOLD, f.getSize()));
71      //else
72      headingLabel.setFont(headingLabel.getFont().deriveFont(Font.BOLD));
73      headingPanel.add("Center",headingLabel);
74  
75      Image image = ContentsCoordinator.getDocServIcon();
76      docServIcon = new JLabel(new ImageIcon(image), JLabel.RIGHT);
77      docServIcon.setSize(9,14);
78      JPanel rightPanel = new JPanel(new GridLayout(0, 2, 5, 0));
79      sizeLabel = new JLabel();
80      setSizeLabel(cvwObj.length);
81      rightPanel.add(docServIcon);
82      rightPanel.add(sizeLabel);
83      headingPanel.add("East",rightPanel);
84  
85      contents = new MultiListData(cvwObj.length);
86      listPanel = new MultiList(contents, (dropOrTake.equals("drop")));
87      listPanel.setWidths(initialSize);
88      listPanel.setPanelBackground(getBackground());
89      listPanel.getTable().addMouseListener(new MouseAdapter() {
90        public void mousePressed(MouseEvent e) {
91    if (SwingUtilities.isRightMouseButton(e)) {
92      Point pt = e.getPoint();
93      int rowClicked = listPanel.getTable().rowAtPoint(pt);
94      listPanel.select(rowClicked);
95      showMenu(pt.x, pt.y, rowClicked);
96    } else if (SwingUtilities.isLeftMouseButton(e) && 
97             e.getClickCount() == 2) { // double click. Do a Get Info..
98      Point pt = e.getPoint();
99      int row = listPanel.getTable().rowAtPoint(pt);
100     openSelectedObject(row);
101   }
102       }
103     });
104 
105     listPanel.getTable().getTableHeader().addMouseListener(new MouseAdapter() {
106       public void mouseClicked(MouseEvent e) {
107   TableColumnModel columnModel = listPanel.getTable().getColumnModel();
108   int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 
109   int column = listPanel.getTable().convertColumnIndexToModel(viewColumn); 
110   if (column != -1) {
111     //System.out.println("Sorting column..." + column);
112     sortContentsBy(column);
113   }
114       }
115     });
116 
117     initDetailList(cvwObj);
118     
119     // place components
120     add("North", headingPanel);
121     add("Center", listPanel.getScrollTable());
122     doLayout();
123     headingPanel.doLayout();
124     showDocServIcon(false);
125   }
126 
127 /**
128  * Scrolls the detail list to the top.
129  */
130   public void goToTop() {
131     if (listPanel != null)
132       listPanel.makeVisible(0);
133   }
134 
135   /** Initializes the list with the objects passed into the constructor
136    *
137    * @param cvwObj An array of CVWObjects
138    */
139   protected void initDetailList(CVWObject[] cvwObj) {
140     total = cvwObj.length;
141     listPanel.setSortableTitle(titles);
142 
143     setSizeLabel(total);
144     if (total == 0) return;
145 
146     for (int i = 0; i < total; i++)
147       contents.addObject(new DetailObject(cvwObj[i], this));
148 
149     doSort(contents,currentSort);
150 
151   }
152 
153   public void setSizeLabel(int size) {
154      if (size == 1)
155   sizeLabel.setText(size + " item   ");
156      else
157   sizeLabel.setText(size + " items  ");
158    }
159 
160 /**
161  * Updates the detail list with a new array of CVWObjects.
162  * Removes any previous contents the array might have.
163  *
164  * @param cvwObj a new array of CVWObjects
165  */
166   public void updateDetailList(CVWObject[] cvwObj) {
167     int temp;
168     //System.err.println("udl:oldTotal " + total + "newTotal " + cvwObj.length);
169     // remove old observers
170     for (int i = 0; i < contents.length(); i++)
171       contents.getObject(i).deleteObserver();
172 
173     // class variable assignments
174     int newtotal = cvwObj.length;
175     clearContents();
176 
177     setSizeLabel(newtotal);
178 
179     if (newtotal == 0) {
180       return;
181     }
182 
183     for (int a = 0; a < newtotal; a++) {
184       contents.addObject(new DetailObject(cvwObj[a],this));
185     }
186     
187     //System.err.println("done creating");
188     temp = currentSort;
189     currentSort = NO_MENU;
190     
191     total = newtotal;
192     try {
193       sortContentsBy(temp);
194     } catch (Exception e) {
195       currentSort = temp;
196     }
197     
198   }  
199     
200 /* 8/26/98 dage - broke this method into much smaller methods 
201      sortBy, doSort, updateLists, resetHilights
202  */
203 /**
204  * Sorts the current array of CVWObjects by the specified field, remembering which
205  * object is highlighted before the new sort, so as to high light the same object 
206  * after the sort.
207  * @param field the field to sort by
208  */
209   public void sortContentsBy(int field) {
210     int start = listPanel.getVisible();
211     int hilight = listPanel.getSelectedRow();
212     CVWObject select = getSelectedObject();
213 
214     if (sortBy(field)) {
215         currentSort = field;
216   resetHilights(hilight, start, select);
217     }
218     //System.err.println("done sorting");
219   }
220   
221 /**
222  * Sorts the array of CVWObjects by the field specified, but first sorts alphabetically
223  * by name, so that always by name.
224  * @param field the field to sort by
225  * @return whether the sort actually happened (if user clicked on field already
226  * sorted by, just abort
227  */
228   public boolean sortBy(int field) {
229     boolean sorted = true;
230     CVWObjNum selectobj=null;
231     DetailObject next;
232 
233     //contents = new_contents;
234     // at this point the objects on screen are different than those actually
235     // stored, the displayed objects are updated immediately following the sort
236       
237     // Do the actual sorting of our contents array
238     //    if (currentSort==field) {
239     // sorted = false;
240       // } else {
241       
242       // sort alphabetically always
243       // then sort again if name is not our primary sort field
244       /* 5/27/98 dage - name field is 0
245        */
246       //doSort(contents, 0);
247       
248       //System.err.println("done 1st sort");
249       /* 5/27/98 dage - replace each repetive field type with a single loop and sent
250        *   the field value as a parameter to compareTo function
251        */
252       //if (field != 0) 
253       doSort(contents, field);
254       
255     //System.err.println("done 2nd sort");
256       return sorted;
257   }  
258   
259 /**
260  * Performs the sort, given an array of DetailObjects and a field.
261  * @param detailArray the object to be sorted
262  * @param field the field to do the sort on
263  */
264   public void doSort(MultiListData detailArray, int field) {
265     int i, j, h;
266     DetailObject vObj, jhObj;
267     String vString, jhString;
268     boolean stillGreaterThan;
269     int size = detailArray.length();
270 
271     int hSize;
272     if (size<10)
273       hSize = size-1;
274     else
275       hSize = (size-1)/9;
276     //System.err.println("hSize" + hSize);
277     for (h=1; h<=hSize; h = (3*h+1));
278     do {
279       h /=3;
280       for(i=h; i<size; i++) {
281   vObj = detailArray.getObject(i);
282   j = i;
283   stillGreaterThan = true;
284   while (j >= h && stillGreaterThan) {
285     jhObj = detailArray.getObject(j-h);
286     if (jhObj.compareTo(vObj, field) > 0) {
287       detailArray.setObjectAt(jhObj, j);   //rows.setElementAt(jhObj, j);
288       j -= h;
289     }
290     else
291       stillGreaterThan = false;
292   }  //end while
293   detailArray.setObjectAt(vObj, j);   // rows.setElementAt(vObj, j);
294       }  //end for
295     } while (h > 0);
296     detailArray.dataUpdated();
297     //System.err.println("done sort");
298   }
299    
300 /**
301  * Resets the scroll position 
302  * if something was selected, reselect it
303  * if it's no longer there don't select anything
304  * if nothing was selected, return us to the same row number
305  * @param hilight
306  * @param start
307  * @param selectobj
308  */
309    public void resetHilights(int hilight, int start, CVWObject selectobj) {
310       if (hilight < 0) {
311   // nothing was highlighted
312   if (start < total) 
313     listPanel.makeVisible(start);
314       } else { 
315   // try to reselect
316   int a;
317   for (a=0;a<total;a++) {
318     if (selectobj.equals(contents.getObject(a).getCVWObject())) {
319       listPanel.select(a);
320       listPanel.makeVisible(a);
321       break;
322     }
323   }
324   if (a == total) {
325     // the selected object is no longer there
326     listPanel.select(-1); // deselect 
327     if (hilight < total) {
328       listPanel.makeVisible(hilight);
329     } else {
330       listPanel.makeVisible(total);
331      }
332   }
333       }
334 
335   }
336   
337 /**
338  * Refreshes the layouts of the different gui panels.
339  */
340   public void doLayouts() {
341     doLayout();
342     headingPanel.doLayout();
343   }
344   
345 /**
346  * Notifies this detail list of when the right mouse selection finished
347  * painting so that the right mouse menu can be shown. No longer used.
348  * @param ob an instance of MultiListWatcher
349  * @param arg &quot;done painting&quot;
350  */
351   public void update(Observable ob, Object arg) {
352   }
353 
354 /**
355  * Makes the appropriate right mouse menu visible.
356  * @param x the x coordinate
357  * @param y the y coordinate
358  * @param row the row selected
359  */
360   public void showMenu(int x, int y, int row)  {
361     int displayX = x+5, displayY=y-12;
362     int mtype = contents.getObject(row).menuType; // rows start at 1, objects start at 0!
363     
364     if ((row >= 0) && (row < total)) {
365       if ((mtype == 89) || (mtype == PROXY)) // 89 is a randomly chosen number to
366   return;                         // denote lack of menu
367 
368       int drop_or_take = (dropOrTake.equals("drop")) ? DROP : TAKE;
369 
370       if (menu != null) { // remove previous menu
371   try {
372     //remove(menu);
373   }
374   catch (NullPointerException npe) {
375     System.err.println("menu no longer exists");
376   }
377       }
378 
379       CVWObject obj = contents.getObject(row).getCVWObject();
380       if (mtype == GROUP) {
381   menu = ObjectMenuControl.getMenu(mtype, obj, drop_or_take);
382       } else if (mtype == RECORDER) {
383 /* 9/23/98 dage - dot is really whether the recorder is currently on or off
384  */
385   int state = (obj.name.indexOf("OFF")< 0) ? 1 : 0;
386   menu = ObjectMenuControl.getMenu(mtype, obj, state);
387       } else {  
388   menu = ObjectMenuControl.getMenu(mtype, obj, drop_or_take);
389       }
390       //add(menu);
391       
392       // see what needs to be grayed out, if anything
393       int menu_mask = 0;
394       if (drop_or_take == DROP && 
395      ((menu instanceof DocMenu) || (menu instanceof DocWBMenu)) &&
396      !(menu instanceof DocSCMenu)) {
397   // this is a doc in carrying folder
398   CVWDocument doc = (CVWDocument)obj; // should be a document
399   if (doc.isCheckedOut()) {
400     menu_mask = menu.getGrayoutMask(CHECKEDOUTDOC);
401   } else {
402     menu_mask = menu.getGrayoutMask(NOTCHECKEDOUTDOC);
403   }
404       }
405       if (menu != null) 
406   menu.show(listPanel.getTable(), menu_mask, displayX, displayY);
407       
408     }
409   }
410 
411 /**
412  * Updates the contents of the list.
413  */
414   public void updateContents() {
415     contents.dataUpdated();
416   }
417 
418 /**
419  * Clears the contents ofthe room.
420  */
421   public void clearContents() {
422     contents.clear();
423   }
424 
425 /**
426  * Updates the label of this detail list, can be a room name or folder name change.
427  * @param roomName the new name
428  */
429   public void updateHeading(String roomName) { //called when a room change occurs
430     headingLabel.setText(roomName);
431     headingPanel.doLayout();
432     doLayout();
433     goToTop(); // scroll to the top on change of room
434   }    
435 
436 /**
437  * Shows/Hides the doc server communication icon.
438  * @param b whether to show or hide the icon
439  */
440   public void showDocServIcon(boolean b) {
441     if (docServIcon == null) 
442   return;
443     docServIcon.setVisible(b);
444     docServIcon.repaint();
445     doLayout();
446     headingPanel.doLayout();
447    }
448 
449   public boolean openSelectedObject(int row) {
450     DetailObject dob = contents.getObject(row);
451     if (row >= contents.length()) return false;
452     if (dob.menuType == 89) return false; // 89 == no menu
453 
454     if (dob.menuType == 88 || dob.menuType == FORMFOLDER) {
455      CVWCoordinator.getInstance().displayError(CVWCoordinator.findFrame(this),
456       "\"" + dob.getName() 
457       + "\", which is of type "       
458       + dob.getType() 
459       + ", can not be opened in this version of CVW.");
460      return false;
461     }
462     if (dob.menuType == PROXY)
463       return false;
464     dob.getCVWObject().startOpen();
465     return true;
466   }
467  
468 
469 /**
470  * Returns the CVWObject represented by the selected row.
471  * @return  the CVWObject selected
472  */
473   public CVWObject getSelectedObject() {
474     int row = listPanel.getSelectedRow();
475     if (row == -1) 
476       return null;
477     if (row >= contents.length())
478       return null;
479     return contents.getObject(row).getCVWObject();
480    }
481 
482 /**
483  * Returns the CVWObject represented by the selected row and y coordinate, returns
484  * <code>null</code> if y and selected row DO NOT match.
485  * @param y the y coordinate
486  * @return  the CVWObject selected
487  */
488   public CVWObject getSelectedObject(int y) {
489     int row = listPanel.getSelectedRow();
490     int row2 = listPanel.getRowIndex(y);
491     row2--;
492     if (row != row2) 
493       return null;
494     if (row == -1) 
495       return null;
496     if (row >= contents.length())
497       return null;
498     //System.err.println(contents.length);
499     return contents.getObject(row).getCVWObject();
500    }
501 
502   // DropTargetListener methods
503   public void dragEnter(DropTargetDragEvent dtde) {
504      if (dtde.isDataFlavorSupported(DetailObjectTransferable.OBJECT_FLAVOR)) {
505         dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
506      } else
507         dtde.rejectDrag();
508   }
509 
510   public void dropActionChanged(DropTargetDragEvent dtde) {}
511   public void dragExit(DropTargetEvent dte) {}
512   
513   public void dragOver(DropTargetDragEvent dtde) {
514     if (!(dtde.getDropTargetContext().getComponent() instanceof JTable)) {
515   listPanel.select(-1); 
516   return;  
517       }
518     int row = listPanel.getRowIndex(dtde.getLocation().y);
519     if (row < 0 || row >= contents.length()) {
520   listPanel.select(-1); 
521   return;  
522       }
523     CVWObject cvwObj = contents.getObject(row).getCVWObject();
524     if (cvwObj != null && cvwObj instanceof CVWFolder)
525       listPanel.select(row);
526     else
527   listPanel.select(-1);
528    }
529   
530   public void drop(DropTargetDropEvent dtde) {
531     try {
532       if (dtde.isLocalTransfer()) {
533   Transferable tr = dtde.getTransferable();
534   DataFlavor objFlavor = DetailObjectTransferable.OBJECT_FLAVOR;
535   if (tr.isDataFlavorSupported(objFlavor)) {
536     dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
537     CVWObject dropObject = (CVWObject)tr.getTransferData(objFlavor);
538 
539 //get target object, current selection if folder, 
540 //current folder window, current user or current room.
541   CVWObject target = null;
542 
543         if (dtde.getDropTargetContext().getComponent() instanceof JTable) {
544           int row = listPanel.getRowIndex(dtde.getLocation().y);
545     if (row > -1) {
546             CVWObject cvwObj = contents.getObject(row).getCVWObject();
547       if (cvwObj != null && cvwObj instanceof CVWFolder)
548         target = cvwObj;
549         }
550       }
551   if (target == null)
552     target = getDropLocation();
553   dropObject.moveObject(target);
554   dtde.getDropTargetContext().dropComplete(true);
555   }
556       }
557       
558       else {
559   int action = dtde.getSourceActions();
560   System.err.println("hey, you dropped something! action = " + action);
561   dtde.rejectDrop();
562       }
563     } 
564     catch (Exception e) {
565       System.err.println("Error during drop: " + e);
566       dtde.rejectDrop();
567     }
568   }
569 
570 /**
571  * Sets the drop target listener for this detail list to itself.
572  */
573    public void setDropTargetListener() {
574      listPanel.setDropTarget((DropTargetListener)this);
575      new DropTarget(headingLabel, this);
576     }
577 
578 /**
579  * Returns the container for this detail list.  If the frame is CVWCoordinator
580  * then current room is assumed.  If frame is a CVWFolderWindow, then the
581  * CVWFolder the window represents, which could be the current user.  
582  */
583    public CVWObject getDropLocation() {
584      JFrame frame = CVWCoordinator.findFrame(this);
585      if (frame instanceof CVWCoordinator)
586   return CVWCoordinator.getInstance().getCurrentRoom();
587   
588      if (frame instanceof CVWFolderWindow) {
589   return ((CVWFolderWindow)frame).getCVWFolder();
590       }
591 
592      return null; //should never get here
593    }
594 
595 }
596 
597