KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > TreeItem


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.swt.widgets;
12
13  
14 import org.eclipse.swt.internal.win32.*;
15 import org.eclipse.swt.*;
16 import org.eclipse.swt.graphics.*;
17
18 /**
19  * Instances of this class represent a selectable user interface object
20  * that represents a hierarchy of tree items in a tree widget.
21  *
22  * <dl>
23  * <dt><b>Styles:</b></dt>
24  * <dd>(none)</dd>
25  * <dt><b>Events:</b></dt>
26  * <dd>(none)</dd>
27  * </dl>
28  * <p>
29  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
30  * </p>
31  */

32
33 public class TreeItem extends Item {
34     /**
35      * the handle to the OS resource
36      * (Warning: This field is platform dependent)
37      * <p>
38      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
39      * public API. It is marked public only so that it can be shared
40      * within the packages provided by SWT. It is not available on all
41      * platforms and should never be accessed from application code.
42      * </p>
43      */

44     public int handle;
45     Tree parent;
46     String JavaDoc [] strings;
47     Image [] images;
48     boolean cached;
49     int background = -1, foreground = -1, font = -1;
50     int [] cellBackground, cellForeground, cellFont;
51     
52 /**
53  * Constructs a new instance of this class given its parent
54  * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
55  * and a style value describing its behavior and appearance.
56  * The item is added to the end of the items maintained by its parent.
57  * <p>
58  * The style value is either one of the style constants defined in
59  * class <code>SWT</code> which is applicable to instances of this
60  * class, or must be built by <em>bitwise OR</em>'ing together
61  * (that is, using the <code>int</code> "|" operator) two or more
62  * of those <code>SWT</code> style constants. The class description
63  * lists the style constants that are applicable to the class.
64  * Style bits are also inherited from superclasses.
65  * </p>
66  *
67  * @param parent a tree control which will be the parent of the new instance (cannot be null)
68  * @param style the style of control to construct
69  *
70  * @exception IllegalArgumentException <ul>
71  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
72  * </ul>
73  * @exception SWTException <ul>
74  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
75  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
76  * </ul>
77  *
78  * @see SWT
79  * @see Widget#checkSubclass
80  * @see Widget#getStyle
81  */

82 public TreeItem (Tree parent, int style) {
83     this (parent, style, OS.TVGN_ROOT, OS.TVI_LAST, 0);
84 }
85
86 /**
87  * Constructs a new instance of this class given its parent
88  * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
89  * a style value describing its behavior and appearance, and the index
90  * at which to place it in the items maintained by its parent.
91  * <p>
92  * The style value is either one of the style constants defined in
93  * class <code>SWT</code> which is applicable to instances of this
94  * class, or must be built by <em>bitwise OR</em>'ing together
95  * (that is, using the <code>int</code> "|" operator) two or more
96  * of those <code>SWT</code> style constants. The class description
97  * lists the style constants that are applicable to the class.
98  * Style bits are also inherited from superclasses.
99  * </p>
100  *
101  * @param parent a tree control which will be the parent of the new instance (cannot be null)
102  * @param style the style of control to construct
103  * @param index the zero-relative index to store the receiver in its parent
104  *
105  * @exception IllegalArgumentException <ul>
106  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
107  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
108  * </ul>
109  * @exception SWTException <ul>
110  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
111  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
112  * </ul>
113  *
114  * @see SWT
115  * @see Widget#checkSubclass
116  * @see Widget#getStyle
117  */

118 public TreeItem (Tree parent, int style, int index) {
119     this (parent, style, OS.TVGN_ROOT, findPrevious (parent, index), 0);
120 }
121
122 /**
123  * Constructs a new instance of this class given its parent
124  * (which must be a <code>Tree</code> or a <code>TreeItem</code>)
125  * and a style value describing its behavior and appearance.
126  * The item is added to the end of the items maintained by its parent.
127  * <p>
128  * The style value is either one of the style constants defined in
129  * class <code>SWT</code> which is applicable to instances of this
130  * class, or must be built by <em>bitwise OR</em>'ing together
131  * (that is, using the <code>int</code> "|" operator) two or more
132  * of those <code>SWT</code> style constants. The class description
133  * lists the style constants that are applicable to the class.
134  * Style bits are also inherited from superclasses.
135  * </p>
136  *
137  * @param parentItem a tree control which will be the parent of the new instance (cannot be null)
138  * @param style the style of control to construct
139  *
140  * @exception IllegalArgumentException <ul>
141  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
142  * </ul>
143  * @exception SWTException <ul>
144  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
145  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
146  * </ul>
147  *
148  * @see SWT
149  * @see Widget#checkSubclass
150  * @see Widget#getStyle
151  */

152 public TreeItem (TreeItem parentItem, int style) {
153     this (checkNull (parentItem).parent, style, parentItem.handle, OS.TVI_LAST, 0);
154 }
155
156 /**
157  * Constructs a new instance of this class given its parent
158  * (which must be a <code>Tree</code> or a <code>TreeItem</code>),
159  * a style value describing its behavior and appearance, and the index
160  * at which to place it in the items maintained by its parent.
161  * <p>
162  * The style value is either one of the style constants defined in
163  * class <code>SWT</code> which is applicable to instances of this
164  * class, or must be built by <em>bitwise OR</em>'ing together
165  * (that is, using the <code>int</code> "|" operator) two or more
166  * of those <code>SWT</code> style constants. The class description
167  * lists the style constants that are applicable to the class.
168  * Style bits are also inherited from superclasses.
169  * </p>
170  *
171  * @param parentItem a tree control which will be the parent of the new instance (cannot be null)
172  * @param style the style of control to construct
173  * @param index the zero-relative index to store the receiver in its parent
174  *
175  * @exception IllegalArgumentException <ul>
176  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
177  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li>
178  * </ul>
179  * @exception SWTException <ul>
180  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
181  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
182  * </ul>
183  *
184  * @see SWT
185  * @see Widget#checkSubclass
186  * @see Widget#getStyle
187  */

188 public TreeItem (TreeItem parentItem, int style, int index) {
189     this (checkNull (parentItem).parent, style, parentItem.handle, findPrevious (parentItem, index), 0);
190 }
191
192 TreeItem (Tree parent, int style, int hParent, int hInsertAfter, int hItem) {
193     super (parent, style);
194     this.parent = parent;
195     parent.createItem (this, hParent, hInsertAfter, hItem);
196 }
197
198 static TreeItem checkNull (TreeItem item) {
199     if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
200     return item;
201 }
202
203 static int findPrevious (Tree parent, int index) {
204     if (parent == null) return 0;
205     if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE);
206     if (index == 0) return OS.TVI_FIRST;
207     int hwnd = parent.handle;
208     int hFirstItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0);
209     int hItem = parent.findItem (hFirstItem, index - 1);
210     if (hItem == 0) SWT.error (SWT.ERROR_INVALID_RANGE);
211     return hItem;
212 }
213
214 static int findPrevious (TreeItem parentItem, int index) {
215     if (parentItem == null) return 0;
216     if (index < 0) SWT.error (SWT.ERROR_INVALID_RANGE);
217     if (index == 0) return OS.TVI_FIRST;
218     Tree parent = parentItem.parent;
219     int hwnd = parent.handle, hParent = parentItem.handle;
220     int hFirstItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hParent);
221     int hItem = parent.findItem (hFirstItem, index - 1);
222     if (hItem == 0) SWT.error (SWT.ERROR_INVALID_RANGE);
223     return hItem;
224 }
225
226 protected void checkSubclass () {
227     if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
228 }
229
230 void clear () {
231     text = "";
232     image = null;
233     strings = null;
234     images = null;
235     if ((parent.style & SWT.CHECK) != 0) {
236         int hwnd = parent.handle;
237         TVITEM tvItem = new TVITEM ();
238         tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
239         tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
240         tvItem.state = 1 << 12;
241         tvItem.hItem = handle;
242         OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
243     }
244     background = foreground = font = -1;
245     cellBackground = cellForeground = cellFont = null;
246     if ((parent.style & SWT.VIRTUAL) != 0) cached = false;
247 }
248
249 /**
250  * Clears the item at the given zero-relative index in the receiver.
251  * The text, icon and other attributes of the item are set to the default
252  * value. If the tree was created with the <code>SWT.VIRTUAL</code> style,
253  * these attributes are requested again as needed.
254  *
255  * @param index the index of the item to clear
256  * @param all <code>true</code> if all child items of the indexed item should be
257  * cleared recursively, and <code>false</code> otherwise
258  *
259  * @exception IllegalArgumentException <ul>
260  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
261  * </ul>
262  * @exception SWTException <ul>
263  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
264  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
265  * </ul>
266  *
267  * @see SWT#VIRTUAL
268  * @see SWT#SetData
269  *
270  * @since 3.2
271  */

