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