KickJava   Java API By Example, From Geeks To Geeks.

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


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 import org.eclipse.swt.events.*;
18
19 /**
20  * Instances of this class represent a column in a table widget.
21  * <p><dl>
22  * <dt><b>Styles:</b></dt>
23  * <dd>LEFT, RIGHT, CENTER</dd>
24  * <dt><b>Events:</b></dt>
25  * <dd> Move, Resize, Selection</dd>
26  * </dl>
27  * </p><p>
28  * Note: Only one of the styles LEFT, RIGHT and CENTER may be specified.
29  * </p><p>
30  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
31  * </p>
32  */

33 public class TableColumn extends Item {
34     Table parent;
35     boolean resizable, moveable;
36     String JavaDoc toolTipText;
37     int id;
38
39 /**
40  * Constructs a new instance of this class given its parent
41  * (which must be a <code>Table</code>) and a style value
42  * describing its behavior and appearance. The item is added
43  * to the end of the items maintained by its parent.
44  * <p>
45  * The style value is either one of the style constants defined in
46  * class <code>SWT</code> which is applicable to instances of this
47  * class, or must be built by <em>bitwise OR</em>'ing together
48  * (that is, using the <code>int</code> "|" operator) two or more
49  * of those <code>SWT</code> style constants. The class description
50  * lists the style constants that are applicable to the class.
51  * Style bits are also inherited from superclasses.
52  * </p>
53  *
54  * @param parent a composite control which will be the parent of the new instance (cannot be null)
55  * @param style the style of control to construct
56  *
57  * @exception IllegalArgumentException <ul>
58  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
59  * </ul>
60  * @exception SWTException <ul>
61  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
62  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
63  * </ul>
64  *
65  * @see SWT#LEFT
66  * @see SWT#RIGHT
67  * @see SWT#CENTER
68  * @see Widget#checkSubclass
69  * @see Widget#getStyle
70  */

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

112 public TableColumn (Table parent, int style, int index) {
113     super (parent, checkStyle (style));
114     resizable = true;
115     this.parent = parent;
116     parent.createItem (this, index);
117 }
118
119 /**
120  * Adds the listener to the collection of listeners who will
121  * be notified when the control is moved or resized, by sending
122  * it one of the messages defined in the <code>ControlListener</code>
123  * interface.
124  *
125  * @param listener the listener which should be notified
126  *
127  * @exception IllegalArgumentException <ul>
128  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
129  * </ul>
130  * @exception SWTException <ul>
131  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
132  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
133  * </ul>
134  *
135  * @see ControlListener
136  * @see #removeControlListener
137  */

138 public void addControlListener(ControlListener listener) {
139     checkWidget ();
140     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
141     TypedListener typedListener = new TypedListener (listener);
142     addListener (SWT.Resize,typedListener);
143     addListener (SWT.Move,typedListener);
144 }
145
146 /**
147  * Adds the listener to the collection of listeners who will
148  * be notified when the control is selected by the user, by sending
149  * it one of the messages defined in the <code>SelectionListener</code>
150  * interface.
151  * <p>
152  * <code>widgetSelected</code> is called when the column header is selected.
153  * <code>widgetDefaultSelected</code> is not called.
154  * </p>
155  *
156  * @param listener the listener which should be notified when the control is selected by the user
157  *
158  * @exception IllegalArgumentException <ul>
159  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
160  * </ul>
161  * @exception SWTException <ul>
162  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
163  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
164  * </ul>
165  *
166  * @see SelectionListener
167  * @see #removeSelectionListener
168  * @see SelectionEvent
169  */

170 public void addSelectionListener (SelectionListener listener) {
171     checkWidget ();
172     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
173     TypedListener typedListener = new TypedListener (listener);
174     addListener (SWT.Selection,typedListener);
175     addListener (SWT.DefaultSelection,typedListener);
176 }
177
178 static int checkStyle (int style) {
179     return checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
180 }
181
182 protected void checkSubclass () {
183     if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
184 }
185
186 void destroyWidget () {
187     parent.destroyItem (this);
188     releaseHandle ();
189 }
190
191 /**
192  * Returns a value which describes the position of the
193  * text or image in the receiver. The value will be one of
194  * <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.
195  *
196  * @return the alignment
197  *
198  * @exception SWTException <ul>
199  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
200  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
201  * </ul>
202  */

203 public int getAlignment () {
204     checkWidget ();
205     if ((style & SWT.LEFT) != 0) return SWT.LEFT;
206     if ((style & SWT.CENTER) != 0) return SWT.CENTER;
207     if ((style & SWT.RIGHT) != 0) return SWT.RIGHT;
208     return SWT.LEFT;
209 }
210
211 String JavaDoc getNameText () {
212     return getText ();
213 }
214
215 /**
216  * Returns the receiver's parent, which must be a <code>Table</code>.
217  *
218  * @return the receiver's parent
219  *
220  * @exception SWTException <ul>
221  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
222  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
223  * </ul>
224  */

225 public Table getParent () {
226     checkWidget ();
227     return parent;
228 }
229
230 /**
231  * Gets the moveable attribute. A column that is
232  * not moveable cannot be reordered by the user
233  * by dragging the header but may be reordered
234  * by the programmer.
235  *
236  * @return the moveable attribute
237  *
238  * @exception SWTException <ul>
239  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
240  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
241  * </ul>
242  *
243  * @see Table#getColumnOrder()
244  * @see Table#setColumnOrder(int[])
245  * @see TableColumn#setMoveable(boolean)
246  * @see SWT#Move
247  *
248  * @since 3.1
249  */

250 public boolean getMoveable () {
251     checkWidget ();
252     return moveable;
253 }
254
255 /**
256  * Gets the resizable attribute. A column that is
257  * not resizable cannot be dragged by the user but
258  * may be resized by the programmer.
259  *
260  * @return the resizable attribute
261  *
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 public boolean getResizable () {
268     checkWidget ();
269     return resizable;
270 }
271
272 /**
273  * Returns the receiver's tool tip text, or null if it has
274  * not been set.
275  *
276  * @return the receiver's tool tip text
277  *
278  * @exception SWTException <ul>
279  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
280  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
281  * </ul>
282  *
283  * @since 3.2
284  */

285 public String JavaDoc getToolTipText () {
286     checkWidget();
287     return toolTipText;
288 }
289
290 /**
291  * Gets the width of the receiver.
292  *
293  * @return the width
294  *
295  * @exception SWTException <ul>
296  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
297  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
298  * </ul>
299  */

300 public int getWidth () {
301     checkWidget ();
302     int index = parent.indexOf (this);
303     if (index == -1) return 0;
304     int hwnd = parent.handle;
305     return OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
306 }
307
308 /**
309  * Causes the receiver to be resized to its preferred size.
310  * For a composite, this involves computing the preferred size
311  * from its layout, if there is one.
312  *
313  * @exception SWTException <ul>
314  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
315  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
316  * </ul>
317  *
318  */

319 public void pack () {
320     checkWidget ();
321     int index = parent.indexOf (this);
322     if (index == -1) return;
323     int hwnd = parent.handle;
324     int oldWidth = OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
325     TCHAR buffer = new TCHAR (parent.getCodePage (), text, true);
326     int headerWidth = OS.SendMessage (hwnd, OS.LVM_GETSTRINGWIDTH, 0, buffer) + Table.HEADER_MARGIN;
327     if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) headerWidth += Table.HEADER_EXTRA;
328     boolean hasHeaderImage = false;
329     if (image != null || parent.sortColumn == this) {
330         hasHeaderImage = true;
331         Image headerImage = null;
332         if (parent.sortColumn == this && parent.sortDirection != SWT.NONE) {
333             if (OS.COMCTL32_MAJOR < 6) {
334                 headerImage = display.getSortImage (parent.sortDirection);
335             } else {
336                 headerWidth += Table.SORT_WIDTH;
337             }
338         } else {
339             headerImage = image;
340         }
341         if (headerImage != null) {
342             Rectangle bounds = headerImage.getBounds ();
343             headerWidth += bounds.width;
344         }
345         int margin = 0;
346         if (OS.COMCTL32_VERSION >= OS.VERSION (5, 80)) {
347             int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
348             margin = OS.SendMessage (hwndHeader, OS.HDM_GETBITMAPMARGIN, 0, 0);
349         } else {
350             margin = OS.GetSystemMetrics (OS.SM_CXEDGE) * 3;
351         }
352         headerWidth += margin * 4;
353     }
354     parent.ignoreColumnResize = true;
355     int columnWidth = 0;
356     /*
357     * Bug in Windows. When the first column of a table does not
358     * have an image and the user double clicks on the divider,
359     * Windows packs the column but does not take into account
360     * the empty space left for the image. The fix is to measure
361     * each items ourselves rather than letting Windows do it.
362     */

363     if ((index == 0 && !parent.firstColumnImage) || parent.hooks (SWT.MeasureItem)) {
364         RECT headerRect = new RECT ();
365         int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
366         OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
367         OS.MapWindowPoints (hwndHeader, hwnd, headerRect, 2);
368         int hDC = OS.GetDC (hwnd);
369         int oldFont = 0, newFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0);
370         if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
371         int count = OS.SendMessage (hwnd, OS.LVM_GETITEMCOUNT, 0, 0);
372         for (int i=0; i<count; i++) {
373             TableItem item = parent.items [i];
374             if (item != null) {
375                 int hFont = item.cellFont != null ? item.cellFont [index] : -1;
376                 if (hFont == -1) hFont = item.font;
377                 if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
378                 Event event = parent.sendMeasureItemEvent (item, i, index, hDC);
379                 if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
380                 if (isDisposed () || parent.isDisposed ()) break;
381                 columnWidth = Math.max (columnWidth, event.x + event.width - headerRect.left);
382             }
383         }
384         if (newFont != 0) OS.SelectObject (hDC, oldFont);
385         OS.ReleaseDC (hwnd, hDC);
386         OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, columnWidth);
387     } else {
388         OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, OS.LVSCW_AUTOSIZE);
389         columnWidth = OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
390         if (index == 0) {
391             /*
392             * Bug in Windows. When LVM_SETCOLUMNWIDTH is used with LVSCW_AUTOSIZE
393             * where each item has I_IMAGECALLBACK but there are no images in the
394             * table, the size computed by LVM_SETCOLUMNWIDTH is too small for the
395             * first column, causing long items to be clipped with '...'. The fix
396             * is to increase the column width by a small amount.
397             */

398             if (parent.imageList == null) columnWidth += 2;
399             /*
400             * Bug in Windows. When LVM_SETCOLUMNWIDTH is used with LVSCW_AUTOSIZE
401             * for a table with a state image list, the column is width does not
402             * include space for the state icon. The fix is to increase the column
403             * width by the width of the image list.
404             */

405             if ((parent.style & SWT.CHECK) != 0) {
406                 int hStateList = OS.SendMessage (hwnd, OS.LVM_GETIMAGELIST, OS.LVSIL_STATE, 0);
407                 if (hStateList != 0) {
408                     int [] cx = new int [1], cy = new int [1];
409                     OS.ImageList_GetIconSize (hStateList, cx, cy);
410                     columnWidth += cx [0];
411                 }
412             }
413         }
414     }
415     if (headerWidth > columnWidth) {
416         if (!hasHeaderImage) {
417             /*
418             * Feature in Windows. When LVSCW_AUTOSIZE_USEHEADER is used
419             * with LVM_SETCOLUMNWIDTH to resize the last column, the last
420             * column is expanded to fill the client area. The fix is to
421             * resize the table to be small, set the column width and then
422             * restore the table to its original size.
423             */

424             RECT rect = null;
425             boolean fixWidth = index == parent.getColumnCount () - 1;
426             if (fixWidth) {
427                 rect = new RECT ();
428                 OS.GetWindowRect (hwnd, rect);
429                 OS.UpdateWindow (hwnd);
430                 int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOREDRAW | OS.SWP_NOZORDER;
431                 SetWindowPos (hwnd, 0, 0, 0, 0, rect.bottom - rect.top, flags);
432             }
433             OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, OS.LVSCW_AUTOSIZE_USEHEADER);
434             if (fixWidth) {
435                 int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOZORDER;
436                 SetWindowPos (hwnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags);
437             }
438         } else {
439             OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, headerWidth);
440         }
441     } else {
442         if (index == 0) {
443             OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, columnWidth);
444         }
445     }
446     parent.ignoreColumnResize = false;
447     int newWidth = OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
448     if (oldWidth != newWidth) {
449         updateToolTip (index);
450         sendEvent (SWT.Resize);
451         if (isDisposed ()) return;
452         boolean moved = false;
453         int [] order = parent.getColumnOrder ();
454         TableColumn [] columns = parent.getColumns ();
455         for (int i=0; i<order.length; i++) {
456             TableColumn column = columns [order [i]];
457             if (moved && !column.isDisposed ()) {
458                 column.updateToolTip (order [i]);
459                 column.sendEvent (SWT.Move);
460             }
461             if (column == this) moved = true;
462         }
463     }
464 }
465
466 void releaseHandle () {
467     super.releaseHandle ();
468     parent = null;
469 }
470
471 void releaseParent () {
472     super.releaseParent ();
473     if (parent.sortColumn == this) {
474         parent.sortColumn = null;
475     }
476 }
477
478 /**
479  * Removes the listener from the collection of listeners who will
480  * be notified when the control is moved or resized.
481  *
482  * @param listener the listener which should no longer be notified
483  *
484  * @exception IllegalArgumentException <ul>
485  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
486  * </ul>
487  * @exception SWTException <ul>
488  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
489  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
490  * </ul>
491  *
492  * @see ControlListener
493  * @see #addControlListener
494  */