272 public void clear (int index, boolean all) {
273     checkWidget ();
274     int hwnd = parent.handle;
275     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
276     if (hItem == 0) error (SWT.ERROR_INVALID_RANGE);
277     hItem = parent.findItem (hItem, index);
278     if (hItem == 0) error (SWT.ERROR_INVALID_RANGE);
279     TVITEM tvItem = new TVITEM ();
280     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
281     parent.clear (hItem, tvItem);
282     if (all) {
283         hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem);
284         parent.clearAll (hItem, tvItem, all);
285     }
286 }
287
288 /**
289  * Clears all the items in the receiver. The text, icon and other
290  * attributes of the items are set to their default values. If the
291  * tree was created with the <code>SWT.VIRTUAL</code> style, these
292  * attributes are requested again as needed.
293  *
294  * @param all <code>true</code> if all child items should be cleared
295  * recursively, and <code>false</code> otherwise
296  *
297  * @exception SWTException <ul>
298  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
299  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
300  * </ul>
301  *
302  * @see SWT#VIRTUAL
303  * @see SWT#SetData
304  *
305  * @since 3.2
306  */

307 public void clearAll (boolean all) {
308     checkWidget ();
309     int hwnd = parent.handle;
310     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
311     if (hItem == 0) return;
312     TVITEM tvItem = new TVITEM ();
313     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
314     parent.clearAll (hItem, tvItem, all);
315 }
316
317 void destroyWidget () {
318     TVITEM tvItem = new TVITEM ();
319     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
320     parent.releaseItem (handle, tvItem, false);
321     parent.destroyItem (this, handle);
322     releaseHandle ();
323 }
324
325 /**
326  * Returns the receiver's background color.
327  *
328  * @return the background color
329  *
330  * @exception SWTException <ul>
331  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
332  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
333  * </ul>
334  *
335  * @since 2.0
336  *
337  */

338 public Color getBackground () {
339     checkWidget ();
340     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
341     if (background == -1) return parent.getBackground ();
342     return Color.win32_new (display, background);
343 }
344
345 /**
346  * Returns the background color at the given column index in the receiver.
347  *
348  * @param index the column index
349  * @return the background color
350  *
351  * @exception SWTException <ul>
352  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
353  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
354  * </ul>
355  *
356  * @since 3.1
357  */

358 public Color getBackground (int index) {
359     checkWidget ();
360     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
361     int count = Math.max (1, parent.getColumnCount ());
362     if (0 > index || index > count - 1) return getBackground ();
363     int pixel = cellBackground != null ? cellBackground [index] : -1;
364     return pixel == -1 ? getBackground () : Color.win32_new (display, pixel);
365 }
366
367 /**
368  * Returns a rectangle describing the receiver's size and location
369  * relative to its parent.
370  *
371  * @return the receiver's bounding rectangle
372  *
373  * @exception SWTException <ul>
374  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
375  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
376  * </ul>
377  */

378 public Rectangle getBounds () {
379     checkWidget ();
380     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
381     RECT rect = getBounds (0, true, false, false);
382     int width = rect.right - rect.left, height = rect.bottom - rect.top;
383     return new Rectangle (rect.left, rect.top, width, height);
384 }
385
386 /**
387  * Returns a rectangle describing the receiver's size and location
388  * relative to its parent at a column in the tree.
389  *
390  * @param index the index that specifies the column
391  * @return the receiver's bounding column rectangle
392  *
393  * @exception SWTException <ul>
394  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
395  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
396  * </ul>
397  *
398  * @since 3.1
399  */

