]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/custom/TableCursor.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / custom / TableCursor.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.custom;
15
16 import org.eclipse.swt.*;
17 import org.eclipse.swt.accessibility.*;
18 import org.eclipse.swt.events.*;
19 import org.eclipse.swt.graphics.*;
20 import org.eclipse.swt.widgets.*;
21
22 /**
23  * A TableCursor provides a way for the user to navigate around a Table
24  * using the keyboard.  It also provides a mechanism for selecting an
25  * individual cell in a table.
26  * <p>
27  * For a detailed example of using a TableCursor to navigate to a cell and then edit it see
28  * http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet96.java .
29  *
30  * <dl>
31  * <dt><b>Styles:</b></dt>
32  * <dd>BORDER</dd>
33  * <dt><b>Events:</b></dt>
34  * <dd>Selection, DefaultSelection</dd>
35  * </dl>
36  *
37  * @since 2.0
38  *
39  * @see <a href="http://www.eclipse.org/swt/snippets/#tablecursor">TableCursor snippets</a>
40  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
41  */
42 public class TableCursor extends Canvas {
43         Table table;
44         TableItem row = null;
45         TableColumn column = null;
46         Listener listener, tableListener, resizeListener, disposeItemListener, disposeColumnListener;
47
48         Color background = null;
49         Color foreground = null;
50
51         /* By default, invert the list selection colors */
52         static final int BACKGROUND = SWT.COLOR_LIST_SELECTION_TEXT;
53         static final int FOREGROUND = SWT.COLOR_LIST_SELECTION;
54
55 /**
56  * Constructs a new instance of this class given its parent
57  * table and a style value describing its behavior and appearance.
58  * <p>
59  * The style value is either one of the style constants defined in
60  * class <code>SWT</code> which is applicable to instances of this
61  * class, or must be built by <em>bitwise OR</em>'ing together
62  * (that is, using the <code>int</code> "|" operator) two or more
63  * of those <code>SWT</code> style constants. The class description
64  * lists the style constants that are applicable to the class.
65  * Style bits are also inherited from superclasses.
66  * </p>
67  *
68  * @param parent a Table control which will be the parent of the new instance (cannot be null)
69  * @param style the style of control to construct
70  *
71  * @exception IllegalArgumentException <ul>
72  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
73  * </ul>
74  * @exception SWTException <ul>
75  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
76  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
77  * </ul>
78  *
79  * @see SWT#BORDER
80  * @see Widget#checkSubclass()
81  * @see Widget#getStyle()
82  */
83 public TableCursor(Table parent, int style) {
84         super(parent, style);
85         table = parent;
86         setBackground(null);
87         setForeground(null);
88
89         listener = event -> {
90                 switch (event.type) {
91                         case SWT.Dispose :
92                                 onDispose(event);
93                                 break;
94                         case SWT.FocusIn :
95                         case SWT.FocusOut :
96                                 redraw();
97                                 break;
98                         case SWT.KeyDown :
99                                 keyDown(event);
100                                 break;
101                         case SWT.Paint :
102                                 paint(event);
103                                 break;
104                         case SWT.Traverse : {
105                                 event.doit = true;
106                                 switch (event.detail) {
107                                         case SWT.TRAVERSE_ARROW_NEXT :
108                                         case SWT.TRAVERSE_ARROW_PREVIOUS :
109                                         case SWT.TRAVERSE_RETURN :
110                                                 event.doit = false;
111                                                 break;
112                                 }
113                                 break;
114                         }
115                 }
116         };
117         int[] events = new int[] {SWT.Dispose, SWT.FocusIn, SWT.FocusOut, SWT.KeyDown, SWT.Paint, SWT.Traverse};
118         for (int i = 0; i < events.length; i++) {
119                 addListener(events[i], listener);
120         }
121
122         tableListener = event -> {
123                 switch (event.type) {
124                         case SWT.MouseDown :
125                                 tableMouseDown(event);
126                                 break;
127                         case SWT.FocusIn :
128                                 tableFocusIn(event);
129                                 break;
130                 }
131         };
132         table.addListener(SWT.FocusIn, tableListener);
133         table.addListener(SWT.MouseDown, tableListener);
134
135         disposeItemListener = event -> {
136                 unhookRowColumnListeners();
137                 row = null;
138                 column = null;
139                 _resize();
140         };
141         disposeColumnListener = event -> {
142                 unhookRowColumnListeners();
143                 row = null;
144                 column = null;
145                 _resize();
146         };
147         resizeListener = event -> _resize();
148         ScrollBar hBar = table.getHorizontalBar();
149         if (hBar != null) {
150                 hBar.addListener(SWT.Selection, resizeListener);
151         }
152         ScrollBar vBar = table.getVerticalBar();
153         if (vBar != null) {
154                 vBar.addListener(SWT.Selection, resizeListener);
155         }
156
157         getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
158                 @Override
159                 public void getRole(AccessibleControlEvent e) {
160                         e.detail = ACC.ROLE_TABLECELL;
161                 }
162         });
163         getAccessible().addAccessibleListener(new AccessibleAdapter() {
164                 @Override
165                 public void getName(AccessibleEvent e) {
166                         if (row == null) return;
167                         int columnIndex = column == null ? 0 : table.indexOf(column);
168                         e.result = row.getText(columnIndex);
169                 }
170         });
171 }
172
173 /**
174  * Adds the listener to the collection of listeners who will
175  * be notified when the user changes the receiver's selection, by sending
176  * it one of the messages defined in the <code>SelectionListener</code>
177  * interface.
178  * <p>
179  * When <code>widgetSelected</code> is called, the item field of the event object is valid.
180  * If the receiver has <code>SWT.CHECK</code> style set and the check selection changes,
181  * the event object detail field contains the value <code>SWT.CHECK</code>.
182  * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
183  * </p>
184  *
185  * @param listener the listener which should be notified when the user changes the receiver's selection
186  *
187  * @exception IllegalArgumentException <ul>
188  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
189  * </ul>
190  * @exception SWTException <ul>
191  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
192  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
193  * </ul>
194  *
195  * @see SelectionListener
196  * @see SelectionEvent
197  * @see #removeSelectionListener(SelectionListener)
198  *
199  */
200 public void addSelectionListener(SelectionListener listener) {
201         checkWidget();
202         if (listener == null)
203                 SWT.error(SWT.ERROR_NULL_ARGUMENT);
204         TypedListener typedListener = new TypedListener(listener);
205         addListener(SWT.Selection, typedListener);
206         addListener(SWT.DefaultSelection, typedListener);
207 }
208
209 void onDispose(Event event) {
210         removeListener(SWT.Dispose, listener);
211         notifyListeners(SWT.Dispose, event);
212         event.type = SWT.None;
213
214         table.removeListener(SWT.FocusIn, tableListener);
215         table.removeListener(SWT.MouseDown, tableListener);
216         unhookRowColumnListeners();
217         ScrollBar hBar = table.getHorizontalBar();
218         if (hBar != null) {
219                 hBar.removeListener(SWT.Selection, resizeListener);
220         }
221         ScrollBar vBar = table.getVerticalBar();
222         if (vBar != null) {
223                 vBar.removeListener(SWT.Selection, resizeListener);
224         }
225 }
226
227 void keyDown(Event event) {
228         if (row == null) return;
229         switch (event.character) {
230                 case SWT.CR :
231                         notifyListeners(SWT.DefaultSelection, new Event());
232                         return;
233         }
234         int rowIndex = table.indexOf(row);
235         int columnIndex = column == null ? 0 : table.indexOf(column);
236         switch (event.keyCode) {
237                 case SWT.ARROW_UP :
238                         setRowColumn(Math.max(0, rowIndex - 1), columnIndex, true);
239                         break;
240                 case SWT.ARROW_DOWN :
241                         setRowColumn(Math.min(rowIndex + 1, table.getItemCount() - 1), columnIndex, true);
242                         break;
243                 case SWT.ARROW_LEFT :
244                 case SWT.ARROW_RIGHT :
245                         {
246                                 int columnCount = table.getColumnCount();
247                                 if (columnCount == 0) break;
248                                 int[] order = table.getColumnOrder();
249                                 int index = 0;
250                                 while (index < order.length) {
251                                         if (order[index] == columnIndex) break;
252                                         index++;
253                                 }
254                                 if (index == order.length) index = 0;
255                                 int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
256                                 if (event.keyCode == leadKey) {
257                                         setRowColumn(rowIndex, order[Math.max(0, index - 1)], true);
258                                 } else {
259                                         setRowColumn(rowIndex, order[Math.min(columnCount - 1, index + 1)], true);
260                                 }
261                                 break;
262                         }
263                 case SWT.HOME :
264                         setRowColumn(0, columnIndex, true);
265                         break;
266                 case SWT.END :
267                         {
268                                 int i = table.getItemCount() - 1;
269                                 setRowColumn(i, columnIndex, true);
270                                 break;
271                         }
272                 case SWT.PAGE_UP :
273                         {
274                                 int index = table.getTopIndex();
275                                 if (index == rowIndex) {
276                                         Rectangle rect = table.getClientArea();
277                                         TableItem item = table.getItem(index);
278                                         Rectangle itemRect = item.getBounds(0);
279                                         rect.height -= itemRect.y;
280                                         int height = table.getItemHeight();
281                                         int page = Math.max(1, rect.height / height);
282                                         index = Math.max(0, index - page + 1);
283                                 }
284                                 setRowColumn(index, columnIndex, true);
285                                 break;
286                         }
287                 case SWT.PAGE_DOWN :
288                         {
289                                 int index = table.getTopIndex();
290                                 Rectangle rect = table.getClientArea();
291                                 TableItem item = table.getItem(index);
292                                 Rectangle itemRect = item.getBounds(0);
293                                 rect.height -= itemRect.y;
294                                 int height = table.getItemHeight();
295                                 int page = Math.max(1, rect.height / height);
296                                 int end = table.getItemCount() - 1;
297                                 index = Math.min(end, index + page - 1);
298                                 if (index == rowIndex) {
299                                         index = Math.min(end, index + page - 1);
300                                 }
301                                 setRowColumn(index, columnIndex, true);
302                                 break;
303                         }
304         }
305 }
306
307 void paint(Event event) {
308         if (row == null) return;
309         int columnIndex = column == null ? 0 : table.indexOf(column);
310         GC gc = event.gc;
311         gc.setBackground(getBackground());
312         gc.setForeground(getForeground());
313         gc.fillRectangle(event.x, event.y, event.width, event.height);
314         int x = 0;
315         Point size = getSize();
316         Image image = row.getImage(columnIndex);
317         if (image != null) {
318                 Rectangle imageSize = image.getBounds();
319                 int imageY = (size.y - imageSize.height) / 2;
320                 gc.drawImage(image, x, imageY);
321                 x += imageSize.width;
322         }
323         String text = row.getText(columnIndex);
324         if (text.length() > 0) {
325                 Rectangle bounds = row.getBounds(columnIndex);
326                 Point extent = gc.stringExtent(text);
327                 // Temporary code - need a better way to determine table trim
328                 String platform = SWT.getPlatform();
329                 if ("win32".equals(platform)) { //$NON-NLS-1$
330                         if (table.getColumnCount() == 0 || columnIndex == 0) {
331                                 x += 2;
332                         } else {
333                                 int alignmnent = column.getAlignment();
334                                 switch (alignmnent) {
335                                         case SWT.LEFT:
336                                                 x += 6;
337                                                 break;
338                                         case SWT.RIGHT:
339                                                 x = bounds.width - extent.x - 6;
340                                                 break;
341                                         case SWT.CENTER:
342                                                 x += (bounds.width - x - extent.x) / 2;
343                                                 break;
344                                 }
345                         }
346                 }  else {
347                         if (table.getColumnCount() == 0) {
348                                 x += 5;
349                         } else {
350                                 int alignmnent = column.getAlignment();
351                                 switch (alignmnent) {
352                                         case SWT.LEFT:
353                                                 x += 5;
354                                                 break;
355                                         case SWT.RIGHT:
356                                                 x = bounds.width- extent.x - 2;
357                                                 break;
358                                         case SWT.CENTER:
359                                                 x += (bounds.width - x - extent.x) / 2 + 2;
360                                                 break;
361                                 }
362                         }
363                 }
364                 int textY = (size.y - extent.y) / 2;
365                 gc.drawString(text, x, textY);
366         }
367         if (isFocusControl()) {
368                 Display display = getDisplay();
369                 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
370                 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
371                 gc.drawFocus(0, 0, size.x, size.y);
372         }
373 }
374
375 void tableFocusIn(Event event) {
376         if (isDisposed()) return;
377         if (isVisible()) {
378                 if (row == null && column == null) return;
379                 setFocus();
380         }
381 }
382
383 void tableMouseDown(Event event) {
384         if (isDisposed() || !isVisible()) return;
385         Point pt = new Point(event.x, event.y);
386         int lineWidth = table.getLinesVisible() ? table.getGridLineWidth() : 0;
387         TableItem item = table.getItem(pt);
388         if ((table.getStyle() & SWT.FULL_SELECTION) != 0) {
389                 if (item == null) return;
390         } else {
391                 int start = item != null ? table.indexOf(item) : table.getTopIndex();
392                 int end = table.getItemCount();
393                 Rectangle clientRect = table.getClientArea();
394                 for (int i = start; i < end; i++) {
395                         TableItem nextItem = table.getItem(i);
396                         Rectangle rect = nextItem.getBounds(0);
397                         if (pt.y >= rect.y && pt.y < rect.y + rect.height + lineWidth) {
398                                 item = nextItem;
399                                 break;
400                         }
401                         if (rect.y > clientRect.y + clientRect.height)  return;
402                 }
403                 if (item == null) return;
404         }
405         TableColumn newColumn = null;
406         int columnCount = table.getColumnCount();
407         if (columnCount == 0) {
408                 if ((table.getStyle() & SWT.FULL_SELECTION) == 0) {
409                         Rectangle rect = item.getBounds(0);
410                         rect.width += lineWidth;
411                         rect.height += lineWidth;
412                         if (!rect.contains(pt)) return;
413                 }
414         } else {
415                 for (int i = 0; i < columnCount; i++) {
416                         Rectangle rect = item.getBounds(i);
417                         rect.width += lineWidth;
418                         rect.height += lineWidth;
419                         if (rect.contains(pt)) {
420                                 newColumn = table.getColumn(i);
421                                 break;
422                         }
423                 }
424                 if (newColumn == null) {
425                         if ((table.getStyle() & SWT.FULL_SELECTION) == 0) return;
426                         newColumn = table.getColumn(0);
427                 }
428         }
429         setRowColumn(item, newColumn, true);
430         setFocus();
431         return;
432 }
433 void setRowColumn(int row, int column, boolean notify) {
434         TableItem item = row == -1 ? null : table.getItem(row);
435         TableColumn col = column == -1 || table.getColumnCount() == 0 ? null : table.getColumn(column);
436         setRowColumn(item, col, notify);
437 }
438 void setRowColumn(TableItem row, TableColumn column, boolean notify) {
439         if (this.row == row && this.column == column) {
440                 return;
441         }
442         if (this.row != null && this.row != row) {
443                 this.row.removeListener(SWT.Dispose, disposeItemListener);
444                 this.row = null;
445         }
446         if (this.column != null && this.column != column) {
447                 this.column.removeListener(SWT.Dispose, disposeColumnListener);
448                 this.column.removeListener(SWT.Move, resizeListener);
449                 this.column.removeListener(SWT.Resize, resizeListener);
450                 this.column = null;
451         }
452         if (row != null) {
453                 if (this.row != row) {
454                         this.row = row;
455                         row.addListener(SWT.Dispose, disposeItemListener);
456                         table.showItem(row);
457                 }
458                 if (this.column != column && column != null) {
459                         this.column = column;
460                         column.addListener(SWT.Dispose, disposeColumnListener);
461                         column.addListener(SWT.Move, resizeListener);
462                         column.addListener(SWT.Resize, resizeListener);
463                         table.showColumn(column);
464                 }
465                 int columnIndex = column == null ? 0 : table.indexOf(column);
466                 setBounds(row.getBounds(columnIndex));
467                 redraw();
468                 if (notify) {
469                         notifyListeners(SWT.Selection, new Event());
470                 }
471         }
472         getAccessible().setFocus(ACC.CHILDID_SELF);
473 }
474
475 @Override
476 public void setVisible(boolean visible) {
477         checkWidget();
478         if (visible) _resize();
479         super.setVisible(visible);
480 }
481
482 /**
483  * Removes the listener from the collection of listeners who will
484  * be notified when the user changes the receiver's selection.
485  *
486  * @param listener the listener which should no longer be notified
487  *
488  * @exception IllegalArgumentException <ul>
489  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
490  * </ul>
491  * @exception SWTException <ul>
492  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
493  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
494  * </ul>
495  *
496  * @see SelectionListener
497  * @see #addSelectionListener(SelectionListener)
498  *
499  * @since 3.0
500  */
501 public void removeSelectionListener(SelectionListener listener) {
502         checkWidget();
503         if (listener == null) {
504                 SWT.error(SWT.ERROR_NULL_ARGUMENT);
505         }
506         removeListener(SWT.Selection, listener);
507         removeListener(SWT.DefaultSelection, listener);
508 }
509
510 void _resize() {
511         if (row == null) {
512                 setBounds(-200, -200, 0, 0);
513         } else {
514                 int columnIndex = column == null ? 0 : table.indexOf(column);
515                 setBounds(row.getBounds(columnIndex));
516         }
517 }
518 /**
519  * Returns the index of the column over which the TableCursor is positioned.
520  *
521  * @return the column index for the current position
522  *
523  * @exception SWTException <ul>
524  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
525  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
526  * </ul>
527  */
528 public int getColumn() {
529         checkWidget();
530         return column == null ? 0 : table.indexOf(column);
531 }
532 /**
533  * Returns the background color that the receiver will use to draw.
534  *
535  * @return the receiver's background color
536  */
537 @Override
538 public Color getBackground() {
539         checkWidget();
540         if (background == null) {
541                 return getDisplay().getSystemColor(BACKGROUND);
542         }
543         return background;
544 }
545 /**
546  * Returns the foreground color that the receiver will use to draw.
547  *
548  * @return the receiver's foreground color
549  */
550 @Override
551 public Color getForeground() {
552         checkWidget();
553         if (foreground == null) {
554                 return getDisplay().getSystemColor(FOREGROUND);
555         }
556         return foreground;
557 }
558 /**
559  * Returns the row over which the TableCursor is positioned.
560  *
561  * @return the item for the current position, or <code>null</code> if none
562  *
563  * @exception SWTException <ul>
564  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
565  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
566  * </ul>
567  */
568 public TableItem getRow() {
569         checkWidget();
570         return row;
571 }
572 /**
573  * Sets the receiver's background color to the color specified
574  * by the argument, or to the default system color for the control
575  * if the argument is null.
576  * <p>
577  * Note: This operation is a hint and may be overridden by the platform.
578  * For example, on Windows the background of a Button cannot be changed.
579  * </p>
580  * @param color the new color (or null)
581  *
582  * @exception IllegalArgumentException <ul>
583  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
584  * </ul>
585  * @exception SWTException <ul>
586  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
587  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
588  * </ul>
589  */
590 @Override
591 public void setBackground (Color color) {
592         background = color;
593         super.setBackground(getBackground());
594         redraw();
595 }
596 /**
597  * Sets the receiver's foreground color to the color specified
598  * by the argument, or to the default system color for the control
599  * if the argument is null.
600  * <p>
601  * Note: This operation is a hint and may be overridden by the platform.
602  * </p>
603  * @param color the new color (or null)
604  *
605  * @exception IllegalArgumentException <ul>
606  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
607  * </ul>
608  * @exception SWTException <ul>
609  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
610  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
611  * </ul>
612  */
613 @Override
614 public void setForeground (Color color) {
615         foreground = color;
616         super.setForeground(getForeground());
617         redraw();
618 }
619 /**
620  * Positions the TableCursor over the cell at the given row and column in the parent table.
621  *
622  * @param row the index of the row for the cell to select
623  * @param column the index of column for the cell to select
624  *
625  * @exception SWTException <ul>
626  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
627  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
628  * </ul>
629  *
630  */
631 public void setSelection(int row, int column) {
632         checkWidget();
633         int columnCount = table.getColumnCount();
634         int maxColumnIndex =  columnCount == 0 ? 0 : columnCount - 1;
635         if (row < 0
636                 || row >= table.getItemCount()
637                 || column < 0
638                 || column > maxColumnIndex)
639                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
640         setRowColumn(row, column, false);
641 }
642 /**
643  * Positions the TableCursor over the cell at the given row and column in the parent table.
644  *
645  * @param row the TableItem of the row for the cell to select
646  * @param column the index of column for the cell to select
647  *
648  * @exception SWTException <ul>
649  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
650  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
651  * </ul>
652  *
653  */
654 public void setSelection(TableItem row, int column) {
655         checkWidget();
656         int columnCount = table.getColumnCount();
657         int maxColumnIndex =  columnCount == 0 ? 0 : columnCount - 1;
658         if (row == null
659                 || row.isDisposed()
660                 || column < 0
661                 || column > maxColumnIndex)
662                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
663         setRowColumn(table.indexOf(row), column, false);
664 }
665 void unhookRowColumnListeners() {
666         if (column != null) {
667                 column.removeListener(SWT.Dispose, disposeColumnListener);
668                 column.removeListener(SWT.Move, resizeListener);
669                 column.removeListener(SWT.Resize, resizeListener);
670                 column = null;
671         }
672         if (row != null) {
673                 row.removeListener(SWT.Dispose, disposeItemListener);
674                 row = null;
675         }
676 }
677 }