private int getSpacing(final int index) {
   int result = 0;
   if (parent.hasColumnImages(index)) {
     result = parent.getCellSpacing();
   }
   return result;
 }
Exemple #2
0
  public static void sortTable(Table table, Comparator<TableItem> comparator) {
    int columnCount = table.getColumnCount();
    String[] values = new String[columnCount];
    TableItem[] items = table.getItems();
    for (int i = 1; i < items.length; i++) {
      for (int j = 0; j < i; j++) {
        TableItem item = items[i];
        if (comparator.compare(item, items[j]) < 0) {
          for (int k = 0; k < columnCount; k++) {
            values[k] = item.getText(k);
          }
          Object data = item.getData();
          boolean checked = item.getChecked();
          item.dispose();

          item = new TableItem(table, SWT.NONE, j);
          item.setText(values);
          item.setData(data);
          item.setChecked(checked);
          items = table.getItems();
          break;
        }
      }
    }
  }
Exemple #3
0
  /**
   * Sets the font that the receiver will use to paint textual information for the specified cell in
   * this item to the font specified by the argument, or to the default font for that kind of
   * control if the argument is null.
   *
   * @param index the column index
   * @param font the new font (or null)
   * @exception IllegalArgumentException
   *     <ul>
   *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
   *     </ul>
   *
   * @exception SWTException
   *     <ul>
   *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
   *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
   *     </ul>
   *
   * @since 3.0
   */
  public void setFont(int index, Font font) {
    checkWidget();
    if (font != null && font.isDisposed()) {
      SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    }
    int count = Math.max(1, parent.getColumnCount());
    if (0 > index || index > count - 1) return;
    if (cellFont == null) {
      if (font == null) return;
      cellFont = new Font[count];
    }
    Font oldFont = cellFont[index];
    if (oldFont == font) return;
    cellFont[index] = font;
    if (oldFont != null && oldFont.equals(font)) return;

    int modelIndex =
        parent.columnCount == 0 ? Table.FIRST_COLUMN : parent.columns[index].modelIndex;
    int /*long*/ fontHandle = font != null ? font.handle : 0;
    OS.gtk_list_store_set(parent.modelHandle, handle, modelIndex + Table.CELL_FONT, fontHandle, -1);
    /*
     * Bug in GTK.  When using fixed-height-mode,
     * row changes do not cause the row to be repainted.  The fix is to
     * invalidate the row when it is cleared.
     */
    if ((parent.style & SWT.VIRTUAL) != 0) {
      if (OS.GTK_VERSION >= OS.VERSION(2, 3, 2) && OS.GTK_VERSION < OS.VERSION(2, 6, 3)) {
        redraw();
      }
    }
    cached = true;

    if (font != null) {
      boolean customDraw =
          (parent.columnCount == 0) ? parent.firstCustomDraw : parent.columns[index].customDraw;
      if (!customDraw) {
        if ((parent.style & SWT.VIRTUAL) == 0) {
          int /*long*/ parentHandle = parent.handle;
          int /*long*/ column = 0;
          if (parent.columnCount > 0) {
            column = parent.columns[index].handle;
          } else {
            column = OS.gtk_tree_view_get_column(parentHandle, index);
          }
          if (column == 0) return;
          int /*long*/ textRenderer = parent.getTextRenderer(column);
          int /*long*/ imageRenderer = parent.getPixbufRenderer(column);
          OS.gtk_tree_view_column_set_cell_data_func(
              column, textRenderer, display.cellDataProc, parentHandle, 0);
          OS.gtk_tree_view_column_set_cell_data_func(
              column, imageRenderer, display.cellDataProc, parentHandle, 0);
        }
        if (parent.columnCount == 0) {
          parent.firstCustomDraw = true;
        } else {
          parent.columns[index].customDraw = true;
        }
      }
    }
  }
 /**
  * Returns the image stored at the given column index in the receiver, or null if the image has
  * not been set or if the column does not exist.
  *
  * @param index the column index
  * @return the image stored at the given column index in the receiver
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Image getImage(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   return getImageInternal(index);
 }
 /**
  * Positions the TableCursor over the cell at the given row and column in the parent table.
  *
  * @param row the TableItem of the row for the cell to select
  * @param column the index of column for the cell to select
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setSelection(TableItem row, int column) {
   checkWidget();
   int columnCount = table.getColumnCount();
   int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1;
   if (row == null || row.isDisposed() || column < 0 || column > maxColumnIndex)
     SWT.error(SWT.ERROR_INVALID_ARGUMENT);
   setRowColumn(table.indexOf(row), column, false);
 }
 /**
  * Positions the TableCursor over the cell at the given row and column in the parent table.
  *
  * @param row the index of the row for the cell to select
  * @param column the index of column for the cell to select
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setSelection(int row, int column) {
   checkWidget();
   int columnCount = table.getColumnCount();
   int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1;
   if (row < 0 || row >= table.getItemCount() || column < 0 || column > maxColumnIndex)
     SWT.error(SWT.ERROR_INVALID_ARGUMENT);
   setRowColumn(row, column, false);
 }
Exemple #7
0
 /**
  * Sets the receiver's image at a column.
  *
  * @param index the column index
  * @param image the new image
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the image has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setImage(int index, Image image) {
   checkWidget();
   if (image != null && image.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   if (image != null && image.type == SWT.ICON) {
     if (image.equals(_getImage(index))) return;
   }
   int count = Math.max(1, parent.getColumnCount());
   if (0 > index || index > count - 1) return;
   int /*long*/ pixbuf = 0;
   if (image != null) {
     ImageList imageList = parent.imageList;
     if (imageList == null) imageList = parent.imageList = new ImageList();
     int imageIndex = imageList.indexOf(image);
     if (imageIndex == -1) imageIndex = imageList.add(image);
     pixbuf = imageList.getPixbuf(imageIndex);
   }
   int modelIndex =
       parent.columnCount == 0 ? Table.FIRST_COLUMN : parent.columns[index].modelIndex;
   OS.gtk_list_store_set(parent.modelHandle, handle, modelIndex + Table.CELL_PIXBUF, pixbuf, -1);
   /*
    * Bug in GTK.  When using fixed-height-mode,
    * row changes do not cause the row to be repainted.  The fix is to
    * invalidate the row when it is cleared.
    */
   if ((parent.style & SWT.VIRTUAL) != 0) {
     if (OS.GTK_VERSION >= OS.VERSION(2, 3, 2) && OS.GTK_VERSION < OS.VERSION(2, 6, 3)) {
       redraw();
     }
   }
   /*
    * Bug in GTK.  When in fixed height mode, GTK does not recalculate the cell renderer width
    * when the image is changed in the model.  The fix is to force it to recalculate the width if
    * more space is required.
    */
   if ((parent.style & SWT.VIRTUAL) != 0 && parent.currentItem == null) {
     if (OS.GTK_VERSION >= OS.VERSION(2, 3, 2)) {
       if (image != null) {
         int /*long*/ parentHandle = parent.handle;
         int /*long*/ column = OS.gtk_tree_view_get_column(parentHandle, index);
         int[] w = new int[1];
         int /*long*/ pixbufRenderer = parent.getPixbufRenderer(column);
         OS.gtk_tree_view_column_cell_get_position(column, pixbufRenderer, null, w);
         if (w[0] < image.getBounds().width) {
           /*
            * There is no direct way to clear the cell renderer width so we
            * are relying on the fact that it is done as part of modifying
            * the style.
            */
           int /*long*/ style = OS.gtk_widget_get_modifier_style(parentHandle);
           parent.modifyStyle(parentHandle, style);
         }
       }
     }
   }
   cached = true;
 }
 /**
  * This implementation of <code>dragOver</code> provides a default drag under effect for the
  * feedback specified in <code>event.feedback</code>. The class description lists the FEEDBACK
  * constants that are applicable to the class.
  *
  * <p>For additional information see <code>DropTargetAdapter.dragOver</code>.
  *
  * <p>Subclasses that override this method should call <code>super.dragOver(event)</code> to get
  * the default drag under effect implementation.
  *
  * @param event the information associated with the drag over event
  * @see DropTargetAdapter
  * @see DropTargetEvent
  * @see DND#FEEDBACK_SELECT
  * @see DND#FEEDBACK_SCROLL
  */
 public void dragOver(DropTargetEvent event) {
   Table table = (Table) control;
   long /*int*/ handle = table.handle;
   int effect = checkEffect(event.feedback);
   Point coordinates = new Point(event.x, event.y);
   coordinates = table.toControl(coordinates);
   long /*int*/[] path = new long /*int*/[1];
   OS.gtk_tree_view_get_path_at_pos(handle, coordinates.x, coordinates.y, path, null, null, null);
   int index = -1;
   if (path[0] != 0) {
     long /*int*/ indices = OS.gtk_tree_path_get_indices(path[0]);
     if (indices != 0) {
       int[] temp = new int[1];
       OS.memmove(temp, indices, 4);
       index = temp[0];
     }
   }
   if ((effect & DND.FEEDBACK_SCROLL) == 0) {
     scrollBeginTime = 0;
     scrollIndex = -1;
   } else {
     if (index != -1 && scrollIndex == index && scrollBeginTime != 0) {
       if (System.currentTimeMillis() >= scrollBeginTime) {
         if (coordinates.y < table.getItemHeight()) {
           OS.gtk_tree_path_prev(path[0]);
         } else {
           OS.gtk_tree_path_next(path[0]);
         }
         if (path[0] != 0) {
           OS.gtk_tree_view_scroll_to_cell(handle, path[0], 0, false, 0, 0);
           OS.gtk_tree_path_free(path[0]);
           path[0] = 0;
           OS.gtk_tree_view_get_path_at_pos(
               handle, coordinates.x, coordinates.y, path, null, null, null);
         }
         scrollBeginTime = 0;
         scrollIndex = -1;
       }
     } else {
       scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
       scrollIndex = index;
     }
   }
   if (path[0] != 0) {
     int position = 0;
     if ((effect & DND.FEEDBACK_SELECT) != 0) position = OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
     // if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE;
     // if ((effect & DND.FEEDBACK_INSERT_AFTER) != 0) position = OS.GTK_TREE_VIEW_DROP_AFTER;
     if (position != 0) {
       OS.gtk_tree_view_set_drag_dest_row(handle, path[0], OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
     } else {
       OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);
     }
   } else {
     OS.gtk_tree_view_set_drag_dest_row(handle, 0, OS.GTK_TREE_VIEW_DROP_BEFORE);
   }
   if (path[0] != 0) OS.gtk_tree_path_free(path[0]);
 }
 /**
  * Gets the image indent.
  *
  * @return the indent
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public int getImageIndent() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   // [rh] The only method to manipulate the image indent (setImageIndent) is
   // deprecated and thus not implemented, therefore we can safely return 0
   return 0;
 }
 private int getHeight(final int index) {
   int result = 0;
   int columnCount = parent.getColumnCount();
   boolean singleColumn = index == 0 && columnCount == 0;
   boolean columnInRange = index >= 0 && index < columnCount;
   if (singleColumn || columnInRange) {
     result = parent.getItemHeight();
   }
   return result;
 }
 final void clear() {
   data = null;
   checked = false;
   grayed = false;
   parent.updateScrollBars();
   if ((parent.style & SWT.VIRTUAL) != 0) {
     cached = false;
     parent.redraw();
   }
 }
 /**
  * Returns <code>true</code> if the receiver is grayed, and false otherwise. When the parent does
  * not have the <code>CHECK</code> style, return false.
  *
  * @return the grayed state of the checkbox
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public boolean getGrayed() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   boolean result = false;
   if ((parent.style & SWT.CHECK) != 0) {
     result = grayed;
   }
   return result;
 }
  public Shell open(Display display) {
    shell = new Shell(display);
    shell.setLayout(new FillLayout());
    shell.addShellListener(
        new ShellAdapter() {
          @Override
          public void shellClosed(ShellEvent e) {
            e.doit = closeAddressBook();
          }
        });

    createMenuBar();

    searchDialog = new SearchDialog(shell);
    searchDialog.setSearchAreaNames(columnNames);
    searchDialog.setSearchAreaLabel(resAddressBook.getString("Column"));
    searchDialog.addFindListener(
        new FindListener() {
          public boolean find() {
            return findEntry();
          }
        });

    table = new Table(shell, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
    table.setHeaderVisible(true);
    table.setMenu(createPopUpMenu());
    table.addSelectionListener(
        new SelectionAdapter() {
          @Override
          public void widgetDefaultSelected(SelectionEvent e) {
            TableItem[] items = table.getSelection();
            if (items.length > 0) editEntry(items[0]);
          }
        });
    for (int i = 0; i < columnNames.length; i++) {
      TableColumn column = new TableColumn(table, SWT.NONE);
      column.setText(columnNames[i]);
      column.setWidth(150);
      final int columnIndex = i;
      column.addSelectionListener(
          new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
              sort(columnIndex);
            }
          });
    }

    newAddressBook();

    shell.setSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, 300);
    shell.open();
    return shell;
  }
 /**
  * Returns the text stored at the given column index in the receiver, or empty string if the text
  * has not been set.
  *
  * @param index the column index
  * @return the text stored at the given column index in the receiver
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public String getText(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   String result = "";
   if (data != null && index >= 0 && index < data.length && data[index] != null) {
     result = data[index].text;
   }
   return result;
 }
 private int getLeft(final int index) {
   int result = 0;
   int columnCount = parent.getColumnCount();
   if (index == 0 && columnCount == 0) {
     result = getCheckWidth(index) - parent.leftOffset;
   } else if (index >= 0 && index < columnCount) {
     // TODO [rh] consider applying the leftOffset already in Column#getLeft()
     int columnLeft = parent.getColumn(index).getLeft();
     result = getCheckWidth(index) + columnLeft - parent.leftOffset;
   }
   return result;
 }
 /**
  * Returns the foreground color that the receiver will use to draw.
  *
  * @return the receiver's foreground color
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Color getForeground() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Color result;
   if (foreground == null) {
     result = parent.getForeground();
   } else {
     result = foreground;
   }
   return result;
 }
 /**
  * Returns a rectangle describing the size and location relative to its parent of an image at a
  * column in the table. An empty rectangle is returned if index exceeds the index of the table's
  * last column.
  *
  * @param index the index that specifies the column
  * @return the receiver's bounding image rectangle
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Rectangle getImageBounds(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   int itemIndex = parent.indexOf(this);
   Rectangle cellPadding = parent.getCellPadding();
   int left = getLeft(index) + cellPadding.x;
   int top = getTop(itemIndex);
   int width = getImageWidth(index);
   int height = getHeight(index);
   return new Rectangle(left, top, width, height);
 }
 /**
  * Returns the font that the receiver will use to paint textual information for this item.
  *
  * @return the receiver's font
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Font getFont() {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Font result;
   if (font == null) {
     result = parent.getFont();
   } else {
     result = font;
   }
   return result;
 }
  private void sort(int column) {
    if (table.getItemCount() <= 1) return;

    TableItem[] items = table.getItems();
    String[][] data = new String[items.length][table.getColumnCount()];
    for (int i = 0; i < items.length; i++) {
      for (int j = 0; j < table.getColumnCount(); j++) {
        data[i][j] = items[i].getText(j);
      }
    }

    Arrays.sort(data, new RowComparator(column));

    if (lastSortColumn != column) {
      table.setSortColumn(table.getColumn(column));
      table.setSortDirection(SWT.DOWN);
      for (int i = 0; i < data.length; i++) {
        items[i].setText(data[i]);
      }
      lastSortColumn = column;
    } else {
      // reverse order if the current column is selected again
      table.setSortDirection(SWT.UP);
      int j = data.length - 1;
      for (int i = 0; i < data.length; i++) {
        items[i].setText(data[j--]);
      }
      lastSortColumn = -1;
    }
  }
 /**
  * Sets the font that the receiver will use to paint textual information for this item to the font
  * specified by the argument, or to the default font for that kind of control if the argument is
  * null.
  *
  * @param font the new font (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setFont(final Font font) {
   checkWidget();
   if (font != null && font.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   if (!equals(this.font, font)) {
     this.font = font;
     markCached();
     if (parent.getColumnCount() == 0) {
       parent.updateScrollBars();
     }
     parent.redraw();
   }
 }
 /**
  * Returns the font that the receiver will use to paint textual information for the specified cell
  * in this item.
  *
  * @param index the column index
  * @return the receiver's font
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Font getFont(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Font result = getFont();
   if (data != null
       && index >= 0
       && index < data.length
       && data[index] != null
       && data[index].font != null) {
     result = data[index].font;
   }
   return result;
 }
 /**
  * Sets the font that the receiver will use to paint textual information for the specified cell in
  * this item to the font specified by the argument, or to the default font for that kind of
  * control if the argument is null.
  *
  * @param index the column index
  * @param font the new font (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setFont(final int index, final Font font) {
   checkWidget();
   if (font != null && font.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!equals(font, data[index].font)) {
       data[index].font = font;
       markCached();
       parent.redraw();
     }
   }
 }
 /**
  * Returns the foreground color at the given column index in the receiver.
  *
  * @param index the column index
  * @return the foreground color
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public Color getForeground(final int index) {
   checkWidget();
   if (!parent.checkData(this, parent.indexOf(this))) {
     error(SWT.ERROR_WIDGET_DISPOSED);
   }
   Color result = getForeground();
   if (data != null
       && index >= 0
       && index < data.length
       && data[index] != null
       && data[index].foreground != null) {
     result = data[index].foreground;
   }
   return result;
 }
 /**
  * Sets the foreground color at the given column index in the receiver to the color specified by
  * the argument, or to the default system color for the item if the argument is null.
  *
  * @param index the column index
  * @param color the new color (or null)
  * @exception IllegalArgumentException
  *     <ul>
  *       <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed
  *     </ul>
  *
  * @exception SWTException
  *     <ul>
  *       <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  *       <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  *     </ul>
  */
 public void setForeground(final int index, final Color color) {
   checkWidget();
   if (color != null && color.isDisposed()) {
     error(SWT.ERROR_INVALID_ARGUMENT);
   }
   int count = Math.max(1, parent.getColumnCount());
   if (index >= 0 && index < count) {
     ensureData(index, count);
     if (!equals(data[index].foreground, color)) {
       data[index].foreground = color;
       markCached();
       parent.redraw();
     }
   }
 }
 void _resize() {
   if (row == null) {
     setBounds(-200, -200, 0, 0);
   } else {
     int columnIndex = column == null ? 0 : table.indexOf(column);
     setBounds(row.getBounds(columnIndex));
   }
 }
 private int getImageWidth(final int index) {
   int result = 0;
   Image image = getImage(index);
   if (image != null) {
     result = parent.getItemImageSize().x;
   }
   return result;
 }
 private int getTextWidth(final int index) {
   int result = 0;
   String text = getText(index);
   if (text.length() > 0) {
     result = Graphics.stringExtent(parent.getFont(), text).x;
   }
   return result;
 }
  void onDispose(Event event) {
    removeListener(SWT.Dispose, listener);
    notifyListeners(SWT.Dispose, event);
    event.type = SWT.None;

    table.removeListener(SWT.FocusIn, tableListener);
    table.removeListener(SWT.MouseDown, tableListener);
    unhookRowColumnListeners();
    ScrollBar hBar = table.getHorizontalBar();
    if (hBar != null) {
      hBar.removeListener(SWT.Selection, resizeListener);
    }
    ScrollBar vBar = table.getVerticalBar();
    if (vBar != null) {
      vBar.removeListener(SWT.Selection, resizeListener);
    }
  }
  private void sort(int column) {
    if (table.getItemCount() <= 1) return;

    TableItem[] items = table.getItems();
    String[][] data = new String[items.length][table.getColumnCount()];
    for (int i = 0; i < items.length; i++) {
      for (int j = 0; j < table.getColumnCount(); j++) {
        data[i][j] = items[i].getText(j);
      }
    }

    Arrays.sort(data, new RowComparator(column));

    for (int i = 0; i < data.length; i++) {
      items[i].setText(data[i]);
    }
  }
  private boolean save() {
    if (file == null) return saveAs();

    Cursor waitCursor = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
    shell.setCursor(waitCursor);

    TableItem[] items = table.getItems();
    String[] lines = new String[items.length];
    for (int i = 0; i < items.length; i++) {
      String[] itemText = new String[table.getColumnCount()];
      for (int j = 0; j < itemText.length; j++) {
        itemText[j] = items[i].getText(j);
      }
      lines[i] = encodeLine(itemText);
    }

    FileWriter fileWriter = null;
    try {
      fileWriter = new FileWriter(file.getAbsolutePath(), false);
      for (int i = 0; i < lines.length; i++) {
        fileWriter.write(lines[i]);
      }
    } catch (FileNotFoundException e) {
      displayError(resMessages.getString("File_not_found") + "\n" + file.getName());
      return false;
    } catch (IOException e) {
      displayError(resMessages.getString("IO_error_write") + "\n" + file.getName());
      return false;
    } finally {
      shell.setCursor(null);
      waitCursor.dispose();

      if (fileWriter != null) {
        try {
          fileWriter.close();
        } catch (IOException e) {
          displayError(resMessages.getString("IO_error_close") + "\n" + file.getName());
          return false;
        }
      }
    }

    shell.setText(resMessages.getString("Title_bar") + file.getName());
    isModified = false;
    return true;
  }