400 public Rectangle getBounds (int index) {
401     checkWidget();
402     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
403     RECT rect = getBounds (index, true, true, true);
404     int width = rect.right - rect.left, height = rect.bottom - rect.top;
405     return new Rectangle (rect.left, rect.top, width, height);
406 }
407
408 RECT getBounds (int index, boolean getText, boolean getImage, boolean fullText) {
409     return getBounds (index, getText, getImage, fullText, false, true, 0);
410 }
411
412 //TODO - take into account grid (add boolean arg) to damage less during redraw
413
RECT getBounds (int index, boolean getText, boolean getImage, boolean fullText, boolean fullImage, boolean clip, int hDC) {
414     if (!getText && !getImage) return new RECT ();
415     int hwnd = parent.handle;
416     if ((parent.style & SWT.VIRTUAL) == 0 && !cached && !parent.painted) {
417         TVITEM tvItem = new TVITEM ();
418         tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT;
419         tvItem.hItem = handle;
420         tvItem.pszText = OS.LPSTR_TEXTCALLBACK;
421         parent.ignoreCustomDraw = true;
422         OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
423         parent.ignoreCustomDraw = false;
424     }
425     boolean firstColumn = index == 0;
426     int columnCount = 0, hwndHeader = parent.hwndHeader;
427     if (hwndHeader != 0) {
428         columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0);
429         firstColumn = index == OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0);
430     }
431     RECT rect = new RECT ();
432     if (firstColumn) {
433         rect.left = handle;
434         boolean full = columnCount == 0 && getText && getImage && fullText && fullImage;
435         if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, full ? 0 : 1, rect) == 0) {
436             return new RECT ();
437         }
438         if (getImage && !fullImage) {
439             if (OS.SendMessage (hwnd, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0) != 0) {
440                 Point size = parent.getImageSize ();
441                 rect.left -= size.x + Tree.INSET;
442                 if (!getText) rect.right = rect.left + size.x;
443             } else {
444                 if (!getText) rect.right = rect.left;
445             }
446         }
447         if (fullText || fullImage || clip) {
448             if (hwndHeader != 0) {
449                 RECT headerRect = new RECT ();
450                 if (columnCount != 0) {
451                     if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) == 0) {
452                         return new RECT ();
453                     }
454                 } else {
455                     headerRect.right = parent.scrollWidth;
456                     if (headerRect.right == 0) headerRect = rect;
457                 }
458                 if (fullText) rect.right = headerRect.right;
459                 if (fullImage) rect.left = headerRect.left;
460                 if (clip && headerRect.right < rect.right) {
461                     rect.right = headerRect.right;
462                 }
463             }
464         }
465     } else {
466         if (!(0 <= index && index < columnCount)) return new RECT ();
467         RECT headerRect = new RECT ();
468         if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) == 0) {
469             return new RECT ();
470         }
471         rect.left = handle;
472         if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) == 0) {
473             return new RECT ();
474         }
475         rect.left = headerRect.left;
476         if (fullText && getImage) {
477             rect.right = headerRect.right;
478         } else {
479             rect.right = headerRect.left;
480             Image image = null;
481             if (index == 0) {
482                 image = this.image;
483             } else {
484                 if (images != null) image = images [index];
485             }
486             if (image != null) {
487                 Point size = parent.getImageSize ();
488                 rect.right += size.x;
489             }
490             if (getText) {
491                 if (fullText) {
492                     rect.left = rect.right + Tree.INSET;
493                     rect.right = headerRect.right;
494                 } else {
495                     String JavaDoc string = index == 0 ? text : strings != null ? strings [index] : null;
496                     if (string != null) {
497                         RECT textRect = new RECT ();
498                         TCHAR buffer = new TCHAR (parent.getCodePage (), string, false);
499                         int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_CALCRECT;
500                         int hNewDC = hDC, hFont = 0;
501                         if (hDC == 0) {
502                             hNewDC = OS.GetDC (hwnd);
503                             hFont = cellFont != null ? cellFont [index] : -1;
504                             if (hFont == -1) hFont = font;
505                             if (hFont == -1) hFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0);
506                             hFont = OS.SelectObject (hNewDC, hFont);
507                         }
508                         OS.DrawText (hNewDC, buffer, buffer.length (), textRect, flags);
509                         if (hDC == 0) {
510                             OS.SelectObject (hNewDC, hFont);
511                             OS.ReleaseDC (hwnd, hNewDC);
512                         }
513                         if (getImage) {
514                             rect.right += textRect.right - textRect.left + Tree.INSET * 3;
515                         } else {
516                             rect.left = rect.right + Tree.INSET;
517                             rect.right = rect.left + (textRect.right - textRect.left) + Tree.INSET;
518                         }
519                     }
520                 }
521             }
522             if (clip && headerRect.right < rect.right) {
523                 rect.right = headerRect.right;
524             }
525         }
526     }
527     int gridWidth = parent.linesVisible && columnCount != 0 ? Tree.GRID_WIDTH : 0;
528     if (getText || !getImage) {
529         rect.right = Math.max (rect.left, rect.right - gridWidth);
530     }
531     rect.bottom = Math.max (rect.top, rect.bottom - gridWidth);
532     return rect;
533 }
534
535 /**
536  * Returns <code>true</code> if the receiver is checked,
537  * and false otherwise. When the parent does not have
538  * the <code>CHECK style, return false.
539  * <p>
540  *
541  * @return the checked state
542  *
543  * @exception SWTException <ul>
544  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
545  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
546  * </ul>
547  */

548 public boolean getChecked () {
549     checkWidget ();
550     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
551     if ((parent.style & SWT.CHECK) == 0) return false;
552     int hwnd = parent.handle;
553     TVITEM tvItem = new TVITEM ();
554     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
555     tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
556     tvItem.hItem = handle;
557     int result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
558     return (result != 0) && (((tvItem.state >> 12) & 1) == 0);
559 }
560
561 /**
562  * Returns <code>true</code> if the receiver is expanded,
563  * and false otherwise.
564  * <p>
565  *
566  * @return the expanded state
567  *
568  * @exception SWTException <ul>
569  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
570  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
571  * </ul>
572  */

573 public boolean getExpanded () {
574     checkWidget ();
575     int hwnd = parent.handle, state = 0;
576     if (OS.IsWinCE) {
577         TVITEM tvItem = new TVITEM ();
578         tvItem.hItem = handle;
579         tvItem.mask = OS.TVIF_STATE;
580         OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
581         state = tvItem.state;
582     } else {
583         /*
584         * Bug in Windows. Despite the fact that TVM_GETITEMSTATE claims
585         * to return only the bits specified by the stateMask, when called
586         * with TVIS_EXPANDED, the entire state is returned. The fix is
587         * to explicitly check for the TVIS_EXPANDED bit.
588         */

589         state = OS.SendMessage (hwnd, OS.TVM_GETITEMSTATE, handle, OS.TVIS_EXPANDED);
590     }
591     return (state & OS.TVIS_EXPANDED) != 0;
592 }
593
594 /**
595  * Returns the font that the receiver will use to paint textual information for this item.
596  *
597  * @return the receiver's font
598  *
599  * @exception SWTException <ul>
600  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
601  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
602  * </ul>
603  *
604  * @since 3.0
605  */

606 public Font getFont () {
607     checkWidget ();
608     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
609     return font == -1 ? parent.getFont () : Font.win32_new (display, font);
610 }
611
612 /**
613  * Returns the font that the receiver will use to paint textual information
614  * for the specified cell in this item.
615  *
616  * @param index the column index
617  * @return the receiver's font
618  *
619  * @exception SWTException <ul>
620  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
621  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
622  * </ul>
623  *
624  * @since 3.1
625  */

626 public Font getFont (int index) {
627     checkWidget ();
628     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
629     int count = Math.max (1, parent.getColumnCount ());
630     if (0 > index || index > count -1) return getFont ();
631     int hFont = (cellFont != null) ? cellFont [index] : font;
632     return hFont == -1 ? getFont () : Font.win32_new (display, hFont);
633 }
634
635 /**
636  * Returns the foreground color that the receiver will use to draw.
637  *
638  * @return the receiver's foreground color
639  *
640  * @exception SWTException <ul>
641  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
642  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
643  * </ul>
644  *
645  * @since 2.0
646  *
647  */

648 public Color getForeground () {
649     checkWidget ();
650     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
651     if (foreground == -1) return parent.getForeground ();
652     return Color.win32_new (display, foreground);
653 }
654
655 /**
656  *
657  * Returns the foreground color at the given column index in the receiver.
658  *
659  * @param index the column index
660  * @return the foreground color
661  *
662  * @exception SWTException <ul>
663  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
664  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
665  * </ul>
666  *
667  * @since 3.1
668  */

669 public Color getForeground (int index) {
670     checkWidget ();
671     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
672     int count = Math.max (1, parent.getColumnCount ());
673     if (0 > index || index > count -1) return getForeground ();
674     int pixel = cellForeground != null ? cellForeground [index] : -1;
675     return pixel == -1 ? getForeground () : Color.win32_new (display, pixel);
676 }
677
678 /**
679  * Returns <code>true</code> if the receiver is grayed,
680  * and false otherwise. When the parent does not have
681  * the <code>CHECK style, return false.
682  * <p>
683  *
684  * @return the grayed state of the checkbox
685  *
686  * @exception SWTException <ul>
687  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
688  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
689  * </ul>
690  */

