KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > swingwtx > swing > JList


1 /*
2    SwingWT
3    Copyright(c)2003-2004, R. Rawson-Tetley
4
5    For more information on distributing and using this program, please
6    see the accompanying "COPYING" file.
7
8    Contact me by electronic mail: bobintetley@users.sourceforge.net
9
10    $Log: JList.java,v $
11    Revision 1.37 2004/04/30 23:18:26 dannaab
12    List selection support, misc bug fixes
13
14    Revision 1.36 2004/04/28 08:38:11 bobintetley
15    Hierarchy fixes, code cleanup for base classes, additional javadocs and use of flag to identify JComponent descendants with peers
16
17    Revision 1.35 2004/04/19 12:49:37 bobintetley
18    JTaskTray implementation (and demo), along with Frame repaint fix
19
20    Revision 1.34 2004/04/19 09:26:51 bobintetley
21    JList fix to prevent resizing when the data is added
22
23    Revision 1.33 2004/04/16 10:19:06 dannaab
24    Misc bug fixes, InputMap implementation, preliminary undo support
25
26    Revision 1.32 2004/04/07 06:20:23 bobintetley
27    Selection model MULTI/SINGLE translates correctly to SWT selection now
28
29    Revision 1.31 2004/04/06 12:30:53 bobintetley
30    JTable thread safety, ListSelectionModel implementation for JList/JTable
31
32    Revision 1.30 2004/03/30 10:42:46 bobintetley
33    Many minor bug fixes, event improvements by Dan Naab. Full swing.Icon support
34
35    Revision 1.29 2004/03/21 17:22:54 bobintetley
36    Compatibility methods for awt Graphics, List and Label. Dummy Applet implementation
37
38    Revision 1.28 2004/03/03 09:13:12 bobintetley
39    JList threading fixed and top level error handling
40
41    Revision 1.27 2004/02/23 12:11:24 bobintetley
42    JScrollPane bug fixed, tabbing in JTextArea fixed
43
44    Revision 1.26 2004/02/12 10:03:56 bobintetley
45    JList improvements for locationToIndex() and selection colours
46
47    Revision 1.25 2004/02/03 11:20:27 bobintetley
48    JList does not assign listener until data is generated now in default model
49    (prevents flickering)
50
51    Revision 1.24 2004/01/27 09:05:10 bobintetley
52    ListModel and List Selection implemented. ScrollPane fix so all components
53       scrollable
54
55    Revision 1.23 2004/01/26 08:11:00 bobintetley
56    Many bugfixes and addition of SwingSet
57
58    Revision 1.22 2004/01/08 15:36:59 bobintetley
59    Multiselection works correctly in tables and JList now
60
61    Revision 1.21 2004/01/06 15:31:02 bobintetley
62    New render width function for accurate auto-sizing
63
64    Revision 1.20 2004/01/05 12:31:14 bobintetley
65    Table/List/Toolbar fixes for correct layout
66
67    Revision 1.19 2004/01/04 12:02:41 bobintetley
68    Fix to broken popupMenu events, default values and null data handling
69
70    Revision 1.18 2003/12/28 19:29:44 bobintetley
71    Fix so JList refreshes correctly when new data is applied
72
73    Revision 1.17 2003/12/28 19:20:30 bobintetley
74    JList is now based around Table to allow custom cell renderers
75
76    Revision 1.16 2003/12/22 12:27:50 bobintetley
77    JList breaks with null data
78
79    Revision 1.15 2003/12/17 13:38:02 bobintetley
80    setSelectedValue(Obj, bool) support and JOptionPane.showInputDialog now uses JList
81
82    Revision 1.14 2003/12/16 17:46:17 bobintetley
83    Additional thread safety methods
84
85    Revision 1.13 2003/12/16 13:14:33 bobintetley
86    Use of SwingWTUtils.isSWTControlAvailable instead of null test
87
88    Revision 1.12 2003/12/15 18:29:57 bobintetley
89    Changed setParent() method to setSwingWTParent() to avoid conflicts with applications
90
91    Revision 1.11 2003/12/15 17:41:16 bobintetley
92    Missing return value fixed
93
94    Revision 1.10 2003/12/15 16:40:04 bobintetley
95    Core methods + skeleton JTableHeader/JScrollBar support
96
97    Revision 1.9 2003/12/14 09:13:38 bobintetley
98    Added CVS log to source headers
99
100 */