495 public void removeControlListener (ControlListener listener) {
496     checkWidget ();
497     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
498     if (eventTable == null) return;
499     eventTable.unhook (SWT.Move, listener);
500     eventTable.unhook (SWT.Resize, listener);
501 }
502
503 /**
504  * Removes the listener from the collection of listeners who will
505  * be notified when the control is selected by the user.
506  *
507  * @param listener the listener which should no longer be notified
508  *
509  * @exception IllegalArgumentException <ul>
510  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
511  * </ul>
512  * @exception SWTException <ul>
513  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
514  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
515  * </ul>
516  *
517  * @see SelectionListener
518  * @see #addSelectionListener
519  */

520 public void removeSelectionListener(SelectionListener listener) {
521     checkWidget ();
522     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
523     if (eventTable == null) return;
524     eventTable.unhook (SWT.Selection, listener);
525     eventTable.unhook (SWT.DefaultSelection,listener);
526 }
527
528 /**
529  * Controls how text and images will be displayed in the receiver.
530  * The argument should be one of <code>LEFT</code>, <code>RIGHT</code>
531  * or <code>CENTER</code>.
532  *
533  * @param alignment the new alignment
534  *
535  * @exception SWTException <ul>
536  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
537  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
538  * </ul>
539  */

540 public void setAlignment (int alignment) {
541     checkWidget ();
542     if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
543     int index = parent.indexOf (this);
544     if (index == -1 || index == 0) return;
545     style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
546     style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
547     int hwnd = parent.handle;
548     LVCOLUMN lvColumn = new LVCOLUMN ();
549     lvColumn.mask = OS.LVCF_FMT | OS.LVCF_IMAGE;
550     OS.SendMessage (hwnd, OS.LVM_GETCOLUMN, index, lvColumn);
551     lvColumn.fmt &= ~OS.LVCFMT_JUSTIFYMASK;
552     int fmt = 0;
553     if ((style & SWT.LEFT) == SWT.LEFT) fmt = OS.LVCFMT_LEFT;
554     if ((style & SWT.CENTER) == SWT.CENTER) fmt = OS.LVCFMT_CENTER;
555     if ((style & SWT.RIGHT) == SWT.RIGHT) fmt = OS.LVCFMT_RIGHT;
556     lvColumn.fmt |= fmt;
557     OS.SendMessage (hwnd, OS.LVM_SETCOLUMN, index, lvColumn);
558     /*
559     * Bug in Windows. When LVM_SETCOLUMN is used to change
560     * the alignment of a column, the column is not redrawn
561     * to show the new alignment. The fix is to compute the
562     * visible rectangle for the column and redraw it.
563     */

564     if (index != 0) {
565         parent.forceResize ();
566         RECT rect = new RECT (), headerRect = new RECT ();
567         OS.GetClientRect (hwnd, rect);
568         int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
569         OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect);
570         OS.MapWindowPoints (hwndHeader, hwnd, headerRect, 2);
571         rect.left = headerRect.left;
572         rect.right = headerRect.right;
573         OS.InvalidateRect (hwnd, rect, true);
574     }
575 }
576
577 public void setImage (Image image) {
578     checkWidget();
579     if (image != null && image.isDisposed ()) {
580         error (SWT.ERROR_INVALID_ARGUMENT);
581     }
582     super.setImage (image);
583     if (parent.sortColumn != this || parent.sortDirection != SWT.NONE) {
584         setImage (image, false, false);
585     }
586 }
587
588 void setImage (Image image, boolean sort, boolean right) {
589     int index = parent.indexOf (this);
590     if (index == -1) return;
591     int hwnd = parent.handle;
592     if (OS.COMCTL32_MAJOR < 6) {
593         int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
594         HDITEM hdItem = new HDITEM ();
595         hdItem.mask = OS.HDI_FORMAT | OS.HDI_IMAGE | OS.HDI_BITMAP;
596         OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
597         hdItem.fmt &= ~OS.HDF_BITMAP_ON_RIGHT;
598         if (image != null) {
599             if (sort) {
600                 hdItem.mask &= ~OS.HDI_IMAGE;
601                 hdItem.fmt &= ~OS.HDF_IMAGE;
602                 hdItem.fmt |= OS.HDF_BITMAP;
603                 hdItem.hbm = image.handle;
604             } else {
605                 hdItem.mask &= ~OS.HDI_BITMAP;
606                 hdItem.fmt &= ~OS.HDF_BITMAP;
607                 hdItem.fmt |= OS.HDF_IMAGE;
608                 hdItem.iImage = parent.imageIndexHeader (image);
609             }
610             if (right) hdItem.fmt |= OS.HDF_BITMAP_ON_RIGHT;
611         } else {
612             hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_BITMAP);
613         }
614         OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
615     } else {
616         LVCOLUMN lvColumn = new LVCOLUMN ();
617         lvColumn.mask = OS.LVCF_FMT | OS.LVCF_IMAGE;
618         OS.SendMessage (hwnd, OS.LVM_GETCOLUMN, index, lvColumn);
619         if (image != null) {
620             lvColumn.fmt |= OS.LVCFMT_IMAGE;
621             lvColumn.iImage = parent.imageIndexHeader (image);
622             if (right) lvColumn.fmt |= OS.LVCFMT_BITMAP_ON_RIGHT;
623         } else {
624             lvColumn.mask &= ~OS.LVCF_IMAGE;
625             lvColumn.fmt &= ~(OS.LVCFMT_IMAGE | OS.LVCFMT_BITMAP_ON_RIGHT);
626         }
627         OS.SendMessage (hwnd, OS.LVM_SETCOLUMN, index, lvColumn);
628     }
629 }
630
631 /**
632  * Sets the moveable attribute. A column that is
633  * moveable can be reordered by the user by dragging
634  * the header. A column that is not moveable cannot be
635  * dragged by the user but may be reordered
636  * by the programmer.
637  *
638  * @param moveable the moveable attribute
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  * @see Table#setColumnOrder(int[])
646  * @see Table#getColumnOrder()
647  * @see TableColumn#getMoveable()
648  * @see SWT#Move
649  *
650  * @since 3.1
651  */