691 public boolean getGrayed () {
692     checkWidget ();
693     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
694     if ((parent.style & SWT.CHECK) == 0) return false;
695     int hwnd = parent.handle;
696     TVITEM tvItem = new TVITEM ();
697     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
698     tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
699     tvItem.hItem = handle;
700     int result = OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
701     return (result != 0) && ((tvItem.state >> 12) > 2);
702 }
703
704 /**
705  * Returns the item at the given, zero-relative index in the
706  * receiver. Throws an exception if the index is out of range.
707  *
708  * @param index the index of the item to return
709  * @return the item at the given index
710  *
711  * @exception IllegalArgumentException <ul>
712  * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
713  * </ul>
714  * @exception SWTException <ul>
715  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
716  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
717  * </ul>
718  *
719  * @since 3.1
720  */

721 public TreeItem getItem (int index) {
722     checkWidget ();
723     if (index < 0) error (SWT.ERROR_INVALID_RANGE);
724     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
725     int hwnd = parent.handle;
726     int hFirstItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
727     if (hFirstItem == 0) error (SWT.ERROR_INVALID_RANGE);
728     int hItem = parent.findItem (hFirstItem, index);
729     if (hItem == 0) error (SWT.ERROR_INVALID_RANGE);
730     return parent._getItem (hItem);
731 }
732
733 /**
734  * Returns the number of items contained in the receiver
735  * that are direct item children of the receiver.
736  *
737  * @return the number of items
738  *
739  * @exception SWTException <ul>
740  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
741  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
742  * </ul>
743  */

744 public int getItemCount () {
745     checkWidget ();
746     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
747     int hwnd = parent.handle;
748     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
749     if (hItem == 0) return 0;
750     return parent.getItemCount (hItem);
751 }
752
753 /**
754  * Returns a (possibly empty) array of <code>TreeItem</code>s which
755  * are the direct item children of the receiver.
756  * <p>
757  * Note: This is not the actual structure used by the receiver
758  * to maintain its list of items, so modifying the array will
759  * not affect the receiver.
760  * </p>
761  *
762  * @return the receiver's items
763  *
764  * @exception SWTException <ul>
765  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
766  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
767  * </ul>
768  */

769 public TreeItem [] getItems () {
770     checkWidget ();
771     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
772     int hwnd = parent.handle;
773     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
774     if (hItem == 0) return new TreeItem [0];
775     return parent.getItems (hItem);
776 }
777
778 public Image getImage () {
779     checkWidget();
780     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
781     return super.getImage ();
782 }
783
784 /**
785  * Returns the image stored at the given column index in the receiver,
786  * or null if the image has not been set or if the column does not exist.
787  *
788  * @param index the column index
789  * @return the image stored at the given column index in the receiver
790  *
791  * @exception SWTException <ul>
792  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
793  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
794  * </ul>
795  *
796  * @since 3.1
797  */

798 public Image getImage (int index) {
799     checkWidget();
800     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
801     if (index == 0) return getImage ();
802     if (images != null) {
803         if (0 <= index && index < images.length) return images [index];
804     }
805     return null;
806 }
807
808 /**
809  * Returns a rectangle describing the size and location
810  * relative to its parent of an image at a column in the
811  * tree.
812  *
813  * @param index the index that specifies the column
814  * @return the receiver's bounding image rectangle
815  *
816  * @exception SWTException <ul>
817  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
818  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
819  * </ul>
820  *
821  * @since 3.1
822  */

823 public Rectangle getImageBounds (int index) {
824     checkWidget();
825     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
826     RECT rect = getBounds (index, false, true, false);
827     int width = rect.right - rect.left, height = rect.bottom - rect.top;
828     return new Rectangle (rect.left, rect.top, width, height);
829 }
830
831 /**
832  * Returns the receiver's parent, which must be a <code>Tree</code>.
833  *
834  * @return the receiver's parent
835  *
836  * @exception SWTException <ul>
837  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
838  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
839  * </ul>
840  */

841 public Tree getParent () {
842     checkWidget ();
843     return parent;
844 }
845
846 /**
847  * Returns the receiver's parent item, which must be a
848  * <code>TreeItem</code> or null when the receiver is a
849  * root.
850  *
851  * @return the receiver's parent item
852  *
853  * @exception SWTException <ul>
854  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
855  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
856  * </ul>
857  */

858 public TreeItem getParentItem () {
859     checkWidget ();
860     int hwnd = parent.handle;
861     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, handle);
862     return hItem != 0 ? parent._getItem (hItem) : null;
863 }
864
865 public String JavaDoc getText () {
866     checkWidget();
867     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
868     return super.getText ();
869 }
870
871 /**
872  * Returns the text stored at the given column index in the receiver,
873  * or empty string if the text has not been set.
874  *
875  * @param index the column index
876  * @return the text stored at the given column index in the receiver
877  *
878  * @exception SWTException <ul>
879  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
880  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
881  * </ul>
882  *
883  * @since 3.1
884  */

885 public String JavaDoc getText (int index) {
886     checkWidget();
887     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
888     if (index == 0) return getText ();
889     if (strings != null) {
890         if (0 <= index && index < strings.length) {
891             String JavaDoc string = strings [index];
892             return string != null ? string : "";
893         }
894     }
895     return "";
896 }
897
898 /**
899  * Returns a rectangle describing the size and location
900  * relative to its parent of the text at a column in the
901  * tree.
902  *
903  * @param index the index that specifies the column
904  * @return the receiver's bounding text rectangle
905  *
906  * @exception SWTException <ul>
907  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
908  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
909  * </ul>
910  *
911  * @since 3.3
912  */

913 public Rectangle getTextBounds (int index) {
914     checkWidget();
915     if (!parent.checkData (this, true)) error (SWT.ERROR_WIDGET_DISPOSED);
916     RECT rect = getBounds (index, true, false, true);
917     if (index == 0) rect.left += Tree.INSET - 1;
918     rect.left = Math.min (rect.left, rect.right);
919     rect.right = rect.right - Tree.INSET;
920     int width = Math.max (0, rect.right - rect.left);
921     int height = Math.max (0, rect.bottom - rect.top);
922     return new Rectangle (rect.left, rect.top, width, height);
923 }
924
925 /**
926  * Searches the receiver's list starting at the first item
927  * (index 0) until an item is found that is equal to the
928  * argument, and returns the index of that item. If no item
929  * is found, returns -1.
930  *
931  * @param item the search item
932  * @return the index of the item
933  *
934  * @exception IllegalArgumentException <ul>
935  * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
936  * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
937  * </ul>
938  * @exception SWTException <ul>
939  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
940  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
941  * </ul>
942  *
943  * @since 3.1
944  */

