/*******************************************************************************
* Copyright (c) 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* chris.gross@us.ibm.com - initial API and implementation
* Claes Rosell<claes.rosell@solme.se> - rowspan in bug 272384
* Stefan Widmaier<stefan.widmaier@faktorzehn.de> - rowspan in 304797
*******************************************************************************/
package org.eclipse.nebula.widgets.grid;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.TypedListener;
/**
* <p>
* NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A
* PRE-RELEASE ALPHA VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE
* VERSIONS.
* </p>
* Instances of this class represent a selectable user interface object that
* represents an item in a grid.
* <p>
* <dl>
* <dt><b>Styles:</b></dt>
* <dd>(none)</dd>
* <dt><b>Events:</b></dt>
* <dd>(none)</dd>
* </dl>
*
* @author chris.gross@us.ibm.com
*/
public class GridItem extends Item {
/**
* List of background colors for each column.
*/
private ArrayList backgrounds = new ArrayList();
/**
* Lists of check states for each column.
*/
private ArrayList checks = new ArrayList();
/**
* Lists of checkable states for each column.
*/
private ArrayList checkable = new ArrayList();
/**
* List of children.
*/
private ArrayList children = new ArrayList();
/**
* List of column spaning.
*/
private ArrayList columnSpans = new ArrayList();
/**
* List of row spaning.
*/
private ArrayList rowSpans = new ArrayList();
/**
* Default background color.
*/
private Color defaultBackground;
/**
* Default font.
*/
private Font defaultFont;
/**
* Default foreground color.
*/
private Color defaultForeground;
/**
* The height of this <code>GridItem</code>.
*/
private int height = 1;
/**
* Is expanded?
*/
private boolean expanded = false;
/**
* Lists of fonts for each column.
*/
private ArrayList fonts = new ArrayList();
/**
* List of foreground colors for each column.
*/
private ArrayList foregrounds = new ArrayList();
/**
* Lists of grayed (3rd check state) for each column.
*/
private ArrayList grayeds = new ArrayList();
/**
* True if has children.
*/
private boolean hasChildren = false;
/**
* List of images for each column.
*/
private ArrayList images = new ArrayList();
/**
* Level of item in a tree.
*/
private int level = 0;
/**
* Parent grid instance.
*/
private Grid parent;
/**
* Parent item (if a child item).
*/
private GridItem parentItem;
/**
* List of text for each column.
*/
private ArrayList texts = new ArrayList();
/**
* List of tooltips for each column.
*/
private ArrayList tooltips = new ArrayList();
/**
* Is visible?
*/
private boolean visible = true;
/**
* Row header text.
*/
private String headerText = null;
/**
* Row header image
*/
private Image headerImage = null;
/**
* Background color of the header
*/
private Color headerBackground = null;
/**
* Foreground color of the header
*/
public Color headerForeground = null;
/**
* (SWT.VIRTUAL only) Flag that specifies whether the client has already
* been sent a SWT.SetData event.
*/
private boolean hasSetData = false;
/**
* Creates a new instance of this class and places the item at the end of
* the grid.
*
* @param parent
* parent grid
* @param style
* item style
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @throws org.eclipse.swt.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>
*/
public GridItem(Grid parent, int style) {
this(parent, style, -1);
}
/**
* Creates a new instance of this class and places the item in the grid at
* the given index.
*
* @param parent
* parent grid
* @param style
* item style
* @param index
* index where to insert item
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @throws org.eclipse.swt.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>
*/
public GridItem(Grid parent, int style, int index) {
super(parent, style, index);
this.parent = parent;
init();
parent.newItem(this, index, true);
parent.newRootItem(this, index);
}
/**
* Creates a new instance of this class as a child node of the given
* GridItem and places the item at the end of the parents items.
*
* @param parent
* parent item
* @param style
* item style
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @throws org.eclipse.swt.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>
*/
public GridItem(GridItem parent, int style) {
this(parent, style, -1);
}
/**
* Creates a new instance of this class as a child node of the given Grid
* and places the item at the given index in the parent items list.
*
* @param parent
* parent item
* @param style
* item style
* @param index
* index to place item
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* @throws org.eclipse.swt.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>
*/
public GridItem(GridItem parent, int style, int index) {
super(parent, style, index);
parentItem = parent;
this.parent = parentItem.getParent();
init();
this.parent.newItem(this, index, false);
level = parentItem.getLevel() + 1;
parentItem.newItem(this, index);
if (parent.isVisible() && parent.isExpanded()) {
setVisible(true);
} else {
setVisible(false);
}
}
/**
* {@inheritDoc}
*/
public void dispose() {
if (!parent.isDisposing()) {
parent.removeItem(this);
if (parentItem != null) {
parentItem.remove(this);
} else {
parent.removeRootItem(this);
}
for (int i = children.size() - 1; i >= 0; i--) {
((GridItem) children.get(i)).dispose();
}
}
super.dispose();
}
/**
* Adds the listener to the collection of listeners who will be notified
* when the row is resized, by sending it one of the messages defined in the
* <code>ControlListener</code> interface.
* <p>
* Clients who wish to override the standard row resize logic should use the
* untyped listener mechanisms. The untyped <code>Event</code> object passed
* to an untyped listener will have its <code>detail</code> field populated
* with the new row height. Clients may alter this value to, for example,
* enforce minimum or maximum row sizes. Clients may also set the
* <code>doit</code> field to false to prevent the entire resize operation.
*
* @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>
*/
public void addControlListener(ControlListener listener) {
checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener(listener);
addListener(SWT.Resize, typedListener);
}
/**
* Removes the listener from the collection of listeners who will be
* notified when the row is resized.
*
* @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>
*/
public void removeControlListener(ControlListener listener) {
checkWidget();
if (listener == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
removeListener(SWT.Resize, listener);
}
/**
* Fires the given event type on the parent Grid instance. This method
* should only be called from within a cell renderer. Any other use is not
* intended.
*
* @param eventId
* SWT event constant
* @throws 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 fireEvent(int eventId) {
checkWidget();
Event e = new Event();
e.display = getDisplay();
e.widget = this;
e.item = this;
e.type = eventId;
getParent().notifyListeners(eventId, e);
}
/**
* Fires the appropriate events in response to a user checking/unchecking an
* item. Checking an item fires both a selection event (with event.detail of
* SWT.CHECK) if the checkbox is in the first column and the seperate check
* listener (all columns). This method manages that behavior. This method
* should only be called from within a cell renderer. Any other use is not
* intended.
*
* @param column
* the column where the checkbox resides
* @throws 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 fireCheckEvent(int column) {
checkWidget();
Event selectionEvent = new Event();
selectionEvent.display = getDisplay();
selectionEvent.widget = this;
selectionEvent.item = this;
selectionEvent.type = SWT.Selection;
selectionEvent.detail = SWT.CHECK;
selectionEvent.index = column;
getParent().notifyListeners(SWT.Selection, selectionEvent);
}
/**
* Returns the receiver's background color.
*
* @return the background color
* @throws 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 Color getBackground() {
checkWidget();
if (defaultBackground == null) {
return parent.getBackground();
}
return defaultBackground;
}
/**
* Returns the background color at the given column index in the receiver.
*
* @param index
* the column index
* @return the background color
* @throws org.eclipse.swt.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 Color getBackground(int index) {
checkWidget();
handleVirtual();
Color c = (Color) backgrounds.get(index);
// if (c == null)
// {
// c = getBackground();
// }
return c;
}
/**
* Returns a rectangle describing the receiver's size and location relative
* to its parent at a column in the table.
*
* @param columnIndex
* the index that specifies the column
* @return the receiver's bounding column rectangle
* @throws 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 Rectangle getBounds(int columnIndex) {
checkWidget();
// HACK: The -1000,-1000 xy coordinates below are a hack to deal with
// GridEditor issues. In
// normal SWT Table, when an editor is created on Table and its
// positioned in the header area
// the header overlays the editor. Because Grid (header and everything)
// is drawn on one
// composite, when an editor is positioned in the header area the editor
// overlays the header.
// So to fix this, when the editor is anywhere its not supposed to be
// seen (the editor
// coordinates are determined by this getBounds) we position it out in
// timbuktu.
if (!isVisible())
return new Rectangle(-1000, -1000, 0, 0);
if (!parent.isShown(this))
return new Rectangle(-1000, -1000, 0, 0);
Point origin = parent.getOrigin(parent.getColumn(columnIndex), this);
// MOD sizhaoliu TDQ-6010 fix row header bound issue
// if (origin.x < 0 && parent.isRowHeaderVisible())
// return new Rectangle(-1000, -1000, 0, 0);
Point cellSize = this.getCellSize(columnIndex);
return new Rectangle(origin.x, origin.y, cellSize.x, cellSize.y);
}
/**
*
* @param columnIndex
* @return width and height
*/
protected Point getCellSize(int columnIndex) {
int width = 0;
int span = getColumnSpan(columnIndex);
for (int i = 0; i <= span; i++) {
if (parent.getColumnCount() <= columnIndex + i) {
break;
}
width += parent.getColumn(columnIndex + i).getWidth();
}
int indexOfCurrentItem = parent.getIndexOfItem(this);
GridItem item = parent.getItem(indexOfCurrentItem);
int height = item.getHeight();
span = getRowSpan(columnIndex);
for (int i = 1; i <= span; i++) {
/* We will probably need another escape condition here */
if (parent.getItems().length <= indexOfCurrentItem + i) {
break;
}
item = parent.getItem(indexOfCurrentItem + i);
if (item.isVisible()) {
height += item.getHeight() + 1;
}
}
return new Point(width, height);
}
/**
* Returns the checked state at the first column in the receiver.
*
* @return the checked state
* @throws org.eclipse.swt.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 getChecked() {
checkWidget();
return getChecked(0);
}
/**
* Returns the checked state at the given column index in the receiver.
*
* @param index
* the column index
* @return the checked state
* @throws org.eclipse.swt.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 getChecked(int index) {
checkWidget();
handleVirtual();
Boolean b = (Boolean) checks.get(index);
if (b == null) {
return false;
}
return b.booleanValue();
}
/**
* Returns the column span for the given column index in the receiver.
*
* @param index
* the column index
* @return the number of columns spanned (0 equals no columns spanned)
* @throws org.eclipse.swt.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 getColumnSpan(int index) {
checkWidget();
Integer i = (Integer) columnSpans.get(index);
if (i == null) {
return 0;
}
return i.intValue();
}
/**
* Returns the row span for the given column index in the receiver.
*
* @param index
* the row index
* @return the number of row spanned (0 equals no row spanned)
* @throws org.eclipse.swt.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 getRowSpan(int index) {
checkWidget();
if (index >= 0 && index < rowSpans.size()) {
Integer i = (Integer) rowSpans.get(index);
if (i != null) {
return i.intValue();
}
}
return 0;
}
/**
* Returns the font that the receiver will use to paint textual information
* for this item.
*
* @return the receiver's font
* @throws 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 Font getFont() {
if (defaultFont == null) {
return parent.getFont();
}
return defaultFont;
}
/**
* 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
* @throws org.eclipse.swt.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 Font getFont(int index) {
checkWidget();
handleVirtual();
Font f = (Font) fonts.get(index);
if (f == null) {
f = getFont();
}
return f;
}
/**
* Returns the foreground color that the receiver will use to draw.
*
* @return the receiver's foreground color
* @throws 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 Color getForeground() {
if (defaultForeground == null) {
return parent.getForeground();
}
return defaultForeground;
}
/**
* Returns the foreground color at the given column index in the receiver.
*
* @param index
* the column index
* @return the foreground color
* @throws org.eclipse.swt.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 Color getForeground(int index) {
checkWidget();
handleVirtual();
Color c = (Color) foregrounds.get(index);
if (c == null) {
c = getForeground();
}
return c;
}
/**
* Returns <code>true</code> if the first column in the receiver is grayed,
* and false otherwise. When the GridColumn does not have the
* <code>CHECK</code> style, return false.
*
* @return the grayed state of the checkbox
* @throws org.eclipse.swt.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 getGrayed() {
return getGrayed(0);
}
/**
* Returns <code>true</code> if the column at the given index in the
* receiver is grayed, and false otherwise. When the GridColumn does not
* have the <code>CHECK</code> style, return false.
*
* @param index
* the column index
* @return the grayed state of the checkbox
* @throws org.eclipse.swt.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 getGrayed(int index) {
checkWidget();
handleVirtual();
Boolean b = (Boolean) grayeds.get(index);
if (b == null) {
return false;
}
return b.booleanValue();
}
/**
* Returns the height of this <code>GridItem</code>.
*
* @return height of this <code>GridItem</code>
*/
public int getHeight() {
checkWidget();
return height;
}
/**
* {@inheritDoc}
*/
public Image getImage() {
checkWidget();
return getImage(0);
}
/**
* 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
* @throws org.eclipse.swt.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 Image getImage(int index) {
checkWidget();
handleVirtual();
return (Image) images.get(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
* @throws 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>
* @throws 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 GridItem getItem(int index) {
checkWidget();
return (GridItem) children.get(index);
}
/**
* Returns the number of items contained in the receiver that are direct
* item children of the receiver.
*
* @return the number of items
*
* @throws 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 children.size();
}
/**
* 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 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>
*/
public int indexOf(GridItem item) {
checkWidget();
if (item == null)
SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (item.isDisposed())
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
return children.indexOf(item);
}
/**
* Returns a (possibly empty) array of <code>GridItem</code>s which are the
* direct item children of 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 receiver's items
* @throws 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 GridItem[] getItems() {
return (GridItem[]) children.toArray(new GridItem[children.size()]);
}
/**
* Returns the level of this item in the tree.
*
* @return the level of the item in the tree
* @throws org.eclipse.swt.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 getLevel() {
checkWidget();
return level;
}
/**
* Returns the receiver's parent, which must be a <code>Grid</code>.
*
* @return the receiver's parent
* @throws 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 Grid getParent() {
checkWidget();
return parent;
}
/**
* Returns the receiver's parent item, which must be a <code>GridItem</code>
* or null when the receiver is a root.
*
* @return the receiver's parent item
* @throws 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 GridItem getParentItem() {
checkWidget();
return parentItem;
}
/**
* {@inheritDoc}
*/
public String getText() {
checkWidget();
return getText(0);
}
/**
* 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
* @throws org.eclipse.swt.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 String getText(int index) {
checkWidget();
handleVirtual();
String s = (String) texts.get(index);
// SWT TableItem returns empty if never set
// so we return empty to ensure API compatibility
if (s == null) {
return "";
}
return s;
}
/**
* Returns true if this item has children.
*
* @return true if this item has children
* @throws org.eclipse.swt.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 hasChildren() {
checkWidget();
return hasChildren;
}
/**
* Returns <code>true</code> if the receiver is expanded, and false
* otherwise.
* <p>
*
* @return the expanded state
* @throws 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 isExpanded() {
checkWidget();
return expanded;
}
/**
* Sets the receiver's background color to the color specified by the
* argument, or to the default system color for the item if the argument is
* null.
*
* @param background
* the new color (or null)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws 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 setBackground(Color background) {
checkWidget();
if (background != null && background.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
defaultBackground = background;
parent.redraw();
}
/**
* Sets the background 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 background
* the new color (or null)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws org.eclipse.swt.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 setBackground(int index, Color background) {
checkWidget();
if (background != null && background.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
backgrounds.set(index, background);
parent.redraw();
}
/**
* Sets the checked state at the first column in the receiver.
*
* @param checked
* the new checked state
* @throws org.eclipse.swt.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 setChecked(boolean checked) {
checkWidget();
setChecked(0, checked);
parent.redraw();
}
/**
* Sets the checked state at the given column index in the receiver.
*
* @param index
* the column index
* @param checked
* the new checked state
* @throws org.eclipse.swt.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 setChecked(int index, boolean checked) {
checkWidget();
checks.set(index, new Boolean(checked));
parent.redraw();
}
/**
* Sets the column spanning for the column at the given index to span the
* given number of subsequent columns.
*
* @param index
* column index that should span
* @param span
* number of subsequent columns to span
* @throws org.eclipse.swt.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 setColumnSpan(int index, int span) {
checkWidget();
columnSpans.set(index, new Integer(span));
parent.setHasSpanning(true);
parent.redraw();
}
/**
* Sets the row spanning for the row at the given index to span the given
* number of subsequent rows.
*
* @param index
* row index that should span
* @param span
* number of subsequent rows to span
* @throws org.eclipse.swt.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 setRowSpan(int index, int span) {
checkWidget();
rowSpans.set(index, new Integer(span));
parent.setHasSpanning(true);
parent.redraw();
}
/**
* Sets the expanded state of the receiver.
* <p>
*
* @param expanded
* the new expanded state
* @throws 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 setExpanded(boolean expanded) {
checkWidget();
this.expanded = expanded;
// We must unselect any items that are becoming invisible
// and thus if we change the selection we have to fire a selection event
boolean unselected = false;
for (Iterator itemIterator = children.iterator(); itemIterator
.hasNext();) {
GridItem item = (GridItem) itemIterator.next();
item.setVisible(expanded && visible);
if (!expanded) {
if (!getParent().getCellSelectionEnabled()) {
if (getParent().isSelected(item)) {
unselected = true;
getParent().deselect(getParent().indexOf(item));
}
if (deselectChildren(item)) {
unselected = true;
}
} else {
if (deselectCells(item)) {
unselected = true;
}
}
}
}
this.getParent().topIndex = -1;
this.getParent().bottomIndex = -1;
this.getParent().setScrollValuesObsolete();
if (unselected) {
Event e = new Event();
e.item = this;
getParent().notifyListeners(SWT.Selection, e);
}
if (getParent().getFocusItem() != null
&& !getParent().getFocusItem().isVisible()) {
getParent().setFocusItem(this);
}
if (getParent().getCellSelectionEnabled()) {
getParent().updateColumnSelection();
}
}
private boolean deselectCells(GridItem item) {
boolean flag = false;
int index = getParent().indexOf(item);
GridColumn[] columns = getParent().getColumns();
for (int i = 0; i < columns.length; i++) {
Point cell = new Point(getParent().indexOf(columns[i]), index);
if (getParent().isCellSelected(cell)) {
flag = true;
getParent().deselectCell(cell);
}
}
GridItem[] kids = item.getItems();
for (int i = 0; i < kids.length; i++) {
if (deselectCells(kids[i])) {
flag = true;
}
}
return flag;
}
/**
* Deselects the given item's children recursively.
*
* @param item
* item to deselect children.
* @return true if an item was deselected
*/
private boolean deselectChildren(GridItem item) {
boolean flag = false;
GridItem[] kids = item.getItems();
for (int i = 0; i < kids.length; i++) {
if (getParent().isSelected(kids[i])) {
flag = true;
}
getParent().deselect(getParent().indexOf(kids[i]));
if (deselectChildren(kids[i])) {
flag = true;
}
}
return flag;
}
/**
* 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 f
* the new font (or null)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws 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 setFont(Font f) {
checkWidget();
if (f != null && f.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
defaultFont = f;
parent.redraw();
}
/**
* 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)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws org.eclipse.swt.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 setFont(int index, Font font) {
checkWidget();
if (font != null && font.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
fonts.set(index, font);
parent.redraw();
}
/**
* Sets the receiver's foreground color to the color specified by the
* argument, or to the default system color for the item if the argument is
* null.
*
* @param foreground
* the new color (or null)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws 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 setForeground(Color foreground) {
checkWidget();
if (foreground != null && foreground.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
defaultForeground = foreground;
parent.redraw();
}
/**
* 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 foreground
* the new color (or null)
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the argument has been
* disposed</li>
* </ul>
* @throws org.eclipse.swt.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 setForeground(int index, Color foreground) {
checkWidget();
if (foreground != null && foreground.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
foregrounds.set(index, foreground);
parent.redraw();
}
/**
* Sets the grayed state of the checkbox for the first column. This state
* change only applies if the GridColumn was created with the SWT.CHECK
* style.
*
* @param grayed
* the new grayed state of the checkbox;
* @throws org.eclipse.swt.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 setGrayed(boolean grayed) {
checkWidget();
setGrayed(0, grayed);
parent.redraw();
}
/**
* Sets the grayed state of the checkbox for the given column index. This
* state change only applies if the GridColumn was created with the
* SWT.CHECK style.
*
* @param index
* the column index
* @param grayed
* the new grayed state of the checkbox;
* @throws org.eclipse.swt.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 setGrayed(int index, boolean grayed) {
checkWidget();
grayeds.set(index, new Boolean(grayed));
parent.redraw();
}
/**
* Sets the height of this <code>GridItem</code>.
*
* @param newHeight
* new height in pixels
* @throws org.eclipse.swt.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 setHeight(int newHeight) {
checkWidget();
if (newHeight < 1)
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
height = newHeight;
parent.hasDifferingHeights = true;
if (isVisible()) {
int myIndex = parent.indexOf(this);
if (parent.getTopIndex() <= myIndex
&& myIndex <= parent.getBottomIndex()) // note: cannot use
// Grid#isShown()
// here, because
// that returns
// false for
// partially shown
// items
parent.bottomIndex = -1;
}
parent.setScrollValuesObsolete();
parent.redraw();
}
/**
* Sets this <code>GridItem</code> to its preferred height.
*
* @throws org.eclipse.swt.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 pack() {
checkWidget();
int maxPrefHeight = 2;
GridColumn[] columns = parent.getColumns();
GC gc = new GC(parent);
for (int cnt = 0; cnt < columns.length; cnt++) {
if (!columns[cnt].isVisible())
continue; // invisible columns do not affect item/row height
GridCellRenderer renderer = columns[cnt].getCellRenderer();
renderer.setAlignment(columns[cnt].getAlignment());
renderer.setCheck(columns[cnt].isCheck());
renderer.setColumn(cnt);
renderer.setTree(columns[cnt].isTree());
renderer.setWordWrap(columns[cnt].getWordWrap());
Point size = renderer.computeSize(gc, columns[cnt].getWidth(),
SWT.DEFAULT, this);
if (size != null)
maxPrefHeight = Math.max(maxPrefHeight, size.y);
}
gc.dispose();
setHeight(maxPrefHeight);
}
/**
* {@inheritDoc}
*/
public void setImage(Image image) {
setImage(0, image);
parent.redraw();
}
/**
* Sets the receiver's image at a column.
*
* @param index
* the column index
* @param image
* the new image
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
* </ul>
* @throws org.eclipse.swt.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 setImage(int index, Image image) {
checkWidget();
if (image != null && image.isDisposed()) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
images.set(index, image);
parent.imageSetOnItem(index, this);
parent.redraw();
}
/**
* Sets the receiver's text at a column.
*
* @param index
* the column index
* @param text
* the new text
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the text is null</li>
* </ul>
* @throws org.eclipse.swt.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 setText(int index, String text) {
checkWidget();
if (text == null) {
SWT.error(SWT.ERROR_NULL_ARGUMENT);
}
texts.set(index, text);
parent.redraw();
}
/**
* {@inheritDoc}
*/
public void setText(String string) {
setText(0, string);
parent.redraw();
}
/**
* Adds items to the given list to ensure the list is large enough to hold a
* value for each column.
*
* @param al
* list
*/
private void ensureSize(ArrayList al) {
int count = Math.max(1, parent.getColumnCount());
al.ensureCapacity(count);
while (al.size() <= count) {
al.add(null);
}
}
/**
* Removes the given child item from the list of children.
*
* @param child
* child to remove
*/
private void remove(GridItem child) {
children.remove(child);
hasChildren = children.size() > 0;
}
/**
* Returns true if the item is visible because its parent items are all
* expanded. This method does not determine if the item is in the currently
* visible range.
*
* @return Returns the visible.
*/
boolean isVisible() {
return visible;
}
/**
* Creates a new child item in this item at the given index.
*
* @param item
* new child item
* @param index
* index
*/
void newItem(GridItem item, int index) {
setHasChildren(true);
if (index == -1) {
children.add(item);
} else {
children.add(index, item);
}
}
/**
* Sets whether this item has children.
*
* @param hasChildren
* true if this item has children
*/
void setHasChildren(boolean hasChildren) {
this.hasChildren = hasChildren;
}
/**
* Sets the visible state of this item. The visible state is determined by
* the expansion state of all of its parent items. If all parent items are
* expanded it is visible.
*
* @param visible
* The visible to set.
*/
void setVisible(boolean visible) {
if (this.visible == visible) {
return;
}
this.visible = visible;
if (visible) {
parent.updateVisibleItems(1);
} else {
parent.updateVisibleItems(-1);
}
if (hasChildren) {
boolean childrenVisible = visible;
if (visible) {
childrenVisible = expanded;
}
for (Iterator itemIterator = children.iterator(); itemIterator
.hasNext();) {
GridItem item = (GridItem) itemIterator.next();
item.setVisible(childrenVisible);
}
}
}
/**
* Returns the receiver's row header text. If the text is <code>null</code>
* the row header will display the row number.
*
* @return the text stored for the row header or code <code>null</code> if
* the default has to be displayed
* @throws org.eclipse.swt.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 String getHeaderText() {
checkWidget();
// handleVirtual();
return headerText;
}
/**
* Returns the receiver's row header image.
*
* @return the image stored for the header or <code>null</code> if none has
* to be displayed
* @throws org.eclipse.swt.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 Image getHeaderImage() {
checkWidget();
return headerImage;
}
/**
* Returns the receiver's row header background color
*
* @return the color or <code>null</code> if none
* @throws org.eclipse.swt.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 Color getHeaderBackground() {
checkWidget();
return headerBackground;
}
/**
* Returns the receiver's row header foreground color
*
* @return the color or <code>null</code> if none
* @throws org.eclipse.swt.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 Color getHeaderForeground() {
checkWidget();
return headerForeground;
}
/**
* Sets the receiver's row header text. If the text is <code>null</code> the
* row header will display the row number.
*
* @param text
* the new text
* @throws IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the text is null</li>
* </ul>
* @throws org.eclipse.swt.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 setHeaderText(String text) {
checkWidget();
// if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (text != headerText) {
GC gc = new GC(parent);
int oldWidth = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).x;
this.headerText = text;
int newWidth = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).x;
gc.dispose();
parent.recalculateRowHeaderWidth(this, oldWidth, newWidth);
}
parent.redraw();
}
/**
* Sets the receiver's row header image. If the image is <code>null</code>
* none is shown in the header
*
* @param image
* the new image
* @throws org.eclipse.swt.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 setHeaderImage(Image image) {
checkWidget();
// if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (image != headerImage) {
GC gc = new GC(parent);
int oldWidth = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).x;
int oldHeight = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).y;
this.headerImage = image;
int newWidth = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).x;
int newHeight = parent.getRowHeaderRenderer().computeSize(gc,
SWT.DEFAULT, SWT.DEFAULT, this).y;
gc.dispose();
parent.recalculateRowHeaderWidth(this, oldWidth, newWidth);
parent.recalculateRowHeaderHeight(this, oldHeight, newHeight);
}
parent.redraw();
}
/**
* Set the new header background
*
* @param headerBackground
* the color or <code>null</code>
* @throws org.eclipse.swt.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 setHeaderBackground(Color headerBackground) {
checkWidget();
this.headerBackground = headerBackground;
parent.redraw();
}
/**
* Set the new header foreground
*
* @param headerForeground
* the color or <code>null</code>
* @throws org.eclipse.swt.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 setHeaderForeground(Color headerForeground) {
checkWidget();
this.headerForeground = headerForeground;
parent.redraw();
}
/**
* Returns the checkable state at the given column index in the receiver. If
* the column at the given index is not checkable then this will return
* false regardless of the individual cell's checkable state.
*
* @param index
* the column index
* @return the checked state
* @throws org.eclipse.swt.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 getCheckable(int index) {
checkWidget();
if (!parent.getColumn(index).getCheckable())
return false;
Boolean b = (Boolean) checkable.get(index);
if (b == null) {
return true;
}
return b.booleanValue();
}
/**
* Sets the checkable state at the given column index in the receiver. A
* checkbox which is uncheckable will not be modifiable by the user but
* still make be modified programmatically. If the column at the given index
* is not checkable then individual cell will not be checkable regardless.
*
* @param index
* the column index
* @param checked
* the new checked state
* @throws org.eclipse.swt.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 setCheckable(int index, boolean checked) {
checkWidget();
checkable.set(index, new Boolean(checked));
}
/**
* Returns the tooltip for the given cell.
*
* @param index
* the column index
* @return the tooltip
* @throws org.eclipse.swt.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 String getToolTipText(int index) {
checkWidget();
handleVirtual();
String s = (String) tooltips.get(index);
return s;
}
/**
* Sets the tooltip for the given column index.
*
* @param index
* the column index
* @param tooltip
* the tooltip text
* @throws org.eclipse.swt.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 setToolTipText(int index, String tooltip) {
checkWidget();
tooltips.set(index, tooltip);
}
private void init() {
ensureSize(backgrounds);
ensureSize(checks);
ensureSize(checkable);
ensureSize(fonts);
ensureSize(foregrounds);
ensureSize(grayeds);
ensureSize(images);
ensureSize(texts);
ensureSize(columnSpans);
ensureSize(rowSpans);
ensureSize(tooltips);
}
/**
* Notifies the item that a column has been removed.
*
* @param index
* index of column removed.
*/
void columnRemoved(int index) {
removeValue(index, backgrounds);
removeValue(index, checks);
removeValue(index, checkable);
removeValue(index, fonts);
removeValue(index, foregrounds);
removeValue(index, grayeds);
removeValue(index, images);
removeValue(index, texts);
removeValue(index, columnSpans);
removeValue(index, rowSpans);
removeValue(index, tooltips);
}
void columnAdded(int index) {
insertValue(index, backgrounds);
insertValue(index, checks);
insertValue(index, checkable);
insertValue(index, fonts);
insertValue(index, foregrounds);
insertValue(index, grayeds);
insertValue(index, images);
insertValue(index, texts);
insertValue(index, columnSpans);
insertValue(index, rowSpans);
insertValue(index, tooltips);
hasSetData = false;
}
private void insertValue(int index, List list) {
if (index == -1) {
list.add(null);
} else {
list.add(index, null);
}
}
private void removeValue(int index, List list) {
if (list.size() > index) {
list.remove(index);
}
}
private void handleVirtual() {
if ((getParent().getStyle() & SWT.VIRTUAL) != 0 && !hasSetData) {
hasSetData = true;
Event event = new Event();
event.item = this;
if (parentItem == null) {
event.index = getParent().indexOf(this);
} else {
event.index = parentItem.indexOf(this);
}
getParent().notifyListeners(SWT.SetData, event);
}
}
/**
* Sets the initial item height for this item.
*
* @param height
* initial height.
*/
void initializeHeight(int height) {
this.height = height;
}
/**
* Clears all properties of this item and resets values to their defaults.
*
* @param allChildren
* <code>true</code> if all child items should be cleared
* recursively, and <code>false</code> otherwise
*/
void clear(boolean allChildren) {
backgrounds.clear();
checks.clear();
checkable.clear();
columnSpans.clear();
rowSpans.clear();
fonts.clear();
foregrounds.clear();
grayeds.clear();
images.clear();
texts.clear();
tooltips.clear();
defaultForeground = null;
defaultBackground = null;
defaultFont = null;
hasSetData = false;
headerText = null;
headerImage = null;
headerBackground = null;
headerForeground = null;
// Recursively clear children if requested.
if (allChildren) {
for (int i = children.size() - 1; i >= 0; i--) {
((GridItem) children.get(i)).clear(true);
}
}
init();
}
}