652 public void setMoveable (boolean moveable) {
653     checkWidget ();
654     this.moveable = moveable;
655     parent.updateMoveable ();
656 }
657
658 /**
659  * Sets the resizable attribute. A column that is
660  * resizable can be resized by the user dragging the
661  * edge of the header. A column that is not resizable
662  * cannot be dragged by the user but may be resized
663  * by the programmer.
664  *
665  * @param resizable the resize attribute
666  *
667  * @exception SWTException <ul>
668  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
669  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
670  * </ul>
671  */

672 public void setResizable (boolean resizable) {
673     checkWidget ();
674     this.resizable = resizable;
675 }
676
677 void setSortDirection (int direction) {
678     if (OS.COMCTL32_MAJOR >= 6) {
679         int index = parent.indexOf (this);
680         if (index == -1) return;
681         int hwnd = parent.handle;
682         int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
683         HDITEM hdItem = new HDITEM ();
684         hdItem.mask = OS.HDI_FORMAT | OS.HDI_IMAGE;
685         OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);
686         switch (direction) {
687             case SWT.UP:
688                 hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_SORTDOWN);
689                 hdItem.fmt |= OS.HDF_SORTUP;
690                 break;
691             case SWT.DOWN:
692                 hdItem.fmt &= ~(OS.HDF_IMAGE | OS.HDF_SORTUP);
693                 hdItem.fmt |= OS.HDF_SORTDOWN;
694                 break;
695             case SWT.NONE:
696                 hdItem.fmt &= ~(OS.HDF_SORTUP | OS.HDF_SORTDOWN);
697                 if (image != null) {
698                     hdItem.fmt |= OS.HDF_IMAGE;
699                     hdItem.iImage = parent.imageIndexHeader (image);
700                 } else {
701                     hdItem.fmt &= ~OS.HDF_IMAGE;
702                     hdItem.mask &= ~OS.HDI_IMAGE;
703                 }
704                 break;
705         }
706         OS.SendMessage (hwndHeader, OS.HDM_SETITEM, index, hdItem);
707         /*
708         * Bug in Windows. When LVM_SETSELECTEDCOLUMN is used to
709         * specify a selected column, Windows does not redraw either
710         * the new or the previous selected column. The fix is to
711         * force a redraw of both.
712         *
713         * Feature in Windows. When LVM_SETBKCOLOR is used with
714         * CLR_NONE and LVM_SETSELECTEDCOLUMN is used to select
715         * a column, Windows fills the column with the selection
716         * color, drawing on top of the background image and any
717         * other custom drawing. The fix is to avoid setting the
718         * selected column.
719         */