945 public int indexOf (TreeItem item) {
946     checkWidget ();
947     if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
948     if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
949     int hwnd = parent.handle;
950     int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
951     return hItem == 0 ? -1 : parent.findIndex (hItem, item.handle);
952 }
953
954 void redraw () {
955     if (parent.currentItem == this || parent.drawCount != 0) return;
956     int hwnd = parent.handle;
957     if (!OS.IsWindowVisible (hwnd)) return;
958     RECT rect = new RECT ();
959     rect.left = handle;
960     /*
961     * When there are no columns and the tree is not
962     * full selection, redraw only the text. This is
963     * an optimization to reduce flashing.
964     */

965     boolean full = (parent.style & (SWT.FULL_SELECTION | SWT.VIRTUAL)) != 0;
966     if (!full) {
967         int hwndHeader = parent.hwndHeader;
968         if (hwndHeader != 0) {
969             full = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) != 0;
970         }
971         if (!full) {
972             if (parent.hooks (SWT.EraseItem) || parent.hooks (SWT.PaintItem)) {
973                 full = true;
974             }
975         }
976     }
977     if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, full ? 0 : 1, rect) != 0) {
978         OS.InvalidateRect (hwnd, rect, true);
979     }
980 }
981
982 void redraw (int column, boolean drawText, boolean drawImage) {
983     if (parent.currentItem == this || parent.drawCount != 0) return;
984     int hwnd = parent.handle;
985     if (!OS.IsWindowVisible (hwnd)) return;
986     boolean fullImage = column == 0 && drawText && drawImage;
987     RECT rect = getBounds (column, drawText, drawImage, true, fullImage, true, 0);
988     OS.InvalidateRect (hwnd, rect, true);
989 }
990
991 void releaseChildren (boolean destroy) {
992     if (destroy) {
993         TVITEM tvItem = new TVITEM ();
994         tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
995         parent.releaseItems (handle, tvItem);
996     }
997     super.releaseChildren (destroy);
998 }
999
1000void releaseHandle () {
1001    super.releaseHandle ();
1002    handle = 0;
1003    parent = null;
1004}
1005
1006void releaseWidget () {
1007    super.releaseWidget ();
1008    strings = null;
1009    images = null;
1010    cellBackground = cellForeground = cellFont = null;
1011}
1012
1013/**
1014 * Removes all of the items from the receiver.
1015 * <p>
1016 * @exception SWTException <ul>
1017 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1018 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1019 * </ul>
1020 *
1021 * @since 3.1
1022 */

1023public void removeAll () {
1024    checkWidget ();
1025    int hwnd = parent.handle;
1026    TVITEM tvItem = new TVITEM ();
1027    tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;
1028    tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
1029    while (tvItem.hItem != 0) {
1030        OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
1031        TreeItem item = tvItem.lParam != -1 ? parent.items [tvItem.lParam] : null;
1032        if (item != null && !item.isDisposed ()) {
1033            item.dispose ();
1034        } else {
1035            parent.releaseItem (tvItem.hItem, tvItem, false);
1036            parent.destroyItem (null, tvItem.hItem);
1037        }
1038        tvItem.hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
1039    }
1040}
1041
1042/**
1043 * Sets the receiver's background color to the color specified
1044 * by the argument, or to the default system color for the item
1045 * if the argument is null.
1046 *
1047 * @param color the new color (or null)
1048 *
1049 * @exception IllegalArgumentException <ul>
1050 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1051 * </ul>
1052 * @exception SWTException <ul>
1053 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1054 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1055 * </ul>
1056 *
1057 * @since 2.0
1058 *
1059 */

1060public void setBackground (Color color) {
1061    checkWidget ();
1062    if (color != null && color.isDisposed ()) {
1063        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1064    }
1065    int pixel = -1;
1066    if (color != null) {
1067        parent.customDraw = true;
1068        pixel = color.handle;
1069    }
1070    if (background == pixel) return;
1071    background = pixel;
1072    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1073    redraw ();
1074}
1075
1076/**
1077 * Sets the background color at the given column index in the receiver
1078 * to the color specified by the argument, or to the default system color for the item
1079 * if the argument is null.
1080 *
1081 * @param index the column index
1082 * @param color the new color (or null)
1083 *
1084 * @exception IllegalArgumentException <ul>
1085 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1086 * </ul>
1087 * @exception SWTException <ul>
1088 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1089 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1090 * </ul>
1091 *
1092 * @since 3.1
1093 *
1094 */

1095public void setBackground (int index, Color color) {
1096    checkWidget ();
1097    if (color != null && color.isDisposed ()) {
1098        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1099    }
1100    int count = Math.max (1, parent.getColumnCount ());
1101    if (0 > index || index > count - 1) return;
1102    int pixel = -1;
1103    if (color != null) {
1104        parent.customDraw = true;
1105        pixel = color.handle;
1106    }
1107    if (cellBackground == null) {
1108        cellBackground = new int [count];
1109        for (int i = 0; i < count; i++) {
1110            cellBackground [i] = -1;
1111        }
1112    }
1113    if (cellBackground [index] == pixel) return;
1114    cellBackground [index] = pixel;
1115    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1116    redraw (index, true, true);
1117}
1118
1119/**
1120 * Sets the checked state of the receiver.
1121 * <p>
1122 *
1123 * @param checked the new checked state
1124 *
1125 * @exception SWTException <ul>
1126 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1127 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1128 * </ul>
1129 */

1130public void setChecked (boolean checked) {
1131    checkWidget ();
1132    if ((parent.style & SWT.CHECK) == 0) return;
1133    int hwnd = parent.handle;
1134    TVITEM tvItem = new TVITEM ();
1135    tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
1136    tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
1137    tvItem.hItem = handle;
1138    OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
1139    int state = tvItem.state >> 12;
1140    if (checked) {
1141        if ((state & 0x1) != 0) state++;
1142    } else {
1143        if ((state & 0x1) == 0) --state;
1144    }
1145    state <<= 12;
1146    if (tvItem.state == state) return;
1147    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1148    tvItem.state = state;
1149    OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1150    /*
1151    * Bug in Windows. When TVM_SETITEM is used to set
1152    * the state image of an item inside TVN_GETDISPINFO,
1153    * the new state is not redrawn. The fix is to force
1154    * a redraw.
1155    */

1156    if ((parent.style & SWT.VIRTUAL) != 0) {
1157        if (parent.currentItem == this && OS.IsWindowVisible (hwnd)) {
1158            RECT rect = new RECT ();
1159            rect.left = handle;
1160            if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) != 0) {
1161                OS.InvalidateRect (hwnd, rect, true);
1162            }
1163        }
1164    }
1165}
1166
1167/**
1168 * Sets the expanded state of the receiver.
1169 * <p>
1170 *
1171 * @param expanded the new expanded state
1172 *
1173 * @exception SWTException <ul>
1174 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1175 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1176 * </ul>
1177 */

1178public void setExpanded (boolean expanded) {
1179    checkWidget ();
1180    
1181    /* Do nothing when the item is a leaf or already expanded */
1182    int hwnd = parent.handle;
1183    if (OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle) == 0) {
1184        return;
1185    }
1186    int state = 0;
1187    if (OS.IsWinCE) {
1188        TVITEM tvItem = new TVITEM ();
1189        tvItem.hItem = handle;
1190        tvItem.mask = OS.TVIF_STATE;
1191        OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
1192        state = tvItem.state;
1193    } else {
1194        /*
1195        * Bug in Windows. Despite the fact that TVM_GETITEMSTATE claims
1196        * to return only the bits specified by the stateMask, when called
1197        * with TVIS_EXPANDED, the entire state is returned. The fix is
1198        * to explicitly check for the TVIS_EXPANDED bit.
1199        */

1200        state = OS.SendMessage (hwnd, OS.TVM_GETITEMSTATE, handle, OS.TVIS_EXPANDED);
1201    }
1202    if (((state & OS.TVIS_EXPANDED) != 0) == expanded) return;
1203    
1204    /*
1205    * Feature in Windows. When TVM_EXPAND is used to expand
1206    * an item, the widget scrolls to show the item and the
1207    * newly expanded items. While not strictly incorrect,
1208    * this means that application code that expands tree items
1209    * in a background thread can scroll the widget while the
1210    * user is interacting with it. The fix is to remember
1211    * the top item and the bounds of every tree item, turn
1212    * redraw off, expand the item, scroll back to the top
1213    * item. If none of the rectangles have moved, then
1214    * it is safe to turn redraw back on without redrawing
1215    * the control.
1216    */

