void tableMouseDown(Event event) {
   if (isDisposed() || !isVisible()) return;
   Point pt = new Point(event.x, event.y);
   int lineWidth = table.getLinesVisible() ? table.getGridLineWidth() : 0;
   TableItem item = table.getItem(pt);
   if ((table.getStyle() & SWT.FULL_SELECTION) != 0) {
     if (item == null) return;
   } else {
     int start = item != null ? table.indexOf(item) : table.getTopIndex();
     int end = table.getItemCount();
     Rectangle clientRect = table.getClientArea();
     for (int i = start; i < end; i++) {
       TableItem nextItem = table.getItem(i);
       Rectangle rect = nextItem.getBounds(0);
       if (pt.y >= rect.y && pt.y < rect.y + rect.height + lineWidth) {
         item = nextItem;
         break;
       }
       if (rect.y > clientRect.y + clientRect.height) return;
     }
     if (item == null) return;
   }
   TableColumn newColumn = null;
   int columnCount = table.getColumnCount();
   if (columnCount == 0) {
     if ((table.getStyle() & SWT.FULL_SELECTION) == 0) {
       Rectangle rect = item.getBounds(0);
       rect.width += lineWidth;
       rect.height += lineWidth;
       if (!rect.contains(pt)) return;
     }
   } else {
     for (int i = 0; i < columnCount; i++) {
       Rectangle rect = item.getBounds(i);
       rect.width += lineWidth;
       rect.height += lineWidth;
       if (rect.contains(pt)) {
         newColumn = table.getColumn(i);
         break;
       }
     }
     if (newColumn == null) {
       if ((table.getStyle() & SWT.FULL_SELECTION) == 0) return;
       newColumn = table.getColumn(0);
     }
   }
   setRowColumn(item, newColumn, true);
   setFocus();
   return;
 }
 void _resize() {
   if (row == null) {
     setBounds(-200, -200, 0, 0);
   } else {
     int columnIndex = column == null ? 0 : table.indexOf(column);
     setBounds(row.getBounds(columnIndex));
   }
 }
 void setRowColumn(TableItem row, TableColumn column, boolean notify) {
   if (this.row == row && this.column == column) {
     return;
   }
   if (this.row != null && this.row != row) {
     this.row.removeListener(SWT.Dispose, disposeItemListener);
     this.row = null;
   }
   if (this.column != null && this.column != column) {
     this.column.removeListener(SWT.Dispose, disposeColumnListener);
     this.column.removeListener(SWT.Move, resizeListener);
     this.column.removeListener(SWT.Resize, resizeListener);
     this.column = null;
   }
   if (row != null) {
     if (this.row != row) {
       this.row = row;
       row.addListener(SWT.Dispose, disposeItemListener);
       table.showItem(row);
     }
     if (this.column != column && column != null) {
       this.column = column;
       column.addListener(SWT.Dispose, disposeColumnListener);
       column.addListener(SWT.Move, resizeListener);
       column.addListener(SWT.Resize, resizeListener);
       table.showColumn(column);
     }
     int columnIndex = column == null ? 0 : table.indexOf(column);
     setBounds(row.getBounds(columnIndex));
     redraw();
     if (notify) {
       notifyListeners(SWT.Selection, new Event());
     }
   }
   getAccessible().setFocus(ACC.CHILDID_SELF);
 }
 void paint(Event event) {
   if (row == null) return;
   int columnIndex = column == null ? 0 : table.indexOf(column);
   GC gc = event.gc;
   gc.setBackground(getBackground());
   gc.setForeground(getForeground());
   gc.fillRectangle(event.x, event.y, event.width, event.height);
   int x = 0;
   Point size = getSize();
   Image image = row.getImage(columnIndex);
   if (image != null) {
     Rectangle imageSize = image.getBounds();
     int imageY = (size.y - imageSize.height) / 2;
     gc.drawImage(image, x, imageY);
     x += imageSize.width;
   }
   String text = row.getText(columnIndex);
   if (text.length() > 0) {
     Rectangle bounds = row.getBounds(columnIndex);
     Point extent = gc.stringExtent(text);
     // Temporary code - need a better way to determine table trim
     String platform = SWT.getPlatform();
     if ("win32".equals(platform)) { // $NON-NLS-1$
       if (table.getColumnCount() == 0 || columnIndex == 0) {
         x += 2;
       } else {
         int alignmnent = column.getAlignment();
         switch (alignmnent) {
           case SWT.LEFT:
             x += 6;
             break;
           case SWT.RIGHT:
             x = bounds.width - extent.x - 6;
             break;
           case SWT.CENTER:
             x += (bounds.width - x - extent.x) / 2;
             break;
         }
       }
     } else {
       if (table.getColumnCount() == 0) {
         x += 5;
       } else {
         int alignmnent = column.getAlignment();
         switch (alignmnent) {
           case SWT.LEFT:
             x += 5;
             break;
           case SWT.RIGHT:
             x = bounds.width - extent.x - 2;
             break;
           case SWT.CENTER:
             x += (bounds.width - x - extent.x) / 2 + 2;
             break;
         }
       }
     }
     int textY = (size.y - extent.y) / 2;
     gc.drawString(text, x, textY);
   }
   if (isFocusControl()) {
     Display display = getDisplay();
     gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
     gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
     gc.drawFocus(0, 0, size.x, size.y);
   }
 }
 void keyDown(Event event) {
   if (row == null) return;
   switch (event.character) {
     case SWT.CR:
       notifyListeners(SWT.DefaultSelection, new Event());
       return;
   }
   int rowIndex = table.indexOf(row);
   int columnIndex = column == null ? 0 : table.indexOf(column);
   switch (event.keyCode) {
     case SWT.ARROW_UP:
       setRowColumn(Math.max(0, rowIndex - 1), columnIndex, true);
       break;
     case SWT.ARROW_DOWN:
       setRowColumn(Math.min(rowIndex + 1, table.getItemCount() - 1), columnIndex, true);
       break;
     case SWT.ARROW_LEFT:
     case SWT.ARROW_RIGHT:
       {
         int columnCount = table.getColumnCount();
         if (columnCount == 0) break;
         int[] order = table.getColumnOrder();
         int index = 0;
         while (index < order.length) {
           if (order[index] == columnIndex) break;
           index++;
         }
         if (index == order.length) index = 0;
         int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
         if (event.keyCode == leadKey) {
           setRowColumn(rowIndex, order[Math.max(0, index - 1)], true);
         } else {
           setRowColumn(rowIndex, order[Math.min(columnCount - 1, index + 1)], true);
         }
         break;
       }
     case SWT.HOME:
       setRowColumn(0, columnIndex, true);
       break;
     case SWT.END:
       {
         int i = table.getItemCount() - 1;
         setRowColumn(i, columnIndex, true);
         break;
       }
     case SWT.PAGE_UP:
       {
         int index = table.getTopIndex();
         if (index == rowIndex) {
           Rectangle rect = table.getClientArea();
           TableItem item = table.getItem(index);
           Rectangle itemRect = item.getBounds(0);
           rect.height -= itemRect.y;
           int height = table.getItemHeight();
           int page = Math.max(1, rect.height / height);
           index = Math.max(0, index - page + 1);
         }
         setRowColumn(index, columnIndex, true);
         break;
       }
     case SWT.PAGE_DOWN:
       {
         int index = table.getTopIndex();
         Rectangle rect = table.getClientArea();
         TableItem item = table.getItem(index);
         Rectangle itemRect = item.getBounds(0);
         rect.height -= itemRect.y;
         int height = table.getItemHeight();
         int page = Math.max(1, rect.height / height);
         int end = table.getItemCount() - 1;
         index = Math.min(end, index + page - 1);
         if (index == rowIndex) {
           index = Math.min(end, index + page - 1);
         }
         setRowColumn(index, columnIndex, true);
         break;
       }
   }
 }