| package org.eclipse.swt.widgets;
|
|
|
| /*
|
| * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. |
| * This file is made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html
|
| */
|
|
|
| import org.eclipse.swt.events.*;
|
| import org.eclipse.swt.graphics.*;
|
| import org.eclipse.swt.*;
|
| import java.util.Enumeration;
|
| import java.util.Vector;
|
|
|
| /**
|
| * Instances of this class implement a selectable user interface
|
| * object that displays a list of images and strings and issue
|
| * notificiation when selected.
|
| * <p>
|
| * The item children that may be added to instances of this class
|
| * must be of type <code>TableItem</code>.
|
| * </p><p>
|
| * Note that although this class is a subclass of <code>Composite</code>,
|
| * it does not make sense to add <code>Control</code> children to it,
|
| * or set a layout on it.
|
| * </p><p>
|
| * <dl>
|
| * <dt><b>Styles:</b></dt>
|
| * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION</dd>
|
| * <dt><b>Events:</b></dt>
|
| * <dd>Selection, DefaultSelection</dd>
|
| * </dl>
|
| * <p>
|
| * Note: Only one of the styles SINGLE, and MULTI may be specified.
|
| * </p><p>
|
| * IMPORTANT: This class is <em>not</em> intended to be subclassed.
|
| * </p>
|
| */ |
| public class Table extends SelectableItemWidget {
|
| private static final int COLUMN_RESIZE_OFFSET = 7; // offset from the start and end of each
|
| // column at which the resize cursor is displayed
|
| // if the mouse is in the column header
|
| static final String DOT_STRING = "..."; // used to indicate truncated item labels
|
|
|
| private Header tableHeader;
|
| private Vector items;
|
| private Vector columns;
|
| private boolean drawGridLines = false;
|
| private boolean firstColumnImage = false; // true if any item in the first column has an image
|
| private int columnResizeX; // last position of the cursor in a column resize operation
|
| private Cursor columnResizeCursor; // cursor displayed when a column resize is in progress.
|
| // Need to keep reference to the cursor in order to dispose it.
|
| private boolean isColumnResizeCursor = false; // set to true if the column resize cursor is active
|
| private TableColumn resizeColumn; // column that is currently being resized
|
| private TableColumn fillColumn; // column used to fill up space that is not used
|
| // by user defined columns
|
| private TableColumn defaultColumn; // Default column that is created as soon as the table is created.
|
| // Fix for 1FUSJY5
|
| private int dotsWidth; // width of the static String dots (see above)
|
| private int fontHeight; // font height, avoid use GC.stringExtend for each pain
|
|
|
| /**
|
| * Constructs a new instance of this class given its parent
|
| * and a style value describing its behavior and appearance.
|
| * <p>
|
| * The style value is either one of the style constants defined in
|
| * class <code>SWT</code> which is applicable to instances of this
|
| * class, or must be built by <em>bitwise OR</em>'ing together
|
| * (that is, using the <code>int</code> "|" operator) two or more
|
| * of those <code>SWT</code> style constants. The class description
|
| * lists the style constants that are applicable to the class.
|
| * Style bits are also inherited from superclasses.
|
| * </p>
|
| *
|
| * @param parent a composite control which will be the parent of the new instance (cannot be null)
|
| * @param style the style of control to construct
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
|
| * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
|
| * </ul>
|
| *
|
| * @see SWT#SINGLE
|
| * @see SWT#MULTI
|
| * @see SWT#CHECK
|
| * @see SWT#FULL_SELECTION
|
| * @see SWT#HIDE_SELECTION
|
| * @see Widget#checkSubclass
|
| * @see Widget#getStyle
|
| */ |
| public Table(Composite parent, int style) {
|
| // use NO_REDRAW_RESIZE to avoid flashing during widget resize redraw
|
| super(parent, checkStyle(style| SWT.NO_REDRAW_RESIZE));
|
| }
|
|
|
| /**
|
| * Add 'column' to the receiver.
|
| * @param column - new table column that should be added to
|
| * the receiver
|
| */ |
| void addColumn(TableColumn column) {
|
| int index = column.getIndex();
|
|
|
| getColumnVector().insertElementAt(column, index);
|
| // has the column been inserted (vs. appended)?
|
| if (index < getColumnCount() - 1) {
|
| reindexColumns(index + 1);
|
| }
|
| // is there more than one user created column?
|
| // There always is the data and visual of the default column
|
| // so we don't need to create those for the first user column
|
| if (getColumnCount() > 1) {
|
| insertColumnData(column);
|
| }
|
| else { // first user created column
|
| setContentWidth(0); // pretend it's ground zero for column resizings
|
| redraw(); // redraw the table and header. The default column
|
| getHeader().redraw(); // won't be drawn anymore, because there now is a user created table.
|
| }
|
| insertColumnVisual(column);
|
| }
|
| /**
|
| * Add 'item' to the receiver.
|
| * @param item - new table item that should be added to
|
| * the receiver
|
| * @param index - position the new item should be inserted at
|
| */ |
| void addItem(TableItem item, int index) {
|
| Vector items = getItemVector();
|
|
|
| if (index < 0 || index > getItemCount()) {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
| addingItem(item, index);
|
| item.setIndex(index);
|
| if (index < items.size()) {
|
| for (int i = index; i < items.size(); i++) {
|
| TableItem anItem = (TableItem) items.elementAt(i);
|
| anItem.setIndex(anItem.getIndex() + 1);
|
| }
|
| items.insertElementAt(item, index);
|
| }
|
| else {
|
| items.addElement(item);
|
| }
|
| addedItem(item, index);
|
| }
|
| /**
|
| * Adds the listener to the collection of listeners who will
|
| * be notified when the receiver's selection changes, by sending
|
| * it one of the messages defined in the <code>SelectionListener</code>
|
| * interface.
|
| * <p>
|
| * When <code>widgetSelected</code> is called, the item field of the event object is valid.
|
| * If the reciever has <code>SWT.CHECK</code> style set and the check selection changes,
|
| * the event object detail field contains the value <code>SWT.CHECK</code>.
|
| * <code>widgetDefaultSelected</code> is typically called when an item is double-clicked.
|
| * The item field of the event object is valid for default selection, but the detail field is not used.
|
| * </p>
|
| *
|
| * @param listener the listener which should be notified
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see SelectionListener
|
| * @see #removeSelectionListener
|
| * @see SelectionEvent
|
| */ |
| public void addSelectionListener (SelectionListener listener) {
|
| checkWidget();
|
| if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| TypedListener typedListener = new TypedListener(listener);
|
| addListener(SWT.Selection,typedListener);
|
| addListener(SWT.DefaultSelection,typedListener);
|
| }
|
| static int checkStyle (int style) {
|
| return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
|
| }
|
| protected void checkSubclass () {
|
| if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
|
| }
|
| /**
|
| * The width of 'column' is about to change.
|
| * Adjust the position of all columns behind it.
|
| */ |
| void columnChange(TableColumn column, Rectangle newBounds) {
|
| Rectangle columnBounds = column.getBounds();
|
| Rectangle clientArea = getClientArea();
|
| int oldXPosition = columnBounds.x + columnBounds.width;
|
| int newXPosition = newBounds.x + newBounds.width;
|
| int widthChange = newBounds.width - columnBounds.width;
|
| int headerHeight = getHeaderHeight();
|
| int columnIndex = column.getIndex();
|
|
|
| if (widthChange != 0) {
|
| getHeader().widthChange(columnIndex, widthChange);
|
| if (columnIndex != TableColumn.FILL) {
|
| if (getLinesVisible() == true) {
|
| oldXPosition -= getGridLineWidth(); // include vertical grid line when scrolling resized column.
|
| newXPosition -= getGridLineWidth();
|
| }
|
| scroll( // physically move all following columns
|
| newXPosition, headerHeight, // destination x, y
|
| oldXPosition, headerHeight, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| }
|
| column.internalSetBounds(newBounds);
|
| if (columnIndex != TableColumn.FILL) {
|
| resetTableItems(columnIndex);
|
| moveColumns(columnIndex + 1, widthChange); // logically move all following columns (set their bounds)
|
| setContentWidth(getContentWidth() + widthChange); // set the width of the receiver's content
|
| claimRightFreeSpace();
|
| resizeRedraw(column, columnBounds.width, newBounds.width);
|
| }
|
| }
|
| }
|
| /**
|
| * The mouse pointer was double clicked on the receiver.
|
| * Handle the event according to the position of the mouse click
|
| * and the modifier key that was pressed, if any.
|
| * @param event - the mouse event
|
| */ |
| void columnMouseDoubleClick(Event event) {
|
| int itemHeight = getItemHeight();
|
| int itemIndex;
|
| TableItem hitItem;
|
| TableColumn hitColumn = getColumnAtX (event.x);
|
| Event columnDblClickEvent;
|
| boolean isFullSelection = (getStyle () & SWT.FULL_SELECTION) != 0;
|
|
|
| if (isFocusControl () == false) {
|
| forceFocus ();
|
| }
|
| if (hitColumn != null) {
|
| itemIndex = (event.y - getHeaderHeight()) / itemHeight + getTopIndex();
|
| hitItem = (TableItem) getVisibleItem(itemIndex);
|
| if (hitItem != null &&
|
| (hitColumn.getIndex() == TableColumn.FIRST || isFullSelection)) {
|
| if (hitItem.isSelectionHit(event.x) == true) {
|
| columnDblClickEvent = new Event();
|
| columnDblClickEvent.item = hitItem;
|
| notifyListeners(SWT.DefaultSelection, columnDblClickEvent);
|
| }
|
| }
|
| }
|
| }
|
| /**
|
| * The mouse pointer was pressed down on the receiver.
|
| * Handle the event according to the position of the mouse click
|
| * and the modifier key that was pressed, if any.
|
| * @param event - the mouse event
|
| */ |
| void columnMouseDown(Event event) {
|
| int itemHeight = getItemHeight();
|
| int itemIndex;
|
| TableItem hitItem;
|
| TableColumn hitColumn = getColumnAtX (event.x);
|
|
|
| // only react to button one clicks. fixes bug 6770
|
| if (event.button != 1) {
|
| return;
|
| }
|
| if (isFocusControl () == false) {
|
| forceFocus ();
|
| }
|
| if (hitColumn != null) {
|
| itemIndex = (event.y - getHeaderHeight()) / itemHeight + getTopIndex();
|
| hitItem = (TableItem) getVisibleItem(itemIndex);
|
| if (hitItem != null) {
|
| if (hitItem.isSelectionHit(event.x) == true) {
|
| doMouseSelect(hitItem, itemIndex, event.stateMask, event.button);
|
| }
|
| else
|
| if (hitItem.isCheckHit(new Point(event.x, event.y)) == true) {
|
| doCheckItem(hitItem);
|
| }
|
| }
|
| }
|
| }
|
| /**
|
| * The mouse pointer was moved over the receiver.
|
| * Reset the column resize cursor if it was active.
|
| * @param event - the mouse event
|
| */ |
| void columnMouseMove(Event event) {
|
| if (isColumnResizeStarted() == false) {
|
| setColumnResizeCursor(false);
|
| }
|
| }
|
| public Point computeSize(int wHint, int hHint, boolean changed) {
|
| checkWidget();
|
| Point size = super.computeSize(wHint, hHint, changed);
|
| Point headerSize;
|
| GC gc;
|
| final int WidthCalculationCount = Math.min(getItemCount(), 50); // calculate item width for the first couple of items only
|
| TableItem item;
|
| Image itemImage;
|
| String itemText;
|
| int width;
|
| int newItemWidth = 0;
|
|
|
| if (getHeaderVisible() == true) {
|
| headerSize = getHeader().computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
|
| size.y += headerSize.y;
|
| }
|
| if (getContentWidth() == 0 && WidthCalculationCount > 0) {
|
| gc = new GC(this);
|
| for (int i = 0; i < WidthCalculationCount; i++) {
|
| item = getItem(i);
|
| if (item == null) {
|
| break; // no more items
|
| }
|
| itemImage = item.getImage();
|
| itemText = item.getText();
|
| width = 0;
|
| if (itemImage != null) {
|
| width += itemImage.getBounds().width;
|
| }
|
| if (itemText != null) {
|
| width += gc.stringExtent(itemText).x;
|
| }
|
| newItemWidth = Math.max(newItemWidth, width);
|
| }
|
| if (newItemWidth > 0) {
|
| size.x = newItemWidth;
|
| }
|
| gc.dispose();
|
| }
|
| return size;
|
| }
|
| /**
|
| * Deselects the items at the given zero-relative indices in the receiver.
|
| * If the item at the given zero-relative index in the receiver
|
| * is selected, it is deselected. If the item at the index
|
| * was not selected, it remains deselected. Indices that are out
|
| * of range and duplicate indices are ignored.
|
| *
|
| * @param indices the array of indices for the items to deselect
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void deselect(int indices[]) {
|
| checkWidget();
|
| SelectableItem item = null;
|
|
|
| if (indices == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| for (int i = 0; i < indices.length; i++) {
|
| item = getVisibleItem(indices[i]);
|
| if (item != null) {
|
| deselect(item);
|
| }
|
| }
|
| if (item != null) {
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Deselects the item at the given zero-relative index in the receiver.
|
| * If the item at the index was already deselected, it remains
|
| * deselected. Indices that are out of range are ignored.
|
| *
|
| * @param index the index of the item to deselect
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void deselect(int index) {
|
| checkWidget();
|
| SelectableItem item = getVisibleItem(index);
|
|
|
| if (item != null) {
|
| deselect(item);
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Deselects the items at the given zero-relative indices in the receiver.
|
| * If the item at the given zero-relative index in the receiver
|
| * is selected, it is deselected. If the item at the index
|
| * was not selected, it remains deselected. The range of the
|
| * indices is inclusive. Indices that are out of range are ignored.
|
| *
|
| * @param start the start index of the items to deselect
|
| * @param end the end index of the items to deselect
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void deselect(int start, int end) {
|
| checkWidget();
|
| SelectableItem item = null;
|
|
|
| for (int i=start; i<=end; i++) {
|
| item = getVisibleItem(i);
|
| if (item != null) {
|
| deselect(item);
|
| }
|
| }
|
| if (item != null) {
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Deselects all selected items in the receiver.
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void deselectAll() {
|
| checkWidget();
|
|
|
| deselectAllExcept((SelectableItem) null);
|
| }
|
| /**
|
| * Free resources.
|
| */ |
| void doDispose() {
|
| Vector items = getItemVector();
|
|
|
| super.doDispose();
|
| for (int i = items.size() - 1; i >= 0; i--) {
|
| ((TableItem) items.elementAt(i)).dispose();
|
| }
|
| setItemVector(null);
|
| items = getColumnVector();
|
| while (items.size() > 0) { // TableColumn objects are removed from vector during dispose()
|
| ((TableColumn) items.lastElement()).dispose();
|
| }
|
| resizeColumn = null;
|
| fillColumn = null;
|
| defaultColumn = null;
|
| if (columnResizeCursor != null) {
|
| columnResizeCursor.dispose();
|
| }
|
| }
|
| /**
|
| * Draw a line tracking the current position of a column
|
| * resize operation.
|
| * @param xPosition - x coordinate to draw the line at
|
| */ |
| void drawColumnResizeLine(int xPosition) {
|
| GC gc = new GC(this);
|
| int lineHeight = getClientArea().height;
|
| int lineWidth = getGridLineWidth();
|
|
|
| redraw(getColumnResizeX() - lineWidth, 0, 1, lineHeight, false);
|
| setColumnResizeX(xPosition);
|
| gc.drawLine(xPosition - lineWidth, 0, xPosition - lineWidth, lineHeight);
|
| gc.dispose();
|
| }
|
| /**
|
| * Draw the grid lines for the receiver.
|
| * @param event - Paint event triggering the drawing operation.
|
| * @param drawColumns - The table columns for which the grid
|
| * lines should be drawn.
|
| */ |
| void drawGridLines(Event event, Enumeration drawColumns) {
|
| GC gc = event.gc;
|
| Color oldForeground = getForeground();
|
| Rectangle columnBounds;
|
| TableColumn column;
|
| int lineWidth = getGridLineWidth();
|
| int itemHeight = getItemHeight();
|
| int headerHeight = getHeaderHeight();
|
| int lineXPosition;
|
| int lineYPosition = headerHeight + ((event.y-headerHeight) / itemHeight) * itemHeight;
|
| int lineYStopPosition = event.y + event.height;
|
|
|
| gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
|
| // Draw the horizontal lines
|
| if (itemHeight > 0) {
|
| while (lineYPosition < lineYStopPosition) {
|
| gc.drawLine(
|
| event.x, lineYPosition + itemHeight - lineWidth,
|
| event.x + event.width, lineYPosition + itemHeight - lineWidth);
|
| lineYPosition += itemHeight;
|
| }
|
| }
|
| // Draw the vertical lines at the right border of each column except the fill column
|
| while (drawColumns.hasMoreElements() == true) {
|
| column = (TableColumn) drawColumns.nextElement();
|
| if (column.getIndex() != TableColumn.FILL) {
|
| columnBounds = column.getBounds();
|
| lineXPosition = columnBounds.x + columnBounds.width - lineWidth;
|
| gc.drawLine(
|
| lineXPosition, event.y,
|
| lineXPosition, event.y + event.height);
|
| }
|
| }
|
| gc.setForeground(oldForeground);
|
| }
|
|
|
| /**
|
| * If the receiver has input focus draw a rectangle enclosing
|
| * the label of 'item' to indicate the input focus.
|
| * The rectangle is drawn in either the first column or in all columns
|
| * for full row select.
|
| * @param item - item for which the selection state should be drawn
|
| * @param gc - GC to draw on.
|
| */ |
| void drawSelectionFocus(TableItem item, GC gc) {
|
| Point extent = item.getSelectionExtent();
|
| Point position = new Point(
|
| item.getImageStopX(TableColumn.FIRST) + getHorizontalOffset(),
|
| getRedrawY(item));
|
|
|
| gc.drawFocus(position.x, position.y, extent.x, extent.y);
|
| }
|
|
|
| /**
|
| * Returns the column at the given, zero-relative index in the
|
| * receiver. Throws an exception if the index is out of range.
|
| * If no <code>TableColumn</code>s were created by the programmer,
|
| * this method will throw <code>ERROR_INVALID_RANGE</code> despite
|
| * the fact that a single column of data may be visible in the table.
|
| * This occurs when the programmer uses the table like a list, adding
|
| * items but never creating a column.
|
| *
|
| * @param index the index of the column to return
|
| * @return the column at the given index
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableColumn getColumn(int index) {
|
| checkWidget();
|
| Vector columns = getColumnVector();
|
|
|
| if (columns == null) error(SWT.ERROR_CANNOT_GET_ITEM);
|
| if (index < 0 || index >= columns.size()) {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
|
|
| return (TableColumn) columns.elementAt(index);
|
| }
|
| /**
|
| * Return the column located at 'xPosition' in the widget.
|
| * Return null if xPosition is outside the widget.
|
| * @param xPosition - position of the desired column
|
| */ |
| TableColumn getColumnAtX(int xPosition) {
|
| Enumeration columns = internalGetColumnVector().elements();
|
| TableColumn column;
|
| TableColumn hitColumn = null;
|
| Rectangle bounds;
|
|
|
| while (columns.hasMoreElements() == true && hitColumn == null) {
|
| column = (TableColumn) columns.nextElement();
|
| bounds = column.getBounds();
|
| if ((xPosition >= bounds.x) &&
|
| (xPosition <= bounds.x + bounds.width)) {
|
| hitColumn = column;
|
| }
|
| }
|
| if (hitColumn == null) {
|
| column = getFillColumn();
|
| bounds = column.getBounds();
|
| if ((xPosition >= bounds.x) &&
|
| (xPosition <= bounds.x + bounds.width)) {
|
| hitColumn = column;
|
| }
|
| }
|
| return hitColumn;
|
| }
|
| /**
|
| * Returns the number of columns contained in the receiver.
|
| * If no <code>TableColumn</code>s were created by the programmer,
|
| * this value is zero, despite the fact that visually, one column
|
| * of items is may be visible. This occurs when the programmer uses
|
| * the table like a list, adding items but never creating a column.
|
| *
|
| * @return the number of columns
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| * @exception SWTError <ul>
|
| * <li>ERROR_CANNOT_GET_COUNT - if the operation fails because of an operating system failure</li>
|
| * </ul>
|
| */ |
| public int getColumnCount() {
|
| checkWidget();
|
| Vector columns = getColumnVector();
|
| int count = 0;
|
|
|
| if (columns != null) {
|
| count = columns.size();
|
| }
|
| return count;
|
| }
|
| /** Replace CURSOR_SIZEWE with real column resize cursor
|
| * (no standard cursor-have to load from file)
|
| * Answer the cursor displayed during a column resize
|
| * operation.
|
| * Lazy initialize the cursor since it may never be needed.
|
| */ |
| Cursor getColumnResizeCursor() {
|
| if (columnResizeCursor == null) {
|
| columnResizeCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEWE);
|
| }
|
| return columnResizeCursor;
|
| }
|
| /**
|
| * Answer the current position of the mouse cursor during
|
| * a column resize operation.
|
| */ |
| int getColumnResizeX() {
|
| return columnResizeX;
|
| }
|
| /**
|
| * Returns an array of <code>TableColumn</code>s which are the
|
| * columns in the receiver. If no <code>TableColumn</code>s were
|
| * created by the programmer, the array is empty, despite the fact
|
| * that visually, one column of items may be visible. This occurs
|
| * when the programmer uses the table like a list, adding items but
|
| * never creating a column.
|
| * <p>
|
| * Note: This is not the actual structure used by the receiver
|
| * to maintain its list of items, so modifying the array will
|
| * not affect the receiver.
|
| * </p>
|
| *
|
| * @return the items in the receiver
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableColumn [] getColumns() {
|
| checkWidget();
|
| Vector columns = getColumnVector();
|
| TableColumn columnArray[] = new TableColumn[columns.size()];
|
|
|
| columns.copyInto(columnArray);
|
| return columnArray;
|
| }
|
| /**
|
| * Answer a Vector containing all columns of receiver except
|
| * the fill column to the right of all content columns.
|
| */ |
| Vector getColumnVector() {
|
| return columns;
|
| }
|
| /**
|
| * Return the default column that is created as soon as the table
|
| * is created.
|
| * Fix for 1FUSJY5
|
| */ |
| TableColumn getDefaultColumn() {
|
| return defaultColumn;
|
| }
|
| /**
|
| * Answer the width of the replacement String used to indicate
|
| * truncated items.
|
| * Cached to speed up calculation of truncated items.
|
| * @param gc - GC used to measure the width of the replacement
|
| * String
|
| */ |
| int getDotsWidth(GC gc) {
|
| return dotsWidth;
|
| }
|
| /**
|
| * Answer the column used to occupy any space left to the
|
| * right of all the user created columns.
|
| */ |
| TableColumn getFillColumn() {
|
| return fillColumn;
|
| }
|
| /**
|
| * Returns the width in pixels of a grid line.
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getGridLineWidth () {
|
| checkWidget();
|
|
|
| return 1;
|
| }
|
| /**
|
| * Answer the table header widget.
|
| */ |
| Header getHeader() {
|
| return tableHeader;
|
| }
|
| /**
|
| * Returns the height of the receiver's header
|
| *
|
| * @return the height of the header or zero if the header is not visible
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @since 2.0
|
| */ |
| public int getHeaderHeight() {
|
| checkWidget();
|
| Header header = getHeader();
|
| int height = 0;
|
|
|
| if (header.getVisible() == true) {
|
| height = header.getBounds().height;
|
| }
|
| return height;
|
| }
|
| /**
|
| * Returns <code>true</code> if the receiver's header is visible,
|
| * and <code>false</code> otherwise.
|
| * <p>
|
| * If one of the receiver's ancestors is not visible or some
|
| * other condition makes the receiver not visible, this method
|
| * may still indicate that it is considered visible even though
|
| * it may not actually be showing.
|
| * </p>
|
| *
|
| * @return the receiver's header's visibility state
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public boolean getHeaderVisible() {
|
| checkWidget();
|
|
|
| return getHeader().getVisible();
|
| }
|
| /**
|
| * Answer the image extent of 'item'. Use the image of any column.
|
| */ |
| Point getImageExtent(SelectableItem item) {
|
| Image image = null;
|
| Rectangle imageBounds;
|
| Point imageExtent = null;
|
| int columnCount = internalGetColumnCount();
|
|
|
| for (int i = 0; i < columnCount && image == null; i++) {
|
| image = ((TableItem) item).getImage(i);
|
| }
|
| if (image != null) {
|
| imageBounds = image.getBounds();
|
| imageExtent = new Point(imageBounds.width, imageBounds.height);
|
| }
|
| return imageExtent;
|
| }
|
| /**
|
| * Answer the index of 'item' in the receiver.
|
| */ |
| int getIndex(SelectableItem item) {
|
| int index = -1;
|
|
|
| if (item != null && item.getSelectableParent() == this) {
|
| index = ((TableItem) item).getIndex();
|
| }
|
| return index;
|
| }
|
| /**
|
| * Returns the item at the given, zero-relative index in the
|
| * receiver. Throws an exception if the index is out of range.
|
| *
|
| * @param index the index of the item to return
|
| * @return the item at the given index
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableItem getItem(int index) {
|
| checkWidget();
|
|
|
| if (!(0 <= index && index < getItemCount())) {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
| return (TableItem) getVisibleItem(index);
|
| }
|
|
|
| /**
|
| * Returns the item at the given point in the receiver
|
| * or null if no such item exists. The point is in the
|
| * coordinate system of the receiver.
|
| *
|
| * @param point the point used to locate the item
|
| * @return the item at the given point
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableItem getItem(Point point) {
|
| checkWidget();
|
| if (point == null) error(SWT.ERROR_NULL_ARGUMENT);
|
| int headerHeight = getHeaderHeight();
|
| TableColumn column = getColumnAtX(point.x);
|
| TableItem item = null;
|
|
|
| if (column != null && column.getIndex() != TableColumn.FILL && point.y - headerHeight > 0) {
|
| int itemIndex = (point.y - headerHeight) / getItemHeight() + getTopIndex();
|
| item = (TableItem) getVisibleItem(itemIndex);
|
| if (item != null) {
|
| Point itemSize = item.getItemExtent(column);
|
| if (point.x - column.getBounds().x > itemSize.x) {
|
| item = null;
|
| }
|
| }
|
| }
|
| return item;
|
| }
|
| /**
|
| * Returns the number of items contained in the receiver.
|
| *
|
| * @return the number of items
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getItemCount() {
|
| checkWidget();
|
|
|
| return getItemVector().size();
|
| }
|
| /**
|
| * Answer the number of items that can be displayed in the
|
| * client area of the receiver without truncating any items.
|
| */ |
| int getItemCountWhole() {
|
| int clientAreaHeight = Math.max(0, getClientArea().height - getHeaderHeight());
|
|
|
| return clientAreaHeight / getItemHeight();
|
| }
|
| /**
|
| * Returns the height of the area which would be used to
|
| * display <em>one</em> of the items in the receiver's.
|
| *
|
| * @return the height of one item
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getItemHeight() {
|
| checkWidget();
|
|
|
| return super.getItemHeight();
|
| }
|
| /**
|
| * Answer the number of pixels that should be added to the item height.
|
| */ |
| int getItemPadding() {
|
| return getGridLineWidth() + getDisplay().textHighlightThickness + 1;
|
| }
|
| /**
|
| * Returns an array of <code>TableItem</code>s which are the items
|
| * in the receiver.
|
| * <p>
|
| * Note: This is not the actual structure used by the receiver
|
| * to maintain its list of items, so modifying the array will
|
| * not affect the receiver.
|
| * </p>
|
| *
|
| * @return the items in the receiver
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableItem [] getItems() {
|
| checkWidget();
|
| Vector items = getItemVector();
|
| TableItem itemArray[] = new TableItem[items.size()];
|
|
|
| items.copyInto(itemArray);
|
| return itemArray;
|
| }
|
| /**
|
| * Answer all items of the receiver.
|
| */ |
| Vector getItemVector() {
|
| return items;
|
| }
|
| /**
|
| * Returns <code>true</code> if the receiver's lines are visible,
|
| * and <code>false</code> otherwise.
|
| * <p>
|
| * If one of the receiver's ancestors is not visible or some
|
| * other condition makes the receiver not visible, this method
|
| * may still indicate that it is considered visible even though
|
| * it may not actually be showing.
|
| * </p>
|
| *
|
| * @return the visibility state of the lines
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public boolean getLinesVisible() {
|
| checkWidget();
|
|
|
| return drawGridLines;
|
| }
|
| /**
|
| * Answer a Vector containing the columns that need repainting
|
| * based on the 'paintArea'.
|
| * @param paintArea - invalidated rectangle that needs repainting
|
| */ |
| Vector getPaintColumns(Rectangle paintArea) {
|
| Enumeration columns = internalGetColumnVector().elements();
|
| Vector paintColumns = new Vector();
|
| TableColumn column;
|
| Rectangle columnBounds;
|
| int paintAreaRightBorder = paintArea.x + paintArea.width;
|
|
|
| while (columns.hasMoreElements() == true) {
|
| column = (TableColumn) columns.nextElement();
|
| columnBounds = column.getBounds();
|
| if ((columnBounds.x + columnBounds.width >= paintArea.x) && // does the paintArea overlap the current column?
|
| (columnBounds.x <= paintAreaRightBorder)) {
|
| paintColumns.addElement(column);
|
| }
|
| }
|
| return paintColumns;
|
| }
|
| /**
|
| * Return the width of the widest item in the column identified by 'columnIndex'
|
| * @param columnIndex - index of the column whose preferred width should be
|
| * calculated
|
| */ |
| int getPreferredColumnWidth(int columnIndex) {
|
| Enumeration tableItems = getItemVector().elements();
|
| TableItem tableItem;
|
| int width = 0;
|
| int headerWidth;
|
|
|
| if (columnIndex != TableColumn.FILL) {
|
| while (tableItems.hasMoreElements() == true) {
|
| tableItem = (TableItem) tableItems.nextElement();
|
| width = Math.max(width, tableItem.getPreferredWidth(columnIndex));
|
| }
|
| headerWidth = getHeader().getPreferredWidth(columnIndex);
|
| if (width < headerWidth) {
|
| width = headerWidth;
|
| }
|
| }
|
| return width;
|
| }
|
| /**
|
| * Answer the position in the receiver where 'item' is drawn
|
| * @return the y coordinate at which 'item' is drawn.
|
| * Return -1 if 'item' is not an item of the receiver
|
| */ |
| int getRedrawY(SelectableItem item) {
|
| int redrawY = super.getRedrawY(item);
|
|
|
| if (redrawY != -1) {
|
| redrawY += getHeaderHeight();
|
| }
|
| return redrawY;
|
| }
|
| /**
|
| * Answer the column that is being resized or null if no
|
| * resize operation is in progress.
|
| */ |
| TableColumn getResizeColumn() {
|
| return resizeColumn;
|
| }
|
| /**
|
| * Return the positions at which the column identified by 'columnIndex'
|
| * must be redrawn.
|
| * These positions may be different for each item since each item may
|
| * have a different label
|
| * @param columnIndex - the column index
|
| * @param columnWidth - width of the column
|
| * @return the positions at which the column must be redrawn.
|
| * Each item in the widget client area is represented by a slot in
|
| * the array. The item at position 'topIndex' is the first item in
|
| * the array.
|
| */ |
| int [] getResizeRedrawX(int columnIndex, int columnWidth) {
|
| int topIndex = getTopIndex();
|
| int bottomIndex = getBottomIndex();
|
| int resizeRedrawX[];
|
| TableItem item;
|
|
|
| bottomIndex = Math.min(bottomIndex, getItemCount());
|
| resizeRedrawX = new int[bottomIndex-topIndex+1];
|
| for (int i = topIndex; i < bottomIndex; i++) {
|
| item = (TableItem) getVisibleItem(i);
|
| resizeRedrawX[i-topIndex] = item.getDotStartX(columnIndex, columnWidth);
|
| }
|
| return resizeRedrawX;
|
| }
|
| /**
|
| * Returns an array of <code>TableItem</code>s that are currently
|
| * selected in the receiver. An empty array indicates that no
|
| * items are selected.
|
| * <p>
|
| * Note: This is not the actual structure used by the receiver
|
| * to maintain its selection, so modifying the array will
|
| * not affect the receiver.
|
| * </p>
|
| * @return an array representing the selection
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public TableItem [] getSelection() {
|
| checkWidget();
|
| Vector selectionVector = getSelectionVector();
|
| TableItem[] selectionArray = new TableItem[selectionVector.size()];
|
|
|
| selectionVector.copyInto(selectionArray);
|
| sort(selectionArray, 0, selectionArray.length);
|
| return selectionArray;
|
| }
|
|
|
| /**
|
| * Returns the number of selected items contained in the receiver.
|
| *
|
| * @return the number of selected items
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getSelectionCount() {
|
| checkWidget();
|
|
|
| return super.getSelectionCount();
|
| }
|
|
|
| int getFontHeight(){
|
| return fontHeight;
|
| }
|
| /**
|
| * Answer the size of the full row selection rectangle for 'item'.
|
| */ |
| Point getFullSelectionExtent(TableItem item) {
|
| TableColumn lastColumn = (TableColumn) internalGetColumnVector().lastElement();
|
| Point selectionExtent = null;
|
| Rectangle columnBounds;
|
| int xPosition = item.getImageStopX(TableColumn.FIRST);
|
| int gridLineWidth = getGridLineWidth();
|
|
|
| if (lastColumn != null) {
|
| columnBounds = lastColumn.getBounds();
|
| selectionExtent = new Point(
|
| columnBounds.x - getHorizontalOffset() + columnBounds.width - xPosition - gridLineWidth,
|
| getItemHeight());
|
| if (getLinesVisible() == true) {
|
| selectionExtent.y -= gridLineWidth;
|
| }
|
| }
|
| return selectionExtent;
|
| }
|
| /**
|
| * Returns the zero-relative index of the item which is currently
|
| * selected in the receiver, or -1 if no item is selected.
|
| *
|
| * @return the index of the selected item
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getSelectionIndex() {
|
| checkWidget();
|
| int index = -1;
|
|
|
| if (getSelectionCount() > 0) {
|
| index = getIndex(getSelection()[0]);
|
| }
|
| return index;
|
| }
|
| /**
|
| * Returns the zero-relative indices of the items which are currently
|
| * selected in the receiver. The array is empty if no items are selected.
|
| * <p>
|
| * Note: This is not the actual structure used by the receiver
|
| * to maintain its selection, so modifying the array will
|
| * not affect the receiver.
|
| * </p>
|
| * @return the array of indices of the selected items
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int [] getSelectionIndices() {
|
| checkWidget();
|
| TableItem[] items = getSelection();
|
| int indices[] = new int[items.length];
|
|
|
| for (int i = 0; i < items.length; i++) {
|
| indices[i] = getIndex(items[i]);
|
| }
|
| return indices;
|
| }
|
| /**
|
| * Returns the zero-relative index of the item which is currently
|
| * at the top of the receiver. This index can change when items are
|
| * scrolled or new items are added or removed.
|
| *
|
| * @return the index of the top item
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int getTopIndex() {
|
| checkWidget();
|
|
|
| return super.getTopIndex();
|
| }
|
| /**
|
| * Answer the index of 'item' in the receiver.
|
| * Answer -1 if the item is not visible.
|
| * The returned index must refer to a visible item.
|
| * Note:
|
| * Visible in this context does not neccessarily mean that the
|
| * item is displayed on the screen. It only means that the item
|
| * would be displayed if it is located inside the receiver's
|
| * client area.
|
| * Every item in a table widget should be visible.
|
| */ |
| int getVisibleIndex(SelectableItem item) {
|
| return getIndex(item);
|
| }
|
| /**
|
| * Answer the SelectableItem located at 'itemIndex' in the receiver.
|
| * @param itemIndex - location of the SelectableItem object to return
|
| */ |
| SelectableItem getVisibleItem(int itemIndex) {
|
| Vector items = getItemVector();
|
| TableItem item = null;
|
|
|
| if ((items != null) && (itemIndex >= 0) && (itemIndex < items.size())) {
|
| item = (TableItem) items.elementAt(itemIndex);
|
| }
|
| return item;
|
| }
|
| /**
|
| * Answer the y coordinate at which 'item' is drawn.
|
| * @param item - SelectableItem for which the paint position
|
| * should be returned
|
| * @return the y coordinate at which 'item' is drawn.
|
| * Return -1 if 'item' is null or outside the client area
|
| */ |
| int getVisibleRedrawY(SelectableItem item) {
|
| int redrawY = -1;
|
| int index = getTopIndex();
|
| int bottomIndex = getBottomIndex();
|
|
|
| if (item == null) {
|
| return redrawY;
|
| }
|
| while (index < bottomIndex && item.equals(getVisibleItem(index)) == false) {
|
| index++;
|
| }
|
| if (index < bottomIndex) {
|
| redrawY = getRedrawY(item);
|
| }
|
| return redrawY;
|
| }
|
| /**
|
| * Handle the events the receiver is listening to.
|
| */ |
| void handleEvents(Event event) {
|
| switch (event.type) {
|
| case SWT.MouseMove:
|
| if (event.widget == tableHeader) {
|
| headerMouseMove(event);
|
| }
|
| else {
|
| columnMouseMove(event);
|
| }
|
| break;
|
| case SWT.MouseDown:
|
| if (event.widget == tableHeader) {
|
| headerMouseDown(event);
|
| }
|
| else {
|
| columnMouseDown(event);
|
| }
|
| break;
|
| case SWT.MouseDoubleClick:
|
| columnMouseDoubleClick(event);
|
| break;
|
| case SWT.MouseUp:
|
| mouseUp(event);
|
| break;
|
| case SWT.Paint:
|
| paint(event);
|
| break;
|
| default:
|
| super.handleEvents(event);
|
| }
|
| }
|
| /**
|
| * Answer true if any item in the first column has an image.
|
| * Answer false otherwise.
|
| */ |
| boolean hasFirstColumnImage() {
|
| return firstColumnImage;
|
| }
|
| /**
|
| * The mouse pointer was pressed down on the receiver's header
|
| * widget. Start a column resize operation if apropriate.
|
| * @param event - the mouse event that occured over the header
|
| * widget
|
| */ |
| void headerMouseDown(Event event) {
|
| TableColumn column = getColumnAtX(event.x);
|
|
|
| // only react to button one clicks. fixes bug 6770
|
| if (event.button != 1) {
|
| return;
|
| }
|
| if (isColumnResize(event) == true) {
|
| startColumnResize(event);
|
| }
|
| else
|
| if (column != null) {
|
| column.notifyListeners(SWT.Selection, new Event());
|
| }
|
| }
|
| /**
|
| * The mouse pointer was moved over the receiver's header widget.
|
| * If a column is currently being resized a vertical line indicating
|
| * the new position of the resized column is drawn.
|
| * Otherwise, if no column resize operation is in progress, the
|
| * column resize cursor is displayed when the mouse is near the border
|
| * of a column.
|
| */ |
| void headerMouseMove(Event event) {
|
| if (isColumnResizeStarted() == false) { // only check whether cursor is in resize
|
| setColumnResizeCursor(isColumnResize(event)); // area if no resize operation is in progress
|
| }
|
| else
|
| if (event.x >= getResizeColumn().getBounds().x) {
|
| drawColumnResizeLine(event.x);
|
| update(); // looks better if resize line is drawn immediately
|
| }
|
| }
|
| /**
|
| * Searches the receiver's list starting at the first column
|
| * (index 0) until a column is found that is equal to the
|
| * argument, and returns the index of that column. If no column
|
| * is found, returns -1.
|
| *
|
| * @param column the search column
|
| * @return the index of the column
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int indexOf(TableColumn column) {
|
| checkWidget();
|
|
|
| if (column == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| return internalGetColumnVector().indexOf(column);
|
| }
|
| /**
|
| * Searches the receiver's list starting at the first item
|
| * (index 0) until an item is found that is equal to the
|
| * argument, and returns the index of that item. If no item
|
| * is found, returns -1.
|
| *
|
| * @param item the search item
|
| * @return the index of the item
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public int indexOf(TableItem item) {
|
| checkWidget();
|
| if (item == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| return getIndex(item);
|
| }
|
| /**
|
| * Initialize the receiver. Create a header widget and an empty column.
|
| */ |
| void initialize() {
|
| columns = new Vector();
|
| setItemVector(new Vector());
|
| GC gc = new GC(this);
|
| Point extent = gc.stringExtent(DOT_STRING);
|
| dotsWidth = extent.x;
|
| fontHeight = extent.y;
|
| gc.dispose();
|
| tableHeader = new Header(this);
|
| tableHeader.setVisible(false); // SWT table header is invisible by default, too
|
| fillColumn = TableColumn.createFillColumn(this);
|
| setColumnPosition(fillColumn);
|
| defaultColumn = TableColumn.createDefaultColumn(this); // Create the default column. Fix for 1FUSJY5
|
| super.initialize();
|
| }
|
| /**
|
| * Insert the new column 'column' into the table data at position
|
| * 'index'.
|
| */ |
| void insertColumnData(TableColumn column) {
|
| Enumeration tableItems = getItemVector().elements();
|
| TableItem tableItem;
|
|
|
| while (tableItems.hasMoreElements() == true ) {
|
| tableItem = (TableItem) tableItems.nextElement();
|
| tableItem.insertColumn(column);
|
| }
|
| }
|
| /**
|
| * Insert the new column 'column'.
|
| * Set the position and move the following columns to the right.
|
| */ |
| void insertColumnVisual(TableColumn column) {
|
| Rectangle columnBounds = column.getBounds();
|
| Rectangle previousColumnBounds;
|
| int index = column.getIndex();
|
|
|
| if (index > 0) {
|
| previousColumnBounds = getColumn(index - 1).getBounds();
|
| columnBounds.x = previousColumnBounds.x + previousColumnBounds.width;
|
| }
|
| else {
|
| columnBounds.x = 0;
|
| }
|
| column.setBounds(columnBounds);
|
| setColumnPosition(column);
|
| }
|
| /**
|
| * Set event listeners for the receiver.
|
| */ |
| void installListeners() {
|
| Header tableHeader = getHeader();
|
| Listener listener = getListener();
|
|
|
| super.installListeners();
|
| tableHeader.addListener(SWT.MouseMove, listener);
|
| tableHeader.addListener(SWT.MouseDown, listener);
|
| tableHeader.addListener(SWT.MouseUp, listener);
|
|
|
| addListener(SWT.MouseMove, listener);
|
| addListener(SWT.MouseDown, listener);
|
| addListener(SWT.MouseDoubleClick, listener);
|
| addListener(SWT.MouseUp, listener);
|
| addListener(SWT.Paint, listener);
|
| }
|
| /**
|
| * Answer the TableColumn at 'index'.
|
| * If the user has not created any columns the default column is
|
| * returned if index is 0.
|
| * Fix for 1FUSJY5
|
| */ |
| TableColumn internalGetColumn(int index) {
|
| Vector columns = internalGetColumnVector();
|
|
|
| if (columns == null) error(SWT.ERROR_CANNOT_GET_ITEM);
|
| if (index < 0 || index >= columns.size()) {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
|
|
| return (TableColumn) columns.elementAt(index);
|
|
|
| }
|
| /**
|
| * Answer the number of columns in the receiver.
|
| * If the user has not created any columns, 1 is returned since there
|
| * always is a default column.
|
| * Fix for 1FUSJY5
|
| */ |
| int internalGetColumnCount() {
|
| Vector columns = internalGetColumnVector();
|
| int count = 0;
|
|
|
| if (columns != null) {
|
| count = columns.size();
|
| }
|
| return count;
|
| }
|
| /**
|
| * Return a Vector containing all columns of the receiver except
|
| * the fill column to the right of all content columns.
|
| * Return a Vector containing the default column if the user has
|
| * not created any columns.
|
| * Fix for 1FUSJY5
|
| */ |
| Vector internalGetColumnVector() {
|
| Vector internalColumnVector;
|
| TableColumn defaultColumn;
|
|
|
| if (columns.isEmpty() == false) {
|
| internalColumnVector = columns;
|
| }
|
| else {
|
| internalColumnVector = new Vector(1);
|
| defaultColumn = getDefaultColumn();
|
| if (defaultColumn != null) {
|
| internalColumnVector.addElement(defaultColumn);
|
| }
|
| }
|
| return internalColumnVector;
|
| }
|
| /**
|
| * Answer whether the mouse pointer is at a position that can
|
| * start a column resize operation. A column resize can be
|
| * started if the mouse pointer is at either the left or right
|
| * border of a column.
|
| * @param event - mouse event specifying the location of the
|
| * mouse pointer.
|
| */ |
| boolean isColumnResize(Event event) {
|
| TableColumn hotColumn = getColumnAtX(event.x);
|
| if (hotColumn == null) return false;
|
| Rectangle bounds = hotColumn.getBounds();
|
| int hotColumnIndex = hotColumn.getIndex();
|
| int columnX = event.x - bounds.x;
|
| boolean isColumnResize = false;
|
|
|
| if (columnX <= COLUMN_RESIZE_OFFSET && // mouse over left side of column? and
|
| hotColumnIndex != TableColumn.FIRST) { // it's not the first column)
|
| if (hotColumnIndex == TableColumn.FILL) {
|
| hotColumn = (TableColumn) internalGetColumnVector().lastElement();
|
| }
|
| else {
|
| hotColumn = internalGetColumn(hotColumnIndex - 1);
|
| }
|
| isColumnResize = hotColumn.getResizable(); // check whether left column can be resized
|
| }
|
| else
|
| if (columnX >= bounds.width - COLUMN_RESIZE_OFFSET && // mouse over right side of column and
|
| hotColumn != getFillColumn()) { // column is a real one (not the right hand fill column)?
|
| isColumnResize = hotColumn.getResizable(); // check whether column under cursor can be resized
|
| }
|
| return isColumnResize;
|
| }
|
| /**
|
| * Answer whether a column of the receiver is being resized.
|
| */ |
| boolean isColumnResizeStarted() {
|
| return (getResizeColumn() != null);
|
| }
|
| /**
|
| * Returns <code>true</code> if the item is selected,
|
| * and <code>false</code> otherwise. Indices out of
|
| * range are ignored.
|
| *
|
| * @param index the index of the item
|
| * @return the visibility state of the item at the index
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public boolean isSelected(int index) {
|
| checkWidget();
|
| TableItem item = getItem(index);
|
|
|
| return (item != null && item.isSelected() == true);
|
| }
|
| /**
|
| * 'changedItem' has changed. Update the default column width.
|
| * @param changedItem - the item that has changed
|
| */ |
| void itemChanged(SelectableItem changedItem, int repaintStartX, int repaintWidth) {
|
| // call super.itemChanged first to make sure that table image size is
|
| // calculated if necessary. Fixes 1FYPBBG.
|
| super.itemChanged(changedItem, repaintStartX, repaintWidth);
|
| // remember if any item ever had an image in the first column.
|
| if (firstColumnImage == false && changedItem.getImage() != null) {
|
| firstColumnImage = true;
|
| redraw ();
|
| }
|
| setFirstColumnWidth((TableItem) changedItem);
|
| }
|
| /**
|
| * A mouse button was released.
|
| * Update the display if a column has been resized.
|
| * @param event - the mouse event for the button up action
|
| */ |
| void mouseUp(Event event) {
|
| TableColumn resizeColumn = getResizeColumn();
|
| Rectangle oldColumnBounds;
|
| int resizeXPosition;
|
| int widthChange;
|
| if (isColumnResizeStarted() == true) {
|
| oldColumnBounds = resizeColumn.getBounds();
|
| resizeXPosition = getColumnResizeX();
|
| widthChange = resizeXPosition - (oldColumnBounds.x + oldColumnBounds.width);
|
| if (widthChange >= 0) {
|
| redraw(resizeXPosition - getGridLineWidth(), 0, 1, getClientArea().height, false); // remove resize line
|
| update(); // to avoid cheese caused by scrolling the resize line
|
| }
|
| if (widthChange != 0) {
|
| resizeColumn.setWidth(oldColumnBounds.width + widthChange);
|
| }
|
| setResizeColumn(null);
|
| }
|
| }
|
| /**
|
| * Adjust the position of all columns starting at 'startIndex'.
|
| * @param startIndex - index at which the column move should begin
|
| * If this is the index of the fill column all columns are moved,
|
| * including the fill column
|
| * @param moveDistance - distance that the columns should be moved.
|
| * < 0 = columns are going to be moved left.
|
| * > 0 = columns are going to be moved right.
|
| */ |
| void moveColumns(int startIndex, int moveDistance) {
|
| Vector columns = internalGetColumnVector();
|
| TableColumn moveColumn;
|
| Rectangle columnBounds;
|
|
|
| if (startIndex == TableColumn.FILL) {
|
| moveColumn = getFillColumn();
|
| columnBounds = moveColumn.getBounds();
|
| columnBounds.x += moveDistance;
|
| moveColumn.setBounds(columnBounds);
|
| startIndex = 0; // continue with first data column
|
| }
|
| for (int i = startIndex; i < columns.size(); i++) {
|
| moveColumn = (TableColumn) columns.elementAt(i);
|
| columnBounds = moveColumn.getBounds();
|
| columnBounds.x += moveDistance;
|
| moveColumn.setBounds(columnBounds);
|
| }
|
| }
|
| /**
|
| * Adjust the y position of all columns including the fill column.
|
| */ |
| void moveColumnsVertical() {
|
| Enumeration columns = internalGetColumnVector().elements();
|
| TableColumn column;
|
|
|
| setColumnPosition(getFillColumn());
|
| while (columns.hasMoreElements() == true) {
|
| column = (TableColumn) columns.nextElement();
|
| setColumnPosition(column);
|
| }
|
| }
|
| /**
|
| * A paint event has occurred. Paint the invalidated items.
|
| * @param event - paint event specifying the invalidated area.
|
| */ |
| void paint(Event event) {
|
| int visibleRange[];
|
| int headerHeight = getHeaderHeight();
|
| Vector paintColumns = getPaintColumns(event.getBounds());
|
| TableItem focusItem = null;
|
|
|
| if (paintColumns.size() > 0) {
|
| event.y -= headerHeight;
|
| visibleRange = getIndexRange(event.getBounds());
|
| event.y += headerHeight;
|
| // When the top index is > 0 and the receiver is resized
|
| // higher so that the top index becomes 0 the invalidated
|
| // rectangle doesn't start below the header widget but at
|
| // y position 0. Subtraction of the header height (it is
|
| // not above the receiver but on top) causes event.y and
|
| // subsequently visibleRange[0] to be negative.
|
| // Hack to prevent visibleRange[0] from becoming negative.
|
| // Need to find out why the invalidated area starts at 0
|
| // in the first place.
|
| if (visibleRange[0] < 0) {
|
| visibleRange[0] = 0;
|
| }
|
| //
|
| visibleRange[1] = Math.min(visibleRange[1], getItemCount()-1-getTopIndex());
|
| focusItem = paintItems(event, visibleRange[0], visibleRange[1], paintColumns);
|
| }
|
| if (getLinesVisible() == true) {
|
| drawGridLines(event, paintColumns.elements());
|
| }
|
| if (focusItem != null) {
|
| // draw focus on top of drawing grid lines so that focus rectangle
|
| // is not obscured by grid. Fixes 1G5X20B
|
| drawSelectionFocus(focusItem, event.gc);
|
| }
|
| }
|
|
|
| /**
|
| * Paint items of the receiver starting at index 'topPaintIndex' and
|
| * ending at 'bottomPaintIndex'.
|
| * @param event - holds the GC to draw on and the clipping rectangle
|
| * @param topPaintIndex - index of the first item to draw
|
| * @param bottomPaintIndex - index of the last item to draw
|
| * @param paintColumns - the table columns that should be painted
|
| * @return the item that has focus if it was among the rendered items.
|
| * null if the focus item was not rendered or if no item has focus (ie.
|
| * because the widget does not have focus)
|
| */ |
| TableItem paintItems(Event event, int topPaintIndex, int bottomPaintIndex, Vector paintColumns) {
|
| Enumeration columns;
|
| TableColumn column;
|
| TableItem paintItem;
|
| TableItem focusItem = null;
|
| Point selectionExtent;
|
| GC gc = event.gc;
|
| Color selectionColor = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
|
| Point fullSelectionExtent;
|
| int paintXPosition;
|
| int paintYPosition;
|
|
|
| topPaintIndex += getTopIndex();
|
| bottomPaintIndex += getTopIndex();
|
| for (int i = topPaintIndex; i <= bottomPaintIndex; i++) {
|
| paintItem = (TableItem) getVisibleItem(i);
|
| paintXPosition = paintItem.getSelectionX();
|
| paintYPosition = getRedrawY(paintItem);
|
| fullSelectionExtent = getFullSelectionExtent(paintItem);
|
| gc.setBackground(paintItem.getBackground());
|
| gc.fillRectangle(paintXPosition, paintYPosition, fullSelectionExtent.x, fullSelectionExtent.y);
|
|
|
| if (paintItem.isSelected() == true) {
|
| selectionExtent = paintItem.getSelectionExtent();
|
| gc.setBackground(selectionColor);
|
| gc.fillRectangle(paintXPosition, paintYPosition, selectionExtent.x, selectionExtent.y);
|
| }
|
| columns = paintColumns.elements();
|
| while (columns.hasMoreElements() == true) {
|
| column = (TableColumn) columns.nextElement();
|
| paintSubItem(event, paintItem, column, paintYPosition);
|
| }
|
| if (hasFocus(paintItem)) {
|
| focusItem = paintItem;
|
| }
|
| }
|
| return focusItem;
|
| }
|
|
|
| /**
|
| * Paint the table item 'paintItem' in 'column' at y position
|
| * 'paintYPosition' of the receiver.
|
| * @param event - holds the GC to draw on and the clipping
|
| * rectangle.
|
| * @param paintItem - the item to draw
|
| * @param column - column to draw 'paintItem' in
|
| * @param paintYPosition - y position in the receiver to draw
|
| * 'paintItem' at.
|
| */ |
| void paintSubItem(Event event, TableItem paintItem, TableColumn column, int paintYPosition) {
|
| Rectangle columnBounds = column.getBounds();
|
| Point paintPosition;
|
| int gridLineWidth = getGridLineWidth();
|
| int itemDrawStopX = columnBounds.x + columnBounds.width - gridLineWidth;
|
| int clipX;
|
|
|
| if (event.x + event.width > itemDrawStopX) { // does the invalidated area stretch past the current column's right border?
|
| clipX = Math.max(columnBounds.x, event.x);
|
| event.gc.setClipping( // clip the drawing area
|
| clipX, event.y,
|
| Math.max(0, itemDrawStopX - clipX), event.height);
|
| }
|
| paintPosition = new Point(columnBounds.x, paintYPosition);
|
| paintItem.paint(event.gc, paintPosition, column);
|
| if (event.x + event.width > itemDrawStopX) {
|
| event.gc.setClipping(event.x, event.y, event.width, event.height); // restore original clip rectangle
|
| }
|
| }
|
| /**
|
| * Reindex all columns starting at 'startIndex'.
|
| * Reindexing is necessary when a new column has been inserted.
|
| */ |
| void reindexColumns(int startIndex) {
|
| Vector columns = getColumnVector();
|
| TableColumn column;
|
|
|
| for (int i = startIndex; i < getColumnCount(); i++) {
|
| column = (TableColumn) columns.elementAt(i);
|
| column.setIndex(i);
|
| }
|
| }
|
| /**
|
| * Removes the items from the receiver's list at the given
|
| * zero-relative indices.
|
| *
|
| * @param indices the array of indices of the items
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| * @exception SWTError <ul>
|
| * <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
|
| * </ul>
|
| */ |
| public void remove(int indices[]) {
|
| checkWidget();
|
| SelectableItem item;
|
| int [] sortedIndices;
|
| int last = -1;
|
| int sortedIndex;
|
|
|
| if (indices == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| sortedIndices = new int[indices.length];
|
| System.arraycopy (indices, 0, sortedIndices, 0, indices.length);
|
| sort(sortedIndices); // sort indices in descending order
|
| for (int i = 0; i < sortedIndices.length; i++) {
|
| sortedIndex = sortedIndices[i];
|
| if (sortedIndex != last) {
|
| item = getVisibleItem(sortedIndex);
|
| if (item != null) {
|
| item.dispose();
|
| }
|
| else {
|
| if (0 <= sortedIndex && sortedIndex < getItemVector().size()) {
|
| error(SWT.ERROR_ITEM_NOT_REMOVED);
|
| }
|
| else {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
| }
|
| last = sortedIndex;
|
| }
|
| }
|
| }
|
| /**
|
| * Removes the item from the receiver at the given
|
| * zero-relative index.
|
| *
|
| * @param index the index for the item
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| * @exception SWTError <ul>
|
| * <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
|
| * </ul>
|
| */ |
| public void remove(int index) {
|
| checkWidget();
|
| SelectableItem item = getVisibleItem(index);
|
|
|
| if (item != null) {
|
| item.dispose();
|
| }
|
| else {
|
| if (0 <= index && index < getItemVector().size()) {
|
| error(SWT.ERROR_ITEM_NOT_REMOVED);
|
| }
|
| else {
|
| error(SWT.ERROR_INVALID_RANGE);
|
| }
|
| }
|
| }
|
| /**
|
| * Removes the items from the receiver which are
|
| * between the given zero-relative start and end
|
| * indices (inclusive).
|
| *
|
| * @param start the start of the range
|
| * @param end the end of the range
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| * @exception SWTError <ul>
|
| * <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
|
| * </ul>
|
| */ |
| public void remove(int start, int end) {
|
| checkWidget();
|
| SelectableItem item;
|
|
|
| for (int i = end; i >= start; i--) {
|
| item = getVisibleItem(i);
|
| if (item != null) {
|
| item.dispose();
|
| }
|
| else {
|
| error(SWT.ERROR_ITEM_NOT_REMOVED);
|
| }
|
| }
|
| }
|
| /**
|
| * Removes all of the items from the receiver.
|
| * <p>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void removeAll() {
|
| checkWidget();
|
| Vector items = getItemVector();
|
|
|
| setRedraw(false);
|
| setRemovingAll(true);
|
| for (int i = items.size() - 1; i >= 0; i--) {
|
| ((TableItem) items.elementAt(i)).dispose();
|
| }
|
| setItemVector(new Vector());
|
| reset();
|
| calculateVerticalScrollbar();
|
| setRemovingAll(false);
|
| setRedraw(true);
|
| }
|
| /**
|
| * Remove 'column' from the receiver.
|
| */ |
| void removeColumn(TableColumn column) {
|
| int index = column.getIndex();
|
| int columnWidth = column.getWidth();
|
| int columnCount;
|
|
|
| if (isRemovingAll() == true) {
|
| getColumnVector().removeElementAt(index);
|
| }
|
| else {
|
| getColumnVector().removeElementAt(index);
|
| columnCount = getColumnCount();
|
| // Never remove the data of the last user created column.
|
| // SWT for Windows does the same.
|
| if (columnCount > 0) {
|
| removeColumnData(column);
|
| removeColumnVisual(column);
|
| }
|
| else {
|
| redraw();
|
| getHeader().redraw();
|
| }
|
| if (index < columnCount) { // is there a column after the removed one?
|
| reindexColumns(index);
|
| }
|
| // last user created column is about to be removed.
|
| if (columnCount == 0) {
|
| TableColumn defaultColumn = getDefaultColumn();
|
| defaultColumn.pack(); // make sure the default column has the right size...
|
| setColumnPosition(defaultColumn); // ...and is at the right position
|
| }
|
| // Fixes for 1G1L0UT
|
| // Reduce the content width by the width of the removed column
|
| setContentWidth(getContentWidth() - columnWidth);
|
| // claim free space
|
| claimRightFreeSpace();
|
| //
|
| }
|
| }
|
| /**
|
| * Remove the column 'column' from the table data.
|
| */ |
| void removeColumnData(TableColumn column) {
|
| Enumeration tableItems = getItemVector().elements();
|
| TableItem tableItem;
|
|
|
| while (tableItems.hasMoreElements() == true ) {
|
| tableItem = (TableItem) tableItems.nextElement();
|
| tableItem.removeColumn(column);
|
| }
|
| }
|
| /**
|
| * Remove the column 'column'.
|
| * Set the position of the following columns.
|
| */ |
| void removeColumnVisual(TableColumn column) {
|
| int columnWidth = column.getWidth();
|
|
|
| // move following columns to the left
|
| moveColumns(column.getIndex(), columnWidth * -1);
|
| redraw();
|
| getHeader().redraw();
|
| }
|
| /**
|
| * 'item' has been removed from the receiver.
|
| * Update the display and the scroll bars.
|
| */
|
| void removedItem(SelectableItem item) {
|
| int oldHeight = getItemHeight();
|
| super.removedItem (item);
|
| if (getItemCount() == 0 && drawGridLines && oldHeight != getItemHeight()) {
|
| redraw();
|
| }
|
| }
|
| /**
|
| * Remove 'item' from the receiver.
|
| * @param item - item that should be removed from the receiver
|
| */ |
| void removeItem(TableItem item) {
|
| if (isRemovingAll() == true) return;
|
|
|
| Vector items = getItemVector();
|
| int index = items.indexOf(item);
|
| if (index != -1) {
|
| removingItem(item);
|
| items.removeElementAt(index);
|
| for (int i = index; i < items.size(); i++) {
|
| TableItem anItem = (TableItem) items.elementAt(i);
|
| anItem.setIndex(anItem.getIndex() - 1);
|
| }
|
| removedItem(item);
|
| }
|
| }
|
| /**
|
| * Removes the listener from the collection of listeners who will
|
| * be notified when the receiver's selection changes.
|
| *
|
| * @param listener the listener which should no longer be notified
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see SelectionListener
|
| * @see #addSelectionListener
|
| */ |
| public void removeSelectionListener(SelectionListener listener) {
|
| checkWidget();
|
| if (listener == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| removeListener(SWT.Selection, listener);
|
| removeListener(SWT.DefaultSelection, listener);
|
| }
|
| /**
|
| * Reset cached data of column at 'columnIndex' for the items of the receiver.
|
| * @param columnIndex - index of the column for which the item data should be
|
| * reset.
|
| */ |
| void resetTableItems(int columnIndex) {
|
| Enumeration tableItems = getItemVector().elements();
|
| TableItem tableItem;
|
|
|
| while (tableItems.hasMoreElements() == true ) {
|
| tableItem = (TableItem) tableItems.nextElement();
|
| tableItem.reset(columnIndex);
|
| }
|
| }
|
| /**
|
| * The receiver has been resized. Resize the fill column
|
| * and the header widget.
|
| */ |
| void resize(Event event) {
|
| TableColumn fillColumn = getFillColumn();
|
| Rectangle fillColumnBounds;
|
|
|
| super.resize(event);
|
| // the x position may change in super.resize.
|
| // get the column bounds after calling super.resize. Fixes 1G7ALGG
|
| fillColumnBounds = fillColumn.getBounds();
|
| fillColumnBounds.width = Math.max(0, getClientArea().width - getContentWidth());
|
| fillColumn.setBounds(fillColumnBounds);
|
| resizeHeader();
|
| }
|
| /**
|
| * Resize the header widget to occupy the whole width of the
|
| * receiver.
|
| */ |
| void resizeHeader() {
|
| Header tableHeader = getHeader();
|
| Point size = tableHeader.getSize();
|
|
|
| size.x = Math.max(getContentWidth(), getClientArea().width);
|
| tableHeader.setSize(size);
|
| }
|
| /**
|
| * Redraw 'column' after its width has been changed.
|
| * @param column - column whose width has changed.
|
| * @param oldColumnWidth - column width before resize
|
| * @param oldColumnWidth - column width after resize
|
| */ |
| void resizeRedraw(TableColumn column, int oldColumnWidth, int newColumnWidth) {
|
| Rectangle columnBounds = column.getBounds();
|
| int columnIndex = column.getIndex();
|
| int oldRedrawStartX[] = getResizeRedrawX(columnIndex, oldColumnWidth);
|
| int newRedrawStartX[] = getResizeRedrawX(columnIndex, newColumnWidth);
|
| int itemHeight = getItemHeight();
|
| int widthChange = newColumnWidth - oldColumnWidth;
|
| int topIndex = getTopIndex();
|
|
|
| for (int i = 0; i < newRedrawStartX.length; i++) {
|
| if (newRedrawStartX[i] != oldRedrawStartX[i]) {
|
| if (widthChange > 0) {
|
| newRedrawStartX[i] = oldRedrawStartX[i];
|
| }
|
| redraw(
|
| columnBounds.x + newRedrawStartX[i], columnBounds.y + itemHeight * (i + topIndex),
|
| columnBounds.width - newRedrawStartX[i], itemHeight, false);
|
| }
|
| }
|
| }
|
| /**
|
| * Scroll horizontally by 'numPixel' pixel.
|
| * @param numPixel - the number of pixel to scroll
|
| * < 0 = columns are going to be moved left.
|
| * > 0 = columns are going to be moved right.
|
| */ |
| void scrollHorizontal(int numPixel) {
|
| Rectangle clientArea = getClientArea();
|
|
|
| scroll(
|
| numPixel, 0, // destination x, y
|
| 0, 0, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| getHeader().scroll(
|
| numPixel, 0, // destination x, y
|
| 0, 0, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| moveColumns(TableColumn.FILL, numPixel);
|
| }
|
| /**
|
| * Scroll vertically by 'scrollIndexCount' items.
|
| * @param scrollIndexCount - the number of items to scroll.
|
| * scrollIndexCount > 0 = scroll up. scrollIndexCount < 0 = scroll down
|
| */ |
| void scrollVertical(int scrollIndexCount) {
|
| int scrollAmount = scrollIndexCount * getItemHeight();
|
| int headerHeight = getHeaderHeight();
|
| int destY;
|
| int sourceY;
|
| boolean scrollUp = scrollIndexCount < 0;
|
| Rectangle clientArea = getClientArea();
|
|
|
| if (scrollIndexCount == 0) {
|
| return;
|
| }
|
| if (scrollUp == true) {
|
| destY = headerHeight - scrollAmount;
|
| sourceY = headerHeight;
|
| }
|
| else {
|
| destY = headerHeight;
|
| sourceY = destY + scrollAmount;
|
| }
|
| scroll(
|
| 0, destY, // destination x, y
|
| 0, sourceY, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| }
|
| /**
|
| * Scroll items down to make space for a new item added to
|
| * the receiver at position 'index'.
|
| * @param index - position at which space for one new item
|
| * should be made. This index is relative to the first item
|
| * of the receiver.
|
| */ |
| void scrollVerticalAddingItem(int index) {
|
| int itemHeight = getItemHeight();
|
| int sourceY = getHeaderHeight();
|
| Rectangle clientArea = getClientArea();
|
|
|
| if (index >= getTopIndex()) {
|
| sourceY += (index-getTopIndex()) * itemHeight;
|
| }
|
| scroll(
|
| 0, sourceY + itemHeight, // destination x, y
|
| 0, sourceY, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| }
|
| /**
|
| * Scroll the items below the item at position 'index' up
|
| * so that they cover the removed item.
|
| * @param index - index of the removed item
|
| */ |
| void scrollVerticalRemovedItem(int index) {
|
| int itemHeight = getItemHeight();
|
| int headerHeight = getHeaderHeight();
|
| int destY;
|
| Rectangle clientArea = getClientArea();
|
|
|
| destY = Math.max(headerHeight, headerHeight + (index - getTopIndex()) * itemHeight);
|
| scroll(
|
| 0, destY, // destination x, y
|
| 0, destY + itemHeight, // source x, y
|
| clientArea.width, clientArea.height, true);
|
| }
|
| /**
|
| * Selects the items at the given zero-relative indices in the receiver.
|
| * If the item at the given zero-relative index in the receiver
|
| * is not selected, it is selected. If the item at the index
|
| * was selected, it remains selected. Indices that are out
|
| * of range and duplicate indices are ignored.
|
| *
|
| * @param indices the array of indices for the items to select
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void select(int indices[]) {
|
| checkWidget();
|
| SelectableItem item = null;
|
| int selectionCount;
|
|
|
| if (indices == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| selectionCount = indices.length;
|
| if (isMultiSelect() == false && selectionCount > 1) {
|
| selectionCount = 1;
|
| deselectAllExcept(getVisibleItem(indices[0]));
|
| }
|
| for (int i = selectionCount - 1; i >= 0; --i) {
|
| item = getVisibleItem(indices[i]);
|
| if (item != null) {
|
| select(item);
|
| }
|
| }
|
| if (item != null) {
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Selects the item at the given zero-relative index in the receiver.
|
| * If the item at the index was already selected, it remains
|
| * selected. Indices that are out of range are ignored.
|
| *
|
| * @param index the index of the item to select
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void select(int index) {
|
| checkWidget();
|
| SelectableItem item = getVisibleItem(index);
|
|
|
| if (isMultiSelect() == false) {
|
| deselectAllExcept(getVisibleItem(index));
|
| }
|
| if (item != null) {
|
| select(item);
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Selects the items at the given zero-relative indices in the receiver.
|
| * If the item at the index was already selected, it remains
|
| * selected. The range of the indices is inclusive. Indices that are
|
| * out of range are ignored.
|
| *
|
| * @param start the start of the range
|
| * @param end the end of the range
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void select(int start, int end) {
|
| checkWidget();
|
| SelectableItem item = null;
|
|
|
| if (isMultiSelect() == false) {
|
| if (start < 0 && end >= 0) {
|
| start = 0;
|
| }
|
| end = start;
|
| deselectAllExcept(getVisibleItem(end));
|
| }
|
| // select in the same order as all the other selection and deslection methods.
|
| // Otherwise setLastSelection repeatedly changes the lastSelectedItem for repeated
|
| // selections of the items, causing flash.
|
| for (int i = end; i >= start; i--) {
|
| item = getVisibleItem(i);
|
| if (item != null) {
|
| select(item);
|
| }
|
| }
|
| if (item != null) {
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Selects all the items in the receiver.
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void selectAll() {
|
| checkWidget();
|
| Enumeration items = getItemVector().elements();
|
| TableItem item = null;
|
|
|
| if (isMultiSelect() == false) {
|
| return;
|
| }
|
| while (items.hasMoreElements() == true) {
|
| item = (TableItem) items.nextElement();
|
| select(item);
|
| }
|
| if (item != null) {
|
| setLastSelection(item, false);
|
| }
|
| }
|
| /**
|
| * Set the y position of 'column'.
|
| * @param column - the TableColumn that should be set to
|
| * a new y position.
|
| */ |
| void setColumnPosition(TableColumn column) {
|
| Rectangle bounds = column.getBounds();
|
|
|
| bounds.y = getHeaderHeight() - getTopIndex() * getItemHeight();
|
| column.setBounds(bounds);
|
| }
|
| /**
|
| * Change the cursor of the receiver.
|
| * @param isColumnResizeCursor - indicates whether the column
|
| * resize cursor or the regular cursor should be set.
|
| */ |
| void setColumnResizeCursor(boolean isColumnResizeCursor) {
|
| if (isColumnResizeCursor != this.isColumnResizeCursor) {
|
| this.isColumnResizeCursor = isColumnResizeCursor;
|
| if (isColumnResizeCursor == true) {
|
| setCursor(getColumnResizeCursor());
|
| }
|
| else {
|
| setCursor(null);
|
| }
|
| }
|
| }
|
| /**
|
| * Set the current position of the resized column to 'xPosition'.
|
| * @param xPosition - the current position of the resized column
|
| */ |
| void setColumnResizeX(int xPosition) {
|
| columnResizeX = xPosition;
|
| }
|
| /**
|
| * Set the width of the receiver's contents to 'newWidth'.
|
| * Content width is used to calculate the horizontal scrollbar.
|
| */ |
| void setContentWidth(int newWidth) {
|
| TableColumn fillColumn = getFillColumn();
|
| Rectangle fillColumnBounds;
|
| int widthDiff = newWidth - getContentWidth();
|
|
|
| super.setContentWidth(newWidth);
|
| if (fillColumn != null) {
|
| fillColumnBounds = fillColumn.getBounds();
|
| fillColumnBounds.x += widthDiff;
|
| fillColumnBounds.width = Math.max(0, getClientArea().width - newWidth);
|
| fillColumn.setBounds(fillColumnBounds);
|
| }
|
| }
|
| /**
|
| * Set the width of the first column to fit 'item' if it is longer than
|
| * the current column width.
|
| * Do nothing if the user has already set a width.
|
| */ |
| void setFirstColumnWidth(TableItem item) {
|
| int newWidth;
|
| TableColumn column;
|
|
|
| if (internalGetColumnCount() > 0) {
|
| column = internalGetColumn(TableColumn.FIRST);
|
| if (column.isDefaultWidth() == true) {
|
| newWidth = Math.max(column.getWidth(), item.getPreferredWidth(TableColumn.FIRST));
|
| column.setWidth(newWidth);
|
| column.setDefaultWidth(true); // reset to true so that we know when the user has set
|
| // the width instead of us setting a default width.
|
| }
|
| }
|
| }
|
| public void setFont(Font font) {
|
| checkWidget();
|
| int itemCount = getItemCount();
|
|
|
| if (font == null || font.equals(getFont()) == true) {
|
| return;
|
| }
|
| setRedraw(false); // disable redraw because itemChanged() triggers undesired redraw
|
| resetItemData();
|
| super.setFont(font);
|
|
|
| GC gc = new GC(this);
|
| Point extent = gc.stringExtent(DOT_STRING);
|
| dotsWidth = extent.x;
|
| fontHeight = extent.y;
|
| gc.dispose();
|
|
|
| for (int i = 0; i < itemCount; i++) {
|
| itemChanged(getItem(i), 0, getClientArea().width);
|
| }
|
| setRedraw(true); // re-enable redraw
|
| getHeader().setFont(font);
|
| }
|
| /**
|
| * Marks the receiver's header as visible if the argument is <code>true</code>,
|
| * and marks it invisible otherwise.
|
| * <p>
|
| * If one of the receiver's ancestors is not visible or some
|
| * other condition makes the receiver not visible, marking
|
| * it visible may not actually cause it to be displayed.
|
| * </p>
|
| *
|
| * @param visible the new visibility state
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void setHeaderVisible(boolean headerVisible) {
|
| checkWidget();
|
| if (headerVisible != getHeaderVisible()) {
|
| getHeader().setLocation(0, 0);
|
| getHeader().setVisible(headerVisible);
|
| // Windows resets scrolling so do we
|
| setTopIndex(0, true);
|
| moveColumnsVertical();
|
| resizeVerticalScrollbar();
|
| redraw();
|
| }
|
| }
|
| /**
|
| * Set the vector that stores the items of the receiver
|
| * to 'newVector'.
|
| * @param newVector - Vector to use for storing the items of
|
| * the receiver.
|
| */ |
| void setItemVector(Vector newVector) {
|
| items = newVector;
|
| }
|
| /**
|
| * Marks the receiver's lines as visible if the argument is <code>true</code>,
|
| * and marks it invisible otherwise.
|
| * <p>
|
| * If one of the receiver's ancestors is not visible or some
|
| * other condition makes the receiver not visible, marking
|
| * it visible may not actually cause it to be displayed.
|
| * </p>
|
| *
|
| * @param visible the new visibility state
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void setLinesVisible(boolean drawGridLines) {
|
| checkWidget();
|
| if (this.drawGridLines != drawGridLines) {
|
| this.drawGridLines = drawGridLines;
|
| redraw();
|
| }
|
| }
|
| public void setRedraw(boolean redraw) {
|
| checkWidget();
|
| super.setRedraw(redraw);
|
| getHeader().setRedraw(redraw);
|
| }
|
| /**
|
| * Set the column that is being resized to 'column'.
|
| * @param column - the TableColumn that is being resized.
|
| * A null value indicates that no column resize operation is
|
| * in progress.
|
| */ |
| void setResizeColumn(TableColumn column) {
|
| resizeColumn = column;
|
| }
|
| /**
|
| * Selects the items at the given zero-relative indices in the receiver.
|
| * The current selected is first cleared, then the new items are selected.
|
| *
|
| * @param indices the indices of the items to select
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the array of indices is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#deselectAll()
|
| * @see Table#select(int[])
|
| */ |
| public void setSelection(int [] indices) {
|
| checkWidget();
|
| Vector keepSelected;
|
|
|
| if (indices == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| keepSelected = new Vector(indices.length);
|
| for (int i = 0; i < indices.length; i++) {
|
| SelectableItem item = getVisibleItem(indices[i]);
|
| if (item != null) {
|
| keepSelected.addElement(item);
|
| }
|
| }
|
| deselectAllExcept(keepSelected);
|
| select(indices);
|
| showSelection ();
|
| }
|
| /**
|
| * Sets the receiver's selection to be the given array of items.
|
| * The current selected is first cleared, then the new items are
|
| * selected.
|
| *
|
| * @param items the array of items
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the array of items is null</li>
|
| * <li>ERROR_INVALID_ARGUMENT - if one of the item has been disposed</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#deselectAll()
|
| * @see Table#select(int)
|
| */ |
| public void setSelection(TableItem selectionItems[]) {
|
| checkWidget();
|
| if (selectionItems == null) {
|
| error(SWT.ERROR_NULL_ARGUMENT);
|
| }
|
| setSelectableSelection(selectionItems);
|
| }
|
| /**
|
| * Selects the item at the given zero-relative index in the receiver.
|
| * The current selected is first cleared, then the new item is selected.
|
| *
|
| * @param index the index of the item to select
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#deselectAll()
|
| * @see Table#select(int)
|
| */ |
| public void setSelection(int index) {
|
| checkWidget();
|
| deselectAllExcept(getVisibleItem(index));
|
| select(index);
|
| showSelection ();
|
| }
|
| /**
|
| * Selects the items at the given zero-relative indices in the receiver.
|
| * The current selected if first cleared, then the new items are selected.
|
| *
|
| * @param start the start index of the items to select
|
| * @param end the end index of the items to select
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#deselectAll()
|
| * @see Table#select(int,int)
|
| */ |
| public void setSelection(int start, int end) {
|
| checkWidget();
|
| Vector keepSelected = new Vector();
|
|
|
| for (int i = start; i <= end; i++) {
|
| SelectableItem item = getVisibleItem(i);
|
| if (item != null) {
|
| keepSelected.addElement(item);
|
| }
|
| }
|
| deselectAllExcept(keepSelected);
|
| select(start, end);
|
| showSelection ();
|
| }
|
| /**
|
| * Sets the zero-relative index of the item which is currently
|
| * at the top of the receiver. This index can change when items
|
| * are scrolled or new items are added and removed.
|
| *
|
| * @param index the index of the top item
|
| *
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| */ |
| public void setTopIndex(int index) {
|
| checkWidget();
|
| int itemCount = getItemCount();
|
| int itemCountWhole = getItemCountWhole();
|
| if (index < 0 || itemCount == 0) return;
|
| if (index >= itemCount) index = itemCount - 1;
|
| if (itemCount > itemCountWhole) {
|
| if (index + itemCountWhole <= itemCount) {
|
| setTopIndex(index, true);
|
| } else if (index > itemCount - itemCountWhole) {
|
| setTopIndex(itemCount - itemCountWhole, true);
|
| } else {
|
| showSelectableItem(index);
|
| }
|
| }
|
| }
|
| /**
|
| * Set the index of the first visible item in the receiver's client
|
| * area to 'index'.
|
| * @param index - 0-based index of the first visible item in the
|
| * receiver's client area.
|
| * @param adjustScrollbar - true=set the position of the vertical
|
| * scroll bar to the new top index.
|
| * false=don't adjust the vertical scroll bar
|
| */ |
| void setTopIndexNoScroll(int index, boolean adjustScrollbar) {
|
| super.setTopIndexNoScroll(index, adjustScrollbar);
|
| moveColumnsVertical();
|
| }
|
| /**
|
| * Shows the item. If the item is already showing in the receiver,
|
| * this method simply returns. Otherwise, the items are scrolled until
|
| * the item is visible.
|
| *
|
| * @param item the item to be shown
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the item is null</li>
|
| * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#showSelection()
|
| */ |
| public void showItem(TableItem item) {
|
| checkWidget();
|
| if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
|
| if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
|
| showSelectableItem(item);
|
| }
|
| /**
|
| * Shows the selection. If the selection is already showing in the receiver,
|
| * this method simply returns. Otherwise, the items are scrolled until
|
| * the selection is visible.
|
| *
|
| * @exception IllegalArgumentException <ul>
|
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
| * </ul>
|
| * @exception SWTException <ul>
|
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
|
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
|
| * </ul>
|
| *
|
| * @see Table#showItem(TableItem)
|
| */ |
| public void showSelection() {
|
| checkWidget();
|
| super.showSelection();
|
| }
|
| void sort (int [] items) {
|
| /* Shell Sort from K&R, pg 108 */
|
| int length = items.length;
|
| for (int gap=length/2; gap>0; gap/=2) {
|
| for (int i=gap; i<length; i++) {
|
| for (int j=i-gap; j>=0; j-=gap) {
|
| if (items [j] <= items [j + gap]) {
|
| int swap = items [j];
|
| items [j] = items [j + gap];
|
| items [j + gap] = swap;
|
| }
|
| }
|
| }
|
| }
|
| }
|
| /**
|
| * Start a column resize operation.
|
| * @param event - the mouse event that occured over the header
|
| * widget
|
| */ |
| void startColumnResize(Event event) {
|
| Vector columns = internalGetColumnVector();
|
| TableColumn hitColumn = getColumnAtX(event.x);
|
| Rectangle hitColumnBounds;
|
| int hitIndex = hitColumn.getIndex();
|
|
|
| if (hitColumn == getFillColumn()) { // clicked on the fill column?
|
| hitColumn = (TableColumn) columns.lastElement(); // resize the last real column
|
| }
|
| else
|
| if ((event.x - hitColumn.getBounds().x <= COLUMN_RESIZE_OFFSET) && // check if left side of a column was clicked
|
| (hitIndex > 0)) {
|
| hitColumn = (TableColumn) columns.elementAt(hitIndex - 1); // resize the preceding column
|
| }
|
| hitColumnBounds = hitColumn.getBounds();
|
| setColumnResizeX(hitColumnBounds.x + hitColumnBounds.width);
|
| setResizeColumn(hitColumn);
|
| }
|
| /**
|
| * Return 'text' after it has been checked to be no longer than 'maxWidth'
|
| * when drawn on 'gc'.
|
| * If it is too long it will be truncated up to the last character.
|
| * @param text - the String that should be checked for length
|
| * @param maxWidth - maximum width of 'text'
|
| * @param gc - GC to use for String measurement
|
| */ |
| String trimItemText(String text, int maxWidth, GC gc) {
|
| int textWidth;
|
| int dotsWidth;
|
|
|
| if (text != null && text.length() > 1) {
|
| textWidth = gc.stringExtent(text).x;
|
| if (textWidth > maxWidth) {
|
| dotsWidth = getDotsWidth(gc);
|
| while (textWidth + dotsWidth > maxWidth && text.length() > 1) {
|
| text = text.substring(0, text.length() - 1); // chop off one character at the end
|
| textWidth = gc.stringExtent(text).x;
|
| }
|
| text = text.concat(Table.DOT_STRING);
|
| }
|
| }
|
| return text;
|
| }
|
|
|
| }
|