720         parent.forceResize ();
721         RECT rect = new RECT ();
722         OS.GetClientRect (hwnd, rect);
723         if (OS.SendMessage (hwnd, OS.LVM_GETBKCOLOR, 0, 0) != OS.CLR_NONE) {
724             int oldColumn = OS.SendMessage (hwnd, OS.LVM_GETSELECTEDCOLUMN, 0, 0);
725             int newColumn = direction == SWT.NONE ? -1 : index;
726             OS.SendMessage (hwnd, OS.LVM_SETSELECTEDCOLUMN, newColumn, 0);
727             RECT headerRect = new RECT ();
728             if (oldColumn != -1) {
729                 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, oldColumn, headerRect) != 0) {
730                     OS.MapWindowPoints (hwndHeader, hwnd, headerRect, 2);
731                     rect.left = headerRect.left;
732                     rect.right = headerRect.right;
733                     OS.InvalidateRect (hwnd, rect, true);
734                 }
735             }
736         }
737         RECT headerRect = new RECT ();
738         if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, headerRect) != 0) {
739             OS.MapWindowPoints (hwndHeader, hwnd, headerRect, 2);
740             rect.left = headerRect.left;
741             rect.right = headerRect.right;
742             OS.InvalidateRect (hwnd, rect, true);
743         }
744     } else {
745         switch (direction) {
746             case SWT.UP:
747             case SWT.DOWN:
748                 setImage (display.getSortImage (direction), true, true);
749                 break;
750             case SWT.NONE:
751                 setImage (image, false, false);
752                 break;
753         }
754     }
755 }
756
757 public void setText (String JavaDoc string) {
758     checkWidget ();
759     if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
760     if (string.equals (text)) return;
761     int index = parent.indexOf (this);
762     if (index == -1) return;
763     super.setText (string);
764
765     /*
766     * Bug in Windows. For some reason, when the title
767     * of a column is changed after the column has been
768     * created, the alignment must also be reset or the
769     * text does not draw. The fix is to query and then
770     * set the alignment.
771     */

772     int hwnd = parent.handle;
773     LVCOLUMN lvColumn = new LVCOLUMN ();
774     lvColumn.mask = OS.LVCF_FMT;
775     OS.SendMessage (hwnd, OS.LVM_GETCOLUMN, index, lvColumn);
776
777     /*
778     * Bug in Windows. When a column header contains a
779     * mnemonic character, Windows does not measure the
780     * text properly. This causes '...' to always appear
781     * at the end of the text. The fix is to remove
782     * mnemonic characters and replace doubled mnemonics
783     * with spaces.
784     */

785     int hHeap = OS.GetProcessHeap ();
786     TCHAR buffer = new TCHAR (parent.getCodePage (), fixMnemonic (string), true);
787     int byteCount = buffer.length () * TCHAR.sizeof;
788     int pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
789     OS.MoveMemory (pszText, buffer, byteCount);
790     lvColumn.mask |= OS.LVCF_TEXT;
791     lvColumn.pszText = pszText;
792     int result = OS.SendMessage (hwnd, OS.LVM_SETCOLUMN, index, lvColumn);
793     if (pszText != 0) OS.HeapFree (hHeap, 0, pszText);
794     if (result == 0) error (SWT.ERROR_CANNOT_SET_TEXT);
795 }
796
797 /**
798  * Sets the receiver's tool tip text to the argument, which
799  * may be null indicating that no tool tip text should be shown.
800  *
801  * @param string the new tool tip text (or null)
802  *
803  * @exception SWTException <ul>
804  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
805  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
806  * </ul>
807  *
808  * @since 3.2
809  */