1217    RECT oldRect = null;
1218    RECT [] rects = null;
1219    SCROLLINFO oldInfo = null;
1220    int count = 0, hBottomItem = 0;
1221    boolean redraw = false, noScroll = true;
1222    int hTopItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0);
1223    if (noScroll && hTopItem != 0) {
1224        oldInfo = new SCROLLINFO ();
1225        oldInfo.cbSize = SCROLLINFO.sizeof;
1226        oldInfo.fMask = OS.SIF_ALL;
1227        if (!OS.GetScrollInfo (hwnd, OS.SB_HORZ, oldInfo)) {
1228            oldInfo = null;
1229        }
1230        if (parent.drawCount == 0 && OS.IsWindowVisible (hwnd)) {
1231            boolean noAnimate = true;
1232            count = OS.SendMessage (hwnd, OS.TVM_GETVISIBLECOUNT, 0, 0);
1233            rects = new RECT [count + 1];
1234            int hItem = hTopItem, index = 0;
1235            while (hItem != 0 && (noAnimate || hItem != handle) && index < count) {
1236                RECT rect = new RECT ();
1237                rect.left = hItem;
1238                if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 1, rect) != 0) {
1239                    rects [index++] = rect;
1240                }
1241                hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem);
1242            }
1243            if (noAnimate || hItem != handle) {
1244                redraw = true;
1245                count = index;
1246                hBottomItem = hItem;
1247                oldRect = new RECT ();
1248                OS.GetClientRect (hwnd, oldRect);
1249                int topHandle = parent.topHandle ();
1250                OS.UpdateWindow (topHandle);
1251                OS.DefWindowProc (topHandle, OS.WM_SETREDRAW, 0, 0);
1252                if (hwnd != topHandle) {
1253                    OS.UpdateWindow (hwnd);
1254                    OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 0, 0);
1255                }
1256                /*
1257                * This code is intentionally commented.
1258                */

1259// OS.SendMessage (hwnd, OS.WM_SETREDRAW, 0, 0);
1260
}
1261        }
1262    }
1263    
1264    /*
1265    * Feature in Windows. When the user collapses the root
1266    * of a subtree that has the focus item, Windows moves
1267    * the selection to the root of the subtree and issues
1268    * a TVN_SELCHANGED to inform the programmer that the
1269    * selection has changed. When the programmer collapses
1270    * the same subtree using TVM_EXPAND, Windows does not
1271    * send the selection changed notification. This is not
1272    * strictly wrong but is inconsistent. The fix is to
1273    * check whether the selection has changed and issue
1274    * the event.
1275    */

1276    int hOldItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);
1277    
1278    /* Expand or collapse the item */
1279    parent.ignoreExpand = true;
1280    OS.SendMessage (hwnd, OS.TVM_EXPAND, expanded ? OS.TVE_EXPAND : OS.TVE_COLLAPSE, handle);
1281    parent.ignoreExpand = false;
1282    
1283    /* Scroll back to the top item */
1284    if (noScroll && hTopItem != 0) {
1285        boolean collapsed = false;
1286        if (!expanded) {
1287            RECT rect = new RECT ();
1288            rect.left = hTopItem;
1289            while (hTopItem != 0 && OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) == 0) {
1290                hTopItem = rect.left = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hTopItem);
1291                collapsed = true;
1292            }
1293        }
1294        boolean scrolled = true;
1295        if (hTopItem != 0) {
1296            OS.SendMessage (hwnd, OS.TVM_SELECTITEM, OS.TVGN_FIRSTVISIBLE, hTopItem);
1297            scrolled = hTopItem != OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0);
1298        }
1299        if (!collapsed && !scrolled && oldInfo != null) {
1300            SCROLLINFO newInfo = new SCROLLINFO ();
1301            newInfo.cbSize = SCROLLINFO.sizeof;
1302            newInfo.fMask = OS.SIF_ALL;
1303            if (OS.GetScrollInfo (hwnd, OS.SB_HORZ, newInfo)) {
1304                if (oldInfo.nPos != newInfo.nPos) {
1305                    int lParam = OS.SB_THUMBPOSITION | ((oldInfo.nPos << 16) & 0xFFFF0000);
1306                    OS.SendMessage (hwnd, OS.WM_HSCROLL, lParam, 0);
1307                }
1308            }
1309        }
1310        if (redraw) {
1311            boolean fixScroll = false;
1312            if (!collapsed && !scrolled) {
1313                RECT newRect = new RECT ();
1314                OS.GetClientRect (hwnd, newRect);
1315                if (OS.EqualRect (oldRect, newRect)) {
1316                    int hItem = hTopItem, index = 0;
1317                    while (hItem != 0 && index < count) {
1318                        RECT rect = new RECT ();
1319                        rect.left = hItem;
1320                        if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 1, rect) != 0) {
1321                            if (!OS.EqualRect (rect, rects [index])) {
1322                                break;
1323                            }
1324                        }
1325                        hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem);
1326                        index++;
1327                    }
1328                    fixScroll = index == count && hItem == hBottomItem;
1329                }
1330            }
1331            int topHandle = parent.topHandle ();
1332            OS.DefWindowProc (topHandle, OS.WM_SETREDRAW, 1, 0);
1333            if (hwnd != topHandle) {
1334                OS.DefWindowProc (hwnd, OS.WM_SETREDRAW, 1, 0);
1335            }
1336            /*
1337            * This code is intentionally commented.
1338            */

1339// OS.SendMessage (hwnd, OS.WM_SETREDRAW, 1, 0);
1340
if (fixScroll) {
1341                parent.updateScrollBar ();
1342                SCROLLINFO info = new SCROLLINFO ();
1343                info.cbSize = SCROLLINFO.sizeof;
1344                info.fMask = OS.SIF_ALL;
1345                if (OS.GetScrollInfo (hwnd, OS.SB_VERT, info)) {
1346                    OS.SetScrollInfo (hwnd, OS.SB_VERT, info, true);
1347                }
1348                if (handle == hBottomItem) {
1349                    RECT rect = new RECT ();
1350                    rect.left = hBottomItem;
1351                    if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) != 0) {
1352                        OS.InvalidateRect (hwnd, rect, true);
1353                    }
1354                }
1355            } else {
1356                if (OS.IsWinCE) {
1357                    OS.InvalidateRect (topHandle, null, true);
1358                    if (hwnd != topHandle) OS.InvalidateRect (hwnd, null, true);
1359                } else {
1360                    int flags = OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE | OS.RDW_ALLCHILDREN;
1361                    OS.RedrawWindow (topHandle, null, 0, flags);
1362                }
1363            }
1364        }
1365    }
1366
1367    /* Check for a selection event */
1368    int hNewItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);
1369    if (hNewItem != hOldItem) {
1370        Event event = new Event ();
1371        if (hNewItem != 0) {
1372            event.item = parent._getItem (hNewItem);
1373            parent.hAnchor = hNewItem;
1374        }
1375        parent.sendEvent (SWT.Selection, event);
1376    }
1377}
1378
1379/**
1380 * Sets the font that the receiver will use to paint textual information
1381 * for this item to the font specified by the argument, or to the default font
1382 * for that kind of control if the argument is null.
1383 *
1384 * @param font the new font (or null)
1385 *
1386 * @exception IllegalArgumentException <ul>
1387 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1388 * </ul>
1389 * @exception SWTException <ul>
1390 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1391 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1392 * </ul>
1393 *
1394 * @since 3.0
1395 */

1396public void setFont (Font font){
1397    checkWidget ();
1398    if (font != null && font.isDisposed ()) {
1399        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1400    }
1401    int hFont = -1;
1402    if (font != null) {
1403        parent.customDraw = true;
1404        hFont = font.handle;
1405    }
1406    if (this.font == hFont) return;
1407    this.font = hFont;
1408    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1409    /*
1410    * Bug in Windows. When the font is changed for an item,
1411    * the bounds for the item are not updated, causing the text
1412    * to be clipped. The fix is to reset the text, causing
1413    * Windows to compute the new bounds using the new font.
1414    */

1415    if ((parent.style & SWT.VIRTUAL) == 0 && !cached && !parent.painted) {
1416        return;
1417    }
1418    int hwnd = parent.handle;
1419    TVITEM tvItem = new TVITEM ();
1420    tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT;
1421    tvItem.hItem = handle;
1422    tvItem.pszText = OS.LPSTR_TEXTCALLBACK;
1423    OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1424}
1425
1426
1427/**
1428 * Sets the font that the receiver will use to paint textual information
1429 * for the specified cell in this item to the font specified by the
1430 * argument, or to the default font for that kind of control if the
1431 * argument is null.
1432 *
1433 * @param index the column index
1434 * @param font the new font (or null)
1435 *
1436 * @exception IllegalArgumentException <ul>
1437 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1438 * </ul>
1439 * @exception SWTException <ul>
1440 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1441 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1442 * </ul>
1443 *
1444 * @since 3.1
1445 */

1446public void setFont (int index, Font font) {
1447    checkWidget ();
1448    if (font != null && font.isDisposed ()) {
1449        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1450    }
1451    int count = Math.max (1, parent.getColumnCount ());
1452    if (0 > index || index > count - 1) return;
1453    int hFont = -1;
1454    if (font != null) {
1455        parent.customDraw = true;
1456        hFont = font.handle;
1457    }
1458    if (cellFont == null) {
1459        cellFont = new int [count];
1460        for (int i = 0; i < count; i++) {
1461            cellFont [i] = -1;
1462        }
1463    }
1464    if (cellFont [index] == hFont) return;
1465    cellFont [index] = hFont;
1466    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1467    /*
1468    * Bug in Windows. When the font is changed for an item,
1469    * the bounds for the item are not updated, causing the text
1470    * to be clipped. The fix is to reset the text, causing
1471    * Windows to compute the new bounds using the new font.
1472    */

1473    if (index == 0) {
1474        if ((parent.style & SWT.VIRTUAL) == 0 && !cached && !parent.painted) {
1475            return;
1476        }
1477        int hwnd = parent.handle;
1478        TVITEM tvItem = new TVITEM ();
1479        tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT;
1480        tvItem.hItem = handle;
1481        tvItem.pszText = OS.LPSTR_TEXTCALLBACK;
1482        OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1483    } else {
1484        redraw (index, true, false);
1485    }
1486}
1487
1488/**
1489 * Sets the receiver's foreground color to the color specified
1490 * by the argument, or to the default system color for the item
1491 * if the argument is null.
1492 *
1493 * @param color the new color (or null)
1494 *
1495 * @since 2.0
1496 *
1497 * @exception IllegalArgumentException <ul>
1498 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1499 * </ul>
1500 * @exception SWTException <ul>
1501 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1502 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1503 * </ul>
1504 *
1505 * @since 2.0
1506 *
1507 */

1508public void setForeground (Color color) {
1509    checkWidget ();
1510    if (color != null && color.isDisposed ()) {
1511        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1512    }
1513    int pixel = -1;
1514    if (color != null) {
1515        parent.customDraw = true;
1516        pixel = color.handle;
1517    }
1518    if (foreground == pixel) return;
1519    foreground = pixel;
1520    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1521    redraw ();
1522}
1523
1524/**
1525 * Sets the foreground color at the given column index in the receiver
1526 * to the color specified by the argument, or to the default system color for the item
1527 * if the argument is null.
1528 *
1529 * @param index the column index
1530 * @param color the new color (or null)
1531 *
1532 * @exception IllegalArgumentException <ul>
1533 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
1534 * </ul>
1535 * @exception SWTException <ul>
1536 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1537 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1538 * </ul>
1539 *
1540 * @since 3.1
1541 *
1542 */

1543public void setForeground (int index, Color color){
1544    checkWidget ();
1545    if (color != null && color.isDisposed ()) {
1546        SWT.error (SWT.ERROR_INVALID_ARGUMENT);
1547    }
1548    int count = Math.max (1, parent.getColumnCount ());
1549    if (0 > index || index > count - 1) return;
1550    int pixel = -1;
1551    if (color != null) {
1552        parent.customDraw = true;
1553        pixel = color.handle;
1554    }
1555    if (cellForeground == null) {
1556        cellForeground = new int [count];
1557        for (int i = 0; i < count; i++) {
1558            cellForeground [i] = -1;
1559        }
1560    }
1561    if (cellForeground [index] == pixel) return;
1562    cellForeground [index] = pixel;
1563    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1564    redraw (index, true, false);
1565}
1566
1567/**
1568 * Sets the grayed state of the checkbox for this item. This state change
1569 * only applies if the Tree was created with the SWT.CHECK style.
1570 *
1571 * @param grayed the new grayed state of the checkbox
1572 *
1573 * @exception SWTException <ul>
1574 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1575 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1576 * </ul>
1577 */

1578public void setGrayed (boolean grayed) {
1579    checkWidget ();
1580    if ((parent.style & SWT.CHECK) == 0) return;
1581    int hwnd = parent.handle;
1582    TVITEM tvItem = new TVITEM ();
1583    tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
1584    tvItem.stateMask = OS.TVIS_STATEIMAGEMASK;
1585    tvItem.hItem = handle;
1586    OS.SendMessage (hwnd, OS.TVM_GETITEM, 0, tvItem);
1587    int state = tvItem.state >> 12;
1588    if (grayed) {
1589        if (state <= 2) state +=2;
1590    } else {
1591        if (state > 2) state -=2;
1592    }
1593    state <<= 12;
1594    if (tvItem.state == state) return;
1595    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1596    tvItem.state = state;
1597    OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1598    /*
1599    * Bug in Windows. When TVM_SETITEM is used to set
1600    * the state image of an item inside TVN_GETDISPINFO,
1601    * the new state is not redrawn. The fix is to force
1602    * a redraw.
1603    */

1604    if ((parent.style & SWT.VIRTUAL) != 0) {
1605        if (parent.currentItem == this && OS.IsWindowVisible (hwnd)) {
1606            RECT rect = new RECT ();
1607            rect.left = handle;
1608            if (OS.SendMessage (hwnd, OS.TVM_GETITEMRECT, 0, rect) != 0) {
1609                OS.InvalidateRect (hwnd, rect, true);
1610            }
1611        }
1612    }
1613}
1614
1615/**
1616 * Sets the image for multiple columns in the tree.
1617 *
1618 * @param images the array of new images
1619 *
1620 * @exception IllegalArgumentException <ul>
1621 * <li>ERROR_NULL_ARGUMENT - if the array of images is null</li>
1622 * <li>ERROR_INVALID_ARGUMENT - if one of the images has been disposed</li>
1623 * </ul>
1624 * @exception SWTException <ul>
1625 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1626 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1627 * </ul>
1628 *
1629 * @since 3.1
1630 */

1631public void setImage (Image [] images) {
1632    checkWidget();
1633    if (images == null) error (SWT.ERROR_NULL_ARGUMENT);
1634    for (int i=0; i<images.length; i++) {
1635        setImage (i, images [i]);
1636    }
1637}
1638
1639/**
1640 * Sets the receiver's image at a column.
1641 *
1642 * @param index the column index
1643 * @param image the new image
1644 *
1645 * @exception IllegalArgumentException <ul>
1646 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
1647 * </ul>
1648 * @exception SWTException <ul>
1649 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1650 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1651 * </ul>
1652 *
1653 * @since 3.1
1654 */

1655public void setImage (int index, Image image) {
1656    checkWidget();
1657    if (image != null && image.isDisposed ()) {
1658        error(SWT.ERROR_INVALID_ARGUMENT);
1659    }
1660    Image oldImage = null;
1661    if (index == 0) {
1662        if (image != null && image.type == SWT.ICON) {
1663            if (image.equals (this.image)) return;
1664        }
1665        oldImage = this.image;
1666        super.setImage (image);
1667    }
1668    int count = Math.max (1, parent.getColumnCount ());
1669    if (0 > index || index > count - 1) return;
1670    if (images == null && index != 0) {
1671        images = new Image [count];
1672        images [0] = image;
1673    }
1674    if (images != null) {
1675        if (image != null && image.type == SWT.ICON) {
1676            if (image.equals (images [index])) return;
1677        }
1678        oldImage = images [index];
1679        images [index] = image;
1680    }
1681    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1682    
1683    /* Ensure that the image list is created */
1684    //TODO - items that are not in column zero don't need to be in the image list
1685
parent.imageIndex (image, index);
1686    
1687    if (index == 0) {
1688        if ((parent.style & SWT.VIRTUAL) == 0 &&!cached && !parent.painted) {
1689            return;
1690        }
1691        int hwnd = parent.handle;
1692        TVITEM tvItem = new TVITEM ();
1693        tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_IMAGE | OS.TVIF_SELECTEDIMAGE;
1694        tvItem.hItem = handle;
1695        tvItem.iImage = tvItem.iSelectedImage = OS.I_IMAGECALLBACK;
1696        /*
1697        * Bug in Windows. When I_IMAGECALLBACK is used with TVM_SETITEM
1698        * to indicate that an image has changed, Windows does not draw
1699        * the new image. The fix is to use LPSTR_TEXTCALLBACK to force
1700        * Windows to ask for the text, causing Windows to ask for both.
1701        */

1702        tvItem.mask |= OS.TVIF_TEXT;
1703        tvItem.pszText = OS.LPSTR_TEXTCALLBACK;
1704        OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1705    } else {
1706        boolean drawText = (image == null && oldImage != null) || (image != null && oldImage == null);
1707        redraw (index, drawText, true);
1708    }
1709}
1710
1711public void setImage (Image image) {
1712    checkWidget ();
1713    setImage (0, image);
1714}
1715
1716/**
1717 * Sets the number of child items contained in the receiver.
1718 *
1719 * @param count the number of items
1720 *
1721 * @exception SWTException <ul>
1722 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1723 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1724 * </ul>
1725 *
1726 * @since 3.2
1727 */

1728public void setItemCount (int count) {
1729    checkWidget ();
1730    count = Math.max (0, count);
1731    int hwnd = parent.handle;
1732    int hItem = OS.SendMessage (hwnd, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, handle);
1733    parent.setItemCount (count, handle, hItem);
1734}
1735
1736/**
1737 * Sets the text for multiple columns in the tree.
1738 *
1739 * @param strings the array of new strings
1740 *
1741 * @exception IllegalArgumentException <ul>
1742 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
1743 * </ul>
1744 * @exception SWTException <ul>
1745 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1746 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1747 * </ul>
1748 *
1749 * @since 3.1
1750 */

1751public void setText (String JavaDoc [] strings) {
1752    checkWidget();
1753    if (strings == null) error (SWT.ERROR_NULL_ARGUMENT);
1754    for (int i=0; i<strings.length; i++) {
1755        String JavaDoc string = strings [i];
1756        if (string != null) setText (i, string);
1757    }
1758}
1759
1760/**
1761 * Sets the receiver's text at a column
1762 *
1763 * @param index the column index
1764 * @param string the new text
1765 *
1766 * @exception IllegalArgumentException <ul>
1767 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
1768 * </ul>
1769 * @exception SWTException <ul>
1770 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1771 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1772 * </ul>
1773 *
1774 * @since 3.1
1775 */

1776public void setText (int index, String JavaDoc string) {
1777    checkWidget();
1778    if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1779    if (index == 0) {
1780        if (string.equals (text)) return;
1781        super.setText (string);
1782    }
1783    int count = Math.max (1, parent.getColumnCount ());
1784    if (0 > index || index > count - 1) return;
1785    if (strings == null && index != 0) {
1786        strings = new String JavaDoc [count];
1787        strings [0] = text;
1788    }
1789    if (strings != null) {
1790        if (string.equals (strings [index])) return;
1791        strings [index] = string;
1792    }
1793    if ((parent.style & SWT.VIRTUAL) != 0) cached = true;
1794    if (index == 0) {
1795        if ((parent.style & SWT.VIRTUAL) == 0 && !cached && !parent.painted) {
1796            return;
1797        }
1798        int hwnd = parent.handle;
1799        TVITEM tvItem = new TVITEM ();
1800        tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_TEXT;
1801        tvItem.hItem = handle;
1802        tvItem.pszText = OS.LPSTR_TEXTCALLBACK;
1803        OS.SendMessage (hwnd, OS.TVM_SETITEM, 0, tvItem);
1804    } else {
1805        redraw (index, true, false);
1806    }
1807}
1808
1809public void setText (String JavaDoc string) {
1810    checkWidget();
1811    setText (0, string);
1812}
1813
1814/*public*/ void sort () {
1815    checkWidget ();
1816    if ((parent.style & SWT.VIRTUAL) != 0) return;
1817    parent.sort (handle, false);
1818}
1819
1820}
1821
Popular Tags