101
102
103 package swingwtx.swing;
104
105 import swingwtx.swing.event.*;
106 import swingwt.awt.Dimension;
107
108 import org.eclipse.swt.widgets.*;
109 import org.eclipse.swt.*;
110
111 import java.util.*;
112
113 public class JList extends swingwtx.swing.JComponent implements JSWTScrollable, ListDataListener {
114
115     protected org.eclipse.swt.widgets.Table ppeer = null;
116     protected String JavaDoc pText = "";
117     protected int pSelectedIndex = -1;
118     protected ListCellRenderer cellRenderer = new DefaultListCellRenderer();
119     protected ListModel listModel = null;
120     protected ListSelectionModel listSelectionModel = new DefaultListSelectionModel(this);
121     
122     /** Thread safe property accessors */
123     private Object JavaDoc[] retVals = null;
124     private int iRetVal = 0;
125     private int[] iRetVals = null;
126     
127     
128     public JList() { listModel = new DefaultListModel(); listModel.addListDataListener(this); }
129     
130     /** Creates a list with the specified items.
131      * WARNING:: SWT cannot store objects against the list
132      * like Swing can, so only the toString() method of your
133      * objects will be stored.
134      */

135     public JList(Object JavaDoc[] items) {
136         loadData(items);
137     }
138     
139     /** Creates a list with the specified items.
140      * WARNING:: SWT cannot store objects against the list
141      * like Swing can, so only the toString() method of your
142      * objects will be stored.
143      */

144     public JList(Vector items) {
145         loadData(items);
146     }
147     
148     public JList(ListModel model) {
149         listModel = model;
150         listModel.addListDataListener(this);
151     }
152     
153     public void addListSelectionListener(ListSelectionListener l) {
154         listSelectionModel.addListSelectionListener(l);
155     }
156     
157     public void removeListSelectionListener(ListSelectionListener l) {
158         listSelectionModel.removeListSelectionListener(l);
159     }
160     
161     public void clearSelection() {
162        ppeer.deselectAll();
163     }
164     
165     public Object JavaDoc getSelectedValue() {
166         if (!SwingWTUtils.isSWTControlAvailable(ppeer))
167             // Since we know that the selected item in the list will be the first item in the data model,
168
// we can return that if we have a non-empty model.
169
if (getModel().getSize() > 0)
170                 return getModel().getElementAt(0);
171             else
172                 return null;
173         else
174             return listModel.getElementAt(ppeer.getSelectionIndex());
175     }
176     
177     public void setSelectedValue(final int index) {
178         SwingUtilities.invokeSync(new Runnable JavaDoc() {
179             public void run() {
180                 if (!SwingWTUtils.isSWTControlAvailable(ppeer))
181                     pSelectedIndex = index;
182                 else
183                     ppeer.select(index);
184             }
185         });
186     }
187     
188     public void setSelectedValue(final Object JavaDoc value, boolean shouldscroll) {
189         if (!checkIsDefault()) return;
190         SwingUtilities.invokeSync(new Runnable JavaDoc() {
191             public void run() {
192                 if (!SwingWTUtils.isSWTControlAvailable(ppeer))
193                     pSelectedIndex = ((DefaultListModel) listModel).indexOf(value);
194                 else
195                     ppeer.select(((DefaultListModel) listModel).indexOf(value));
196             }
197         });
198     }
199     
200     public ListSelectionModel getSelectionModel() { return listSelectionModel; }
201     public void setSelectionModel(ListSelectionModel l) { listSelectionModel = l; }
202     
203     public void setSelectionMode(int mode) {
204         listSelectionModel.setSelectionMode(mode);
205     }
206     
207     public Object JavaDoc[] getSelectedValues() {
208         if (!SwingWTUtils.isSWTControlAvailable(ppeer)) return null;
209         retVals = null;
210         SwingUtilities.invokeSync(new Runnable JavaDoc() {
211             public void run() {
212                 retVals = new Object JavaDoc[ppeer.getSelectionCount()];
213                 for (int i = 0; i < ppeer.getSelectionIndices().length; i++) {
214                     retVals[i] = listModel.getElementAt(ppeer.getSelectionIndices()[i]);
215                 }
216             }
217         });
218         return retVals;
219     }
220     
221     public void addItem(final Object JavaDoc item) {
222         if (!checkIsDefault()) return;
223         ((DefaultListModel) listModel).addElement(item);
224         SwingUtilities.invokeSync(new Runnable JavaDoc() {
225             public void run() {
226                 if (SwingWTUtils.isSWTControlAvailable(ppeer))
227                     updateList();
228             }
229         });
230     }
231     
232     public void insertItemAt(final Object JavaDoc item, final int index) {
233         if (!checkIsDefault()) return;
234         ((DefaultListModel) listModel).add(index, item);
235         SwingUtilities.invokeSync(new Runnable JavaDoc() {
236             public void run() {
237                 if (SwingWTUtils.isSWTControlAvailable(ppeer))
238                     updateList();
239             }
240         });
241     }
242     
243     public int getSelectedIndex() {
244         iRetVal = 0;
245         SwingUtilities.invokeSync(new Runnable JavaDoc() {
246             public void run() {
247                 if (!SwingWTUtils.isSWTControlAvailable(ppeer))
248                     iRetVal = -1;
249                 else
250                     iRetVal = ppeer.getSelectionIndex();
251             }
252         });
253         return iRetVal;
254     }
255     
256     public int[] getSelectedIndices() {
257         iRetVals = null;
258         SwingUtilities.invokeSync(new Runnable JavaDoc() {
259             public void run() {
260                 if (SwingWTUtils.isSWTControlAvailable(ppeer))
261                     iRetVals = ppeer.getSelectionIndices();
262                 else
263                     iRetVals = new int[0];
264             }
265         });
266         return iRetVals;
267     }
268     
269     public Object JavaDoc getItemAt(int index) {
270         return listModel.getElementAt(index);
271     }
272     
273     public int getItemCount() {
274         return listModel.getSize();
275     }
276     
277     /** Scrolls the list to the selected item. This is not a Swing method */
278     public void showSelection() {
279         SwingUtilities.invokeSync(new Runnable JavaDoc() {
280             public void run() {
281                 if (SwingWTUtils.isSWTControlAvailable(ppeer))
282                     ppeer.showSelection();
283             }
284         });
285     }
286     
287     public void setSelectedIndex(final int index) {
288         if (!SwingWTUtils.isSWTControlAvailable(ppeer))
289             pSelectedIndex = index;
290         else
291             SwingUtilities.invokeSync(new Runnable JavaDoc() {
292                 public void run() {
293                     ppeer.select(index);
294                 }
295             });
296     }
297     
298     public void setSelectedIndices(final int[] selection) {
299         if (!SwingWTUtils.isSWTControlAvailable(ppeer)) return;
300         SwingUtilities.invokeSync(new Runnable JavaDoc() {
301             public void run() {
302                 ppeer.select(selection);
303             }
304         });
305     }
306     
307     public void removeAllItems() {
308         setModel(new DefaultListModel());
309         if (SwingWTUtils.isSWTControlAvailable(ppeer))
310             SwingUtilities.invokeSync(new Runnable JavaDoc() {
311                 public void run() {
312                     ppeer.removeAll();
313                     updateList();
314                 }
315             });
316     }
317     
318     public void removeItem(final Object JavaDoc item) {
319         if (!checkIsDefault()) return;
320         final int index = ((DefaultListModel) listModel).indexOf(item);
321         ((DefaultListModel) listModel).removeElement(item);
322         if (SwingWTUtils.isSWTControlAvailable(ppeer))
323             SwingUtilities.invokeSync(new Runnable JavaDoc() {
324                 public void run() {
325                     ppeer.remove(index);
326                     updateList();
327                 }
328             });
329     }
330     
331     public void removeItemAt(final int index) {
332         if (!checkIsDefault()) return;
333         ((DefaultListModel) listModel).remove(index);
334         if (SwingWTUtils.isSWTControlAvailable(ppeer))
335             SwingUtilities.invokeSync(new Runnable JavaDoc() {
336                 public void run() {
337                     ppeer.remove(index);
338                 }
339             });
340     }
341     
342     /** Not a real Swing method - used to switch an already created
343      * item in the DefaultListModel. This is handy for the replace
344      * functionality of the AWT list.
345      */

346     public void replaceItemAt(final Object JavaDoc replacement, final int index) {
347         if (!checkIsDefault()) return;
348         ((DefaultListModel) listModel).set(index, replacement);
349         updateList();
350     }
351     
352     /** Used to calculate preferred height */
353     public void setVisibleRowCount(int rows) {
354         Dimension d = getPreferredSize();
355         d.height = rows * SwingWTUtils.getRenderStringHeight("W");
356         if (d.width == 0)
357             d.width = SwingWTUtils.getRenderStringWidth("WWWWWWWWWWWWWWWWWWW");
358         setPreferredSize(d);
359     }
360     
361     public int locationToIndex(final swingwt.awt.Point point) {
362         // Do a close guess based on font height - this should be pretty
363
// much accurate.
364
return ( point.y / SwingWTUtils.getRenderStringHeight("W") );
365      }
366
367     /** No way in SWT to set selection colour models */
368     public void setSelectionBackground(swingwt.awt.Color color) { }
369     /** No way in SWT to set selection colour models */
370     public void setSelectionForeground(swingwt.awt.Color color) { }
371     
372     /** Fills the table with the list items */
373     protected void updateList() {
374         final JList list = this;
375         SwingUtilities.invokeSync(new Runnable JavaDoc() {
376             public void run() {
377                 
378                 // Don't do anything if we can't see the list anyway
379
if (!SwingWTUtils.isSWTControlAvailable(ppeer)) return;
380
381                 // Clear out all rows from the peer
382
ppeer.removeAll();
383                 
384                 // Get a reference to the column
385
org.eclipse.swt.widgets.TableColumn tc = ppeer.getColumn(0);
386                 
387                 // Generate list data
388
if (listModel != null) {
389                     int widestListItem = 0;
390                     for (int i = 0; i < listModel.getSize(); i++) {
391                         TableItem ti = new TableItem(ppeer, 0);
392                         // Get the cell renderer for this item
393
JLabel renderer =
394                             (JLabel) cellRenderer.getListCellRendererComponent(list, listModel.getElementAt(i), i, false, false);
395
396                             // Use the text from the renderer
397
ti.setText(0, renderer.getText() );
398
399                             // Calculate needed width and update the column if
400
// we have a wider one
401
int needed = SwingWTUtils.getRenderStringWidth(renderer.getText());
402                             if (needed > widestListItem) {
403                                 widestListItem = needed;
404                                 tc.setWidth(needed);
405                             }
406                             
407                             // If there's an image, render it:
408
if (renderer.getIcon() != null)
409                                 ti.setImage(0, SwingWTUtils.getSWTImageFromSwingIcon(list, renderer.getIcon()));
410
411                             // Colours
412
if (renderer.getBackground() != null)
413                                 if (renderer.getBackground().getSWTColor() != null)
414                                     ti.setBackground(renderer.getBackground().getSWTColor());
415                             if (renderer.getForeground() != null)
416                                 if (renderer.getForeground().getSWTColor() != null)
417                                     ti.setForeground(renderer.getForeground().getSWTColor());
418
419                             // Cursor
420
ppeer.setCursor(renderer.getCursor().getSWTCursor());
421                     }
422                 }
423             }
424         });
425     }
426     
427       /**
428       * Fill list model from array
429       */

430      public void setListData(Object JavaDoc [] listData) {
431          loadData(listData);
432          updateList();
433      }
434
435      /**
436       * Fill list model from vector
437       */

438      public void setListData(Vector listData) {
439          loadData(listData);
440          updateList();
441      }
442      
443      protected void loadData(Vector data) {
444          loadData(data.toArray());
445      }
446      
447      protected void loadData(Object JavaDoc[] data) {
448         listModel = new DefaultListModel();
449         for (int i = 0; i < data.length; i++) {
450             ((DefaultListModel) listModel).addElement(data[i]);
451         }
452         listModel.addListDataListener(this);
453      }
454      
455      public void setCellRenderer(ListCellRenderer r) { cellRenderer = r; }
456      public ListCellRenderer getCellRenderer() { return cellRenderer; }
457      
458      public ListModel getModel() {
459         return listModel;
460      }
461      
462      public void setModel(ListModel l) {
463         listModel = l;
464         listModel.addListDataListener(this);
465         updateList();
466      }
467     
468      /** Ensures the listmodel is an instance of
469       * DefaultListModel - returns false if it isn't.
470       */

471      protected boolean checkIsDefault() {
472          return listModel instanceof DefaultListModel;
473      }
474      
475     /**
476      * Once a parent component receives an "add" call for a child, this being
477      * the child, this should be called to tell us to instantiate the peer
478      * and load in any cached properties.
479      */

480     public void setSwingWTParent(swingwt.awt.Container parent) throws Exception JavaDoc {
481         descendantHasPeer = true;
482         
483         // Create the table peer
484
ppeer = new Table(parent.getComposite(), SWT.BORDER |
485             (listSelectionModel.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION ? SWT.MULTI : SWT.SINGLE)
486             | SWT.FULL_SELECTION );
487             
488         // Create a the single list column
489
org.eclipse.swt.widgets.TableColumn tc =
490             new org.eclipse.swt.widgets.TableColumn(ppeer, 0);
491         
492         peer = ppeer;
493         this.parent = parent;
494         
495         // Cached values and events
496
ppeer.setLinesVisible(false);
497         registerSelectionEvents();
498         
499         // Add data
500
updateList();
501         
502         if (pSelectedIndex != -1) ppeer.select(pSelectedIndex);
503         
504     }
505     
506     public void contentsChanged(swingwtx.swing.event.ListDataEvent e) {
507         updateList();
508     }
509     
510     public void intervalAdded(swingwtx.swing.event.ListDataEvent e) {
511         updateList();
512     }
513     
514     public void intervalRemoved(swingwtx.swing.event.ListDataEvent e) {
515         updateList();
516     }
517     
518     /**
519      * Assigns events to the peer for selection so that we can
520      * update the ListSelectionModel for this component.
521      */

522     protected void registerSelectionEvents() {
523         ppeer.addSelectionListener( new org.eclipse.swt.events.SelectionAdapter() {
524             public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
525                 if (listSelectionModel instanceof DefaultListSelectionModel) {
526                     if (listSelectionModel.getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) {
527                         int lowest = ppeer.getSelectionIndex(); int highest = ppeer.getSelectionIndex();
528                         int sel[] = ppeer.getSelectionIndices();
529                         for (int i = 0; i < sel.length; i++) {
530                             if (lowest > sel[i]) lowest = sel[i];
531                             if (highest < sel[i]) highest = sel[i];
532                         }
533                         ((DefaultListSelectionModel) listSelectionModel).fireListSelectionEvent(JList.this, lowest, highest);
534                     }
535                     else {
536                         ((DefaultListSelectionModel) listSelectionModel).fireListSelectionEvent(JList.this, ppeer.getSelectionIndex(), ppeer.getSelectionIndex());
537                     }
538                 }
539             }
540         });
541     }
542     
543 }
544
Popular Tags