810 public void setToolTipText (String JavaDoc string) {
811     checkWidget();
812     toolTipText = string;
813     int hwndHeaderToolTip = parent.headerToolTipHandle;
814     if (hwndHeaderToolTip == 0) {
815         parent.createHeaderToolTips ();
816         parent.updateHeaderToolTips ();
817     }
818 }
819
820 /**
821  * Sets the width of the receiver.
822  *
823  * @param width the new width
824  *
825  * @exception SWTException <ul>
826  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
827  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
828  * </ul>
829  */

830 public void setWidth (int width) {
831     checkWidget ();
832     if (width < 0) return;
833     int index = parent.indexOf (this);
834     if (index == -1) return;
835     int hwnd = parent.handle;
836     OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, width);
837 }
838
839 void updateToolTip (int index) {
840     int hwndHeaderToolTip = parent.headerToolTipHandle;
841     if (hwndHeaderToolTip != 0) {
842         int hwnd = parent.handle;
843         int hwndHeader = OS.SendMessage (hwnd, OS.LVM_GETHEADER, 0, 0);
844         RECT rect = new RECT ();
845         if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, rect) != 0) {
846             TOOLINFO lpti = new TOOLINFO ();
847             lpti.cbSize = TOOLINFO.sizeof;
848             lpti.hwnd = hwndHeader;
849             lpti.uId = id;
850             lpti.left = rect.left;
851             lpti.top = rect.top;
852             lpti.right = rect.right;
853             lpti.bottom = rect.bottom;
854             OS.SendMessage (hwndHeaderToolTip, OS.TTM_NEWTOOLRECT, 0, lpti);
855         }
856     }
857 }
858
859 }
860
Popular Tags