KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > viewers > CheckboxTableViewer


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.viewers;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.core.runtime.ListenerList;
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.jface.util.SafeRunnable;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.SelectionEvent;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Table;
23 import org.eclipse.swt.widgets.TableColumn;
24 import org.eclipse.swt.widgets.TableItem;
25 import org.eclipse.swt.widgets.Widget;
26
27 /**
28  * A concrete viewer based on an SWT <code>Table</code>
29  * control with checkboxes on each node.
30  * <p>
31  * This class is not intended to be subclassed outside the viewer framework.
32  * It is designed to be instantiated with a pre-existing SWT table control and configured
33  * with a domain-specific content provider, label provider, element filter (optional),
34  * and element sorter (optional).
35  * </p>
36  */

37 public class CheckboxTableViewer extends TableViewer implements ICheckable {
38
39     /**
40      * List of check state listeners (element type: <code>ICheckStateListener</code>).
41      */

42     private ListenerList checkStateListeners = new ListenerList();
43
44     /**
45      * Creates a table viewer on a newly-created table control under the given parent.
46      * The table control is created using the SWT style bits:
47      * <code>SWT.CHECK</code> and <code>SWT.BORDER</code>.
48      * The table has one column.
49      * The viewer has no input, no content provider, a default label provider,
50      * no sorter, and no filters.
51      * <p>
52      * This is equivalent to calling <code>new CheckboxTableViewer(parent, SWT.BORDER)</code>.
53      * See that constructor for more details.
54      * </p>
55      *
56      * @param parent the parent control
57      *
58      * @deprecated use newCheckList(Composite, int) or new CheckboxTableViewer(Table)
59      * instead (see below for details)
60      */

61     public CheckboxTableViewer(Composite parent) {
62         this(parent, SWT.BORDER);
63     }
64
65     /**
66      * Creates a table viewer on a newly-created table control under the given parent.
67      * The table control is created using the given SWT style bits, plus the
68      * <code>SWT.CHECK</code> style bit.
69      * The table has one column.
70      * The viewer has no input, no content provider, a default label provider,
71      * no sorter, and no filters.
72      * <p>
73      * This also adds a <code>TableColumn</code> for the single column,
74      * and sets a <code>TableLayout</code> on the table which sizes the column to fill
75      * the table for its initial sizing, but does nothing on subsequent resizes.
76      * </p>
77      * <p>
78      * If the caller just needs to show a single column with no header,
79      * it is preferable to use the <code>newCheckList</code> factory method instead,
80      * since SWT properly handles the initial sizing and subsequent resizes in this case.
81      * </p>
82      * <p>
83      * If the caller adds its own columns, uses <code>Table.setHeadersVisible(true)</code>,
84      * or needs to handle dynamic resizing of the table, it is recommended to
85      * create the <code>Table</code> itself, specifying the <code>SWT.CHECK</code> style bit
86      * (along with any other style bits needed), and use <code>new CheckboxTableViewer(Table)</code>
87      * rather than this constructor.
88      * </p>
89      *
90      * @param parent the parent control
91      * @param style SWT style bits
92      *
93      * @deprecated use newCheckList(Composite, int) or new CheckboxTableViewer(Table)
94      * instead (see above for details)
95      */

96     public CheckboxTableViewer(Composite parent, int style) {
97         this(createTable(parent, style));
98     }
99
100     /**
101      * Creates a table viewer on a newly-created table control under the given parent.
102      * The table control is created using the given SWT style bits, plus the
103      * <code>SWT.CHECK</code> style bit.
104      * The table shows its contents in a single column, with no header.
105      * The viewer has no input, no content provider, a default label provider,
106      * no sorter, and no filters.
107      * <p>
108      * No <code>TableColumn</code> is added. SWT does not require a
109      * <code>TableColumn</code> if showing only a single column with no header.
110      * SWT correctly handles the initial sizing and subsequent resizes in this case.
111      *
112      * @param parent the parent control
113      * @param style SWT style bits
114      *
115      * @since 2.0
116      * @return CheckboxTableViewer
117      */

118     public static CheckboxTableViewer newCheckList(Composite parent, int style) {
119         Table table = new Table(parent, SWT.CHECK | style);
120         return new CheckboxTableViewer(table);
121     }
122
123     /**
124      * Creates a table viewer on the given table control.
125      * The <code>SWT.CHECK</code> style bit must be set on the given table control.
126      * The viewer has no input, no content provider, a default label provider,
127      * no sorter, and no filters.
128      *
129      * @param table the table control
130      */

131     public CheckboxTableViewer(Table table) {
132         super(table);
133     }
134
135     /* (non-Javadoc)
136      * Method declared on ICheckable.
137      */

138     public void addCheckStateListener(ICheckStateListener listener) {
139         checkStateListeners.add(listener);
140     }
141
142     /**
143      * Creates a new table control with one column.
144      *
145      * @param parent the parent control
146      * @param style style bits
147      * @return a new table control
148      */

149     protected static Table createTable(Composite parent, int style) {
150         Table table = new Table(parent, SWT.CHECK | style);
151
152         // Although this table column is not needed, and can cause resize problems,
153
// it can't be removed since this would be a breaking change against R1.0.
154
// See bug 6643 for more details.
155
new TableColumn(table, SWT.NONE);
156         TableLayout layout = new TableLayout();
157         layout.addColumnData(new ColumnWeightData(100));
158         table.setLayout(layout);
159
160         return table;
161     }
162
163     /**
164      * Notifies any check state listeners that a check state changed has been received.
165      * Only listeners registered at the time this method is called are notified.
166      *
167      * @param event a check state changed event
168      *
169      * @see ICheckStateListener#checkStateChanged
170      */

171     private void fireCheckStateChanged(final CheckStateChangedEvent event) {
172         Object JavaDoc[] array = checkStateListeners.getListeners();
173         for (int i = 0; i < array.length; i++) {
174             final ICheckStateListener l = (ICheckStateListener) array[i];
175             SafeRunnable.run(new SafeRunnable() {
176                 public void run() {
177                     l.checkStateChanged(event);
178                 }
179             });
180         }
181     }
182
183     /* (non-Javadoc)
184      * Method declared on ICheckable.
185      */

186     public boolean getChecked(Object JavaDoc element) {
187         Widget widget = findItem(element);
188         if (widget instanceof TableItem) {
189             return ((TableItem) widget).getChecked();
190         }
191         return false;
192     }
193
194     /**
195      * Returns a list of elements corresponding to checked table items in this
196      * viewer.
197      * <p>
198      * This method is typically used when preserving the interesting
199      * state of a viewer; <code>setCheckedElements</code> is used during the restore.
200      * </p>
201      *
202      * @return the array of checked elements
203      * @see #setCheckedElements
204      */

205     public Object JavaDoc[] getCheckedElements() {
206         TableItem[] children = getTable().getItems();
207         ArrayList JavaDoc v = new ArrayList JavaDoc(children.length);
208         for (int i = 0; i < children.length; i++) {
209             TableItem item = children[i];
210             if (item.getChecked()) {
211                 v.add(item.getData());
212             }
213         }
214         return v.toArray();
215     }
216
217     /**
218      * Returns the grayed state of the given element.
219      *
220      * @param element the element
221      * @return <code>true</code> if the element is grayed,
222      * and <code>false</code> if not grayed
223      */

224     public boolean getGrayed(Object JavaDoc element) {
225         Widget widget = findItem(element);
226         if (widget instanceof TableItem) {
227             return ((TableItem) widget).getGrayed();
228         }
229         return false;
230     }
231
232     /**
233      * Returns a list of elements corresponding to grayed nodes in this
234      * viewer.
235      * <p>
236      * This method is typically used when preserving the interesting
237      * state of a viewer; <code>setGrayedElements</code> is used during the restore.
238      * </p>
239      *
240      * @return the array of grayed elements
241      * @see #setGrayedElements
242      */

243     public Object JavaDoc[] getGrayedElements() {
244         TableItem[] children = getTable().getItems();
245         List JavaDoc v = new ArrayList JavaDoc(children.length);
246         for (int i = 0; i < children.length; i++) {
247             TableItem item = children[i];
248             if (item.getGrayed()) {
249                 v.add(item.getData());
250             }
251         }
252         return v.toArray();
253     }
254
255     /* (non-Javadoc)
256      * Method declared on StructuredViewer.
257      */

258     public void handleSelect(SelectionEvent event) {
259         if (event.detail == SWT.CHECK) {
260             super.handleSelect(event); // this will change the current selection
261

262             TableItem item = (TableItem) event.item;
263             Object JavaDoc data = item.getData();
264             if (data != null) {
265                 fireCheckStateChanged(new CheckStateChangedEvent(this, data,
266                         item.getChecked()));
267             }
268         } else {
269             super.handleSelect(event);
270         }
271     }
272
273     /* (non-Javadoc)
274      * Method declared on Viewer.
275      */

276     protected void preservingSelection(Runnable JavaDoc updateCode) {
277
278         TableItem[] children = getTable().getItems();
279         CustomHashtable checked = newHashtable(children.length * 2 + 1);
280         CustomHashtable grayed = newHashtable(children.length * 2 + 1);
281
282         for (int i = 0; i < children.length; i++) {
283             TableItem item = children[i];
284             Object JavaDoc data = item.getData();
285             if (data != null) {
286                 if (item.getChecked()) {
287                     checked.put(data, data);
288                 }
289                 if (item.getGrayed()) {
290                     grayed.put(data, data);
291                 }
292             }
293         }
294
295         super.preservingSelection(updateCode);
296
297         children = getTable().getItems();
298         for (int i = 0; i < children.length; i++) {
299             TableItem item = children[i];
300             Object JavaDoc data = item.getData();
301             if (data != null) {
302                 item.setChecked(checked.containsKey(data));
303                 item.setGrayed(grayed.containsKey(data));
304             }
305         }
306     }
307
308     /* (non-Javadoc)
309      * Method declared on ICheckable.
310      */

311     public void removeCheckStateListener(ICheckStateListener listener) {
312         checkStateListeners.remove(listener);
313     }
314
315     /**
316      * Sets to the given value the checked state for all elements in this viewer.
317      * Does not fire events to check state listeners.
318      *
319      * @param state <code>true</code> if the element should be checked,
320      * and <code>false</code> if it should be unchecked
321      */

322     public void setAllChecked(boolean state) {
323         TableItem[] children = getTable().getItems();
324         for (int i = 0; i < children.length; i++) {
325             TableItem item = children[i];
326             item.setChecked(state);
327         }
328     }
329
330     /**
331      * Sets to the given value the grayed state for all elements in this viewer.
332      *
333      * @param state <code>true</code> if the element should be grayed,
334      * and <code>false</code> if it should be ungrayed
335      */

336     public void setAllGrayed(boolean state) {
337         TableItem[] children = getTable().getItems();
338         for (int i = 0; i < children.length; i++) {
339             TableItem item = children[i];
340             item.setGrayed(state);
341         }
342     }
343
344     /* (non-Javadoc)
345      * Method declared on ICheckable.
346      */

347     public boolean setChecked(Object JavaDoc element, boolean state) {
348         Assert.isNotNull(element);
349         Widget widget = findItem(element);
350         if (widget instanceof TableItem) {
351             ((TableItem) widget).setChecked(state);
352             return true;
353         }
354         return false;
355     }
356
357     /**
358      * Sets which nodes are checked in this viewer.
359      * The given list contains the elements that are to be checked;
360      * all other nodes are to be unchecked.
361      * Does not fire events to check state listeners.
362      * <p>
363      * This method is typically used when restoring the interesting
364      * state of a viewer captured by an earlier call to <code>getCheckedElements</code>.
365      * </p>
366      *
367      * @param elements the list of checked elements (element type: <code>Object</code>)
368      * @see #getCheckedElements
369      */

370     public void setCheckedElements(Object JavaDoc[] elements) {
371         assertElementsNotNull(elements);
372         CustomHashtable set = newHashtable(elements.length * 2 + 1);
373         for (int i = 0; i < elements.length; ++i) {
374             set.put(elements[i], elements[i]);
375         }
376         TableItem[] items = getTable().getItems();
377         for (int i = 0; i < items.length; ++i) {
378             TableItem item = items[i];
379             Object JavaDoc element = item.getData();
380             if (element != null) {
381                 boolean check = set.containsKey(element);
382                 // only set if different, to avoid flicker
383
if (item.getChecked() != check) {
384                     item.setChecked(check);
385                 }
386             }
387         }
388     }
389
390     /**
391      * Sets the grayed state for the given element in this viewer.
392      *
393      * @param element the element
394      * @param state <code>true</code> if the item should be grayed,
395      * and <code>false</code> if it should be ungrayed
396      * @return <code>true</code> if the element is visible and the gray
397      * state could be set, and <code>false</code> otherwise
398      */

399     public boolean setGrayed(Object JavaDoc element, boolean state) {
400         Assert.isNotNull(element);
401         Widget widget = findItem(element);
402         if (widget instanceof TableItem) {
403             ((TableItem) widget).setGrayed(state);
404             return true;
405         }
406         return false;
407     }
408
409     /**
410      * Sets which nodes are grayed in this viewer.
411      * The given list contains the elements that are to be grayed;
412      * all other nodes are to be ungrayed.
413      * <p>
414      * This method is typically used when restoring the interesting
415      * state of a viewer captured by an earlier call to <code>getGrayedElements</code>.
416      * </p>
417      *
418      * @param elements the array of grayed elements
419      *
420      * @see #getGrayedElements
421      */

422     public void setGrayedElements(Object JavaDoc[] elements) {
423         assertElementsNotNull(elements);
424         CustomHashtable set = newHashtable(elements.length * 2 + 1);
425         for (int i = 0; i < elements.length; ++i) {
426             set.put(elements[i], elements[i]);
427         }
428         TableItem[] items = getTable().getItems();
429         for (int i = 0; i < items.length; ++i) {
430             TableItem item = items[i];
431             Object JavaDoc element = item.getData();
432             if (element != null) {
433                 boolean gray = set.containsKey(element);
434                 // only set if different, to avoid flicker
435
if (item.getGrayed() != gray) {
436                     item.setGrayed(gray);
437                 }
438             }
439         }
440     }
441 }
442
Popular Tags