Java/SWT JFace Eclipse/TableTree
Demonstrates TableTree (Table Tree)
//Send questions, comments, bug reports, etc. to the authors:
//Rob Warner (rwarner@interspatial.ru)
//Robert Harris (rbrt_harris@yahoo.ru)
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
/**
* This class demonstrates TableTree
*/
public class TableTreeTest {
// The number of rows and columns
private static final int NUM = 3;
/**
* Runs the application
*/
public void run() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("TableTree Test");
createContents(shell);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
/**
* Creates the main window"s contents
*
* @param shell the main window
*/
private void createContents(final Shell shell) {
shell.setLayout(new FillLayout());
// Create the TableTree and set some attributes on the underlying table
TableTree tableTree = new TableTree(shell, SWT.NONE);
Table table = tableTree.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(false);
// Create the columns, passing the underlying table
for (int i = 0; i < NUM; i++) {
new TableColumn(table, SWT.LEFT).setText("Column " + (i + 1));
}
// Create the data
for (int i = 0; i < NUM; i++) {
// Create a parent item and add data to the columns
TableTreeItem parent = new TableTreeItem(tableTree, SWT.NONE);
parent.setText(0, "Parent " + (i + 1));
parent.setText(1, "Data");
parent.setText(2, "More data");
// Add children items
for (int j = 0; j < NUM; j++) {
// Create a child item and add data to the columns
TableTreeItem child = new TableTreeItem(parent, SWT.NONE);
child.setText(0, "Child " + (j + 1));
child.setText(1, "Some child data");
child.setText(2, "More child data");
}
// Expand the parent item
parent.setExpanded(true);
}
// Pack the columns
TableColumn[] columns = table.getColumns();
for (int i = 0, n = columns.length; i < n; i++) {
columns[i].pack();
}
}
/**
* The application entry point
*
* @param args the command line arguments
*/
public static void main(String[] args) {
new TableTreeTest().run();
}
}
Demonstrates TableTreeViewer 2
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableTreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.ruposite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
/**
* This class demonstrates TableTreeViewer.
*/
public class PlayerTableTree extends ApplicationWindow {
// The TableTreeViewer
private TableTreeViewer ttv;
/**
* PlayerTableTree constructor
*/
public PlayerTableTree() {
super(null);
}
/**
* Runs the application
*/
public void run() {
// Don"t return from open() until window closes
setBlockOnOpen(true);
// Open the main window
open();
// Dispose the display
Display.getCurrent().dispose();
}
/**
* Configures the shell
*
* @param shell
* the shell
*/
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText("Team Tree");
}
/**
* Creates the main window"s contents
*
* @param parent
* the main window
* @return Control
*/
protected Control createContents(Composite parent) {
// Create the table viewer to display the players
ttv = new TableTreeViewer(parent);
ttv.getTableTree().setLayoutData(new GridData(GridData.FILL_BOTH));
// Set the content and label providers
ttv.setContentProvider(new PlayerTreeContentProvider());
ttv.setLabelProvider(new PlayerTreeLabelProvider());
ttv.setInput(new PlayerTableModel());
// Set up the table
Table table = ttv.getTableTree().getTable();
new TableColumn(table, SWT.LEFT).setText("First Name");
new TableColumn(table, SWT.LEFT).setText("Last Name");
new TableColumn(table, SWT.RIGHT).setText("Points");
new TableColumn(table, SWT.RIGHT).setText("Rebounds");
new TableColumn(table, SWT.RIGHT).setText("Assists");
// Expand everything
ttv.expandAll();
// Pack the columns
for (int i = 0, n = table.getColumnCount(); i < n; i++) {
table.getColumn(i).pack();
}
// Turn on the header and the lines
table.setHeaderVisible(true);
table.setLinesVisible(true);
// Pack the window
parent.pack();
// Scroll to top
ttv.reveal(ttv.getElementAt(0));
return ttv.getTableTree();
}
/**
* The application entry point
*
* @param args
* the command line arguments
*/
public static void main(String[] args) {
new PlayerTableTree().run();
}
}
/**
* This class provides the content for the TableTreeViewer in PlayerTableTree
*/
class PlayerTreeContentProvider implements ITreeContentProvider {
private static final Object[] EMPTY = new Object[] {};
/**
* Gets the children for a team or player
*
* @param arg0
* the team or player
* @return Object[]
*/
public Object[] getChildren(Object arg0) {
if (arg0 instanceof Team)
return ((Team) arg0).getPlayers().toArray();
// Players have no children . . . except Shawn Kemp
return EMPTY;
}
/**
* Gets the parent team for a player
*
* @param arg0
* the player
* @return Object
*/
public Object getParent(Object arg0) {
return ((Player) arg0).getTeam();
}
/**
* Gets whether this team or player has children
*
* @param arg0
* the team or player
* @return boolean
*/
public boolean hasChildren(Object arg0) {
return getChildren(arg0).length > 0;
}
/**
* Gets the elements for the table
*
* @param arg0
* the model
* @return Object[]
*/
public Object[] getElements(Object arg0) {
// Returns all the teams in the model
return ((PlayerTableModel) arg0).teams;
}
/**
* Disposes any resources
*/
public void dispose() {
// We don"t create any resources, so we don"t dispose any
}
/**
* Called when the input changes
*
* @param arg0
* the parent viewer
* @param arg1
* the old input
* @param arg2
* the new input
*/
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
// Nothing to do
}
}
/**
* This class provides the labels for the PlayerTableTree application
*/
class PlayerTreeLabelProvider extends PlayerLabelProvider {
/**
* Gets the image for the specified column
*
* @param arg0
* the player or team
* @param arg1
* the column
* @return Image
*/
public Image getColumnImage(Object arg0, int arg1) {
// Teams have no image
if (arg0 instanceof Player)
return super.getColumnImage(arg0, arg1);
return null;
}
/**
* Gets the text for the specified column
*
* @param arg0
* the player or team
* @param arg1
* the column
* @return String
*/
public String getColumnText(Object arg0, int arg1) {
if (arg0 instanceof Player)
return super.getColumnText(arg0, arg1);
Team team = (Team) arg0;
return arg1 == 0 ? team.getYear() + " " + team.getName() : "";
}
}
/**
* This class contains the data model for the PlayerTable
*/
class PlayerTableModel {
public Team[] teams;
/**
* Constructs a PlayerTableModel Fills the model with data
*/
public PlayerTableModel() {
teams = new Team[3];
teams[0] = new Team("Celtics", "1985-86");
teams[0].add(new Player("Larry", "Bird", 25.8f, 9.8f, 6.8f));
teams[0].add(new Player("Kevin", "McHale", 21.3f, 8.1f, 2.7f));
teams[0].add(new Player("Robert", "Parish", 16.1f, 9.5f, 1.8f));
teams[0].add(new Player("Dennis", "Johnson", 15.6f, 3.4f, 5.8f));
teams[0].add(new Player("Danny", "Ainge", 10.7f, 2.9f, 5.1f));
teams[0].add(new Player("Scott", "Wedman", 8.0f, 2.4f, 1.1f));
teams[0].add(new Player("Bill", "Walton", 7.6f, 6.8f, 2.1f));
teams[0].add(new Player("Jerry", "Sichting", 6.5f, 1.3f, 2.3f));
teams[0].add(new Player("David", "Thirdkill", 3.3f, 1.4f, 0.3f));
teams[0].add(new Player("Sam", "Vincent", 3.2f, 0.8f, 1.2f));
teams[0].add(new Player("Sly", "Williams", 2.8f, 2.5f, 0.3f));
teams[0].add(new Player("Rick", "Carlisle", 2.6f, 1.0f, 1.4f));
teams[0].add(new Player("Greg", "Kite", 1.3f, 2.0f, 1.3f));
teams[1] = new Team("Bulls", "1995-96");
teams[1].add(new Player("Michael", "Jordan", 30.4f, 6.6f, 4.3f));
teams[1].add(new Player("Scottie", "Pippen", 19.4f, 6.4f, 5.9f));
teams[1].add(new Player("Toni", "Kukoc", 13.1f, 4.0f, 3.5f));
teams[1].add(new Player("Luc", "Longley", 9.1f, 5.1f, 1.9f));
teams[1].add(new Player("Steve", "Kerr", 8.4f, 1.3f, 2.3f));
teams[1].add(new Player("Ron", "Harper", 7.4f, 2.7f, 2.6f));
teams[1].add(new Player("Dennis", "Rodman", 5.5f, 14.9f, 2.5f));
teams[1].add(new Player("Bill", "Wennington", 5.3f, 2.5f, 0.6f));
teams[1].add(new Player("Jack", "Haley", 5.0f, 2.0f, 0.0f));
teams[1].add(new Player("John", "Salley", 4.4f, 3.3f, 1.3f));
teams[1].add(new Player("Jud", "Buechler", 3.8f, 1.5f, 0.8f));
teams[1].add(new Player("Dickey", "Simpkins", 3.6f, 2.6f, 0.6f));
teams[1].add(new Player("James", "Edwards", 3.5f, 1.4f, 0.4f));
teams[1].add(new Player("Jason", "Caffey", 3.2f, 1.9f, 0.4f));
teams[1].add(new Player("Randy", "Brown", 2.7f, 1.0f, 1.1f));
teams[2] = new Team("Lakers", "1987-1988");
teams[2].add(new Player("Magic", "Johnson", 23.9f, 6.3f, 12.2f));
teams[2].add(new Player("James", "Worthy", 19.4f, 5.7f, 2.8f));
teams[2].add(new Player("Kareem", "Abdul-Jabbar", 17.5f, 6.7f, 2.6f));
teams[2].add(new Player("Byron", "Scott", 17.0f, 3.5f, 3.4f));
teams[2].add(new Player("A.C.", "Green", 10.8f, 7.8f, 1.1f));
teams[2].add(new Player("Michael", "Cooper", 10.5f, 3.1f, 4.5f));
teams[2].add(new Player("Mychal", "Thompson", 10.1f, 4.1f, 0.8f));
teams[2].add(new Player("Kurt", "Rambis", 5.7f, 5.8f, 0.8f));
teams[2].add(new Player("Billy", "Thompson", 5.6f, 2.9f, 1.0f));
teams[2].add(new Player("Adrian", "Branch", 4.3f, 1.7f, 0.5f));
teams[2].add(new Player("Wes", "Matthews", 4.2f, 0.9f, 2.0f));
teams[2].add(new Player("Frank", "Brickowski", 4.0f, 2.6f, 0.3f));
teams[2].add(new Player("Mike", "Smrek", 2.2f, 1.1f, 0.1f));
}
}
/**
* This class represents a player
*/
class Player {
private Team team;
private String lastName;
private String firstName;
private float points;
private float rebounds;
private float assists;
/**
* Constructs an empty Player
*/
public Player() {
this(null, null, 0.0f, 0.0f, 0.0f);
}
/**
* Constructs a Player
*
* @param firstName
* the first name
* @param lastName
* the last name
* @param points
* the points
* @param rebounds
* the rebounds
* @param assists
* the assists
*/
public Player(String firstName, String lastName, float points,
float rebounds, float assists) {
setFirstName(firstName);
setLastName(lastName);
setPoints(points);
setRebounds(rebounds);
setAssists(assists);
}
/**
* Sets the team for theo player
*
* @param team
* the team
*/
public void setTeam(Team team) {
this.team = team;
}
/**
* Gets the assists
*
* @return float
*/
public float getAssists() {
return assists;
}
/**
* Sets the assists
*
* @param assists
* The assists to set.
*/
public void setAssists(float assists) {
this.assists = assists;
}
/**
* Gets the first name
*
* @return String
*/
public String getFirstName() {
return firstName;
}
/**
* Sets the first name
*
* @param firstName
* The firstName to set.
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Gets the last name
*
* @return String
*/
public String getLastName() {
return lastName;
}
/**
* Sets the last name
*
* @param lastName
* The lastName to set.
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Gets the points
*
* @return float
*/
public float getPoints() {
return points;
}
/**
* Sets the points
*
* @param points
* The points to set.
*/
public void setPoints(float points) {
this.points = points;
}
/**
* Gets the rebounds
*
* @return float
*/
public float getRebounds() {
return rebounds;
}
/**
* Sets the rebounds
*
* @param rebounds
* The rebounds to set.
*/
public void setRebounds(float rebounds) {
this.rebounds = rebounds;
}
/**
* Gets the team
*
* @return Team
*/
public Team getTeam() {
return team;
}
/**
* Returns whether this player led the team in the specified category
*
* @param column
* the column (category)
* @return boolean
*/
public boolean ledTeam(int column) {
return team.led(this, column);
}
}
/**
* This class represents a team
*/
class Team {
private String name;
private String year;
private List players;
/**
* Constructs a Team
*
* @param name
* the name
* @param year
* the year
*/
public Team(String name, String year) {
this.name = name;
this.year = year;
players = new LinkedList();
}
/**
* Gets the name
*
* @return String
*/
public String getName() {
return name;
}
/**
* Gets the year
*
* @return String
*/
public String getYear() {
return year;
}
/**
* Adds a player
*
* @param player
* the player to add
* @return boolean
*/
public boolean add(Player player) {
boolean added = players.add(player);
if (added)
player.setTeam(this);
return added;
}
/**
* Gets the players
*
* @return List
*/
public List getPlayers() {
return Collections.unmodifiableList(players);
}
/**
* Returns whether the specified player led his team in the specified
* category
*
* @param player
* the player
* @param column
* the category
* @return boolean
*/
public boolean led(Player player, int column) {
boolean led = true;
// Go through all the players on the team, comparing the specified
// player"s
// stats with each other player.
for (int i = 0, n = players.size(); i < n && led; i++) {
Player test = (Player) players.get(i);
if (player == test)
continue;
switch (column) {
case PlayerConst.COLUMN_POINTS:
if (player.getPoints() < test.getPoints())
led = false;
break;
case PlayerConst.COLUMN_REBOUNDS:
if (player.getRebounds() < test.getRebounds())
led = false;
break;
case PlayerConst.COLUMN_ASSISTS:
if (player.getAssists() < test.getAssists())
led = false;
break;
}
}
return led;
}
}
/**
* This class contains constants for the PlayerTable application
*/
class PlayerConst {
// Column constants
public static final int COLUMN_FIRST_NAME = 0;
public static final int COLUMN_LAST_NAME = 1;
public static final int COLUMN_POINTS = 2;
public static final int COLUMN_REBOUNDS = 3;
public static final int COLUMN_ASSISTS = 4;
}
/**
* This class provides the labels for PlayerTable
*/
class PlayerLabelProvider implements ITableLabelProvider {
// Image to display if the player led his team
private Image ball;
// Constructs a PlayerLabelProvider
public PlayerLabelProvider() {
// Create the image
try {
ball = new Image(null, new FileInputStream("images/ball.png"));
} catch (FileNotFoundException e) {
// Swallow it
}
}
/**
* Gets the image for the specified column
*
* @param arg0
* the player
* @param arg1
* the column
* @return Image
*/
public Image getColumnImage(Object arg0, int arg1) {
Player player = (Player) arg0;
Image image = null;
switch (arg1) {
// A player can"t lead team in first name or last name
case PlayerConst.COLUMN_POINTS:
case PlayerConst.COLUMN_REBOUNDS:
case PlayerConst.COLUMN_ASSISTS:
if (player.ledTeam(arg1))
// Set the image
image = ball;
break;
}
return image;
}
/**
* Gets the text for the specified column
*
* @param arg0
* the player
* @param arg1
* the column
* @return String
*/
public String getColumnText(Object arg0, int arg1) {
Player player = (Player) arg0;
String text = "";
switch (arg1) {
case PlayerConst.COLUMN_FIRST_NAME:
text = player.getFirstName();
break;
case PlayerConst.COLUMN_LAST_NAME:
text = player.getLastName();
break;
case PlayerConst.COLUMN_POINTS:
text = String.valueOf(player.getPoints());
break;
case PlayerConst.COLUMN_REBOUNDS:
text = String.valueOf(player.getRebounds());
break;
case PlayerConst.COLUMN_ASSISTS:
text = String.valueOf(player.getAssists());
break;
}
return text;
}
/**
* Adds a listener
*
* @param arg0
* the listener
*/
public void addListener(ILabelProviderListener arg0) {
// Throw it away
}
/**
* Dispose any created resources
*/
public void dispose() {
// Dispose the image
if (ball != null)
ball.dispose();
}
/**
* Returns whether the specified property, if changed, would affect the
* label
*
* @param arg0
* the player
* @param arg1
* the property
* @return boolean
*/
public boolean isLabelProperty(Object arg0, String arg1) {
return false;
}
/**
* Removes the specified listener
*
* @param arg0
* the listener
*/
public void removeListener(ILabelProviderListener arg0) {
// Do nothing
}
}
SWT Table Tree
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved
*/
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TreeListener;
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.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.ruposite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TypedListener;
/**
*
* A TableTree is a selectable user interface object
*
* that displays a hierarchy of items, and issues
*
* notification when an item is selected.
*
* A TableTree may be single or multi select.
*
* <p>
*
* The item children that may be added to instances of this class
*
* must be of type <code>TableTreeItem</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>
* <dd>SINGLE, MULTI, CHECK, FULL_SELECTION
*
* <dt><b>Events: </b>
* <dd>Selection, DefaultSelection, Collapse, Expand
*
* </dl>
*
*/
public class TableTree extends Composite {
Table table;
TableTreeItem[] items = EMPTY_ITEMS;
Image plusImage, minusImage, sizeImage;
/*
*
* TableTreeItems are not treated as children but rather as items.
*
* When the TableTree is disposed, all children are disposed because
*
* TableTree inherits this behaviour from Composite. The items
*
* must be disposed separately. Because TableTree is not part of
*
* the org.eclipse.swt.widgets package, the method releaseWidget can
*
* not be overriden (this is how items are disposed of in Table and Tree).
*
* Instead, the items are disposed of in response to the dispose event on
* the
*
* TableTree. The "inDispose" flag is used to distinguish between disposing
*
* one TableTreeItem (e.g. when removing an entry from the TableTree) and
*
* disposing the entire TableTree.
*
*/
boolean inDispose = false;
static final TableTreeItem[] EMPTY_ITEMS = new TableTreeItem[0];
static final String[] EMPTY_TEXTS = new String[0];
static final Image[] EMPTY_IMAGES = new Image[0];
/**
*
* Creates a new instance of the widget.
*
*
*
* @param parent
* a composite widget
*
* @param style
* the bitwise OR"ing of widget styles
*
*/
public TableTree(Composite parent, int style) {
super(parent, SWT.NONE);
table = new Table(this, style);
setBackground(table.getBackground());
setForeground(table.getForeground());
setFont(table.getFont());
table.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
onMouseDown(e);
}
});
table.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
onSelection(e);
}
});
table.addListener(SWT.DefaultSelection, new Listener() {
public void handleEvent(Event e) {
onSelection(e);
}
});
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event e) {
onDispose();
}
});
addListener(SWT.Resize, new Listener() {
public void handleEvent(Event e) {
onResize();
}
});
addListener(SWT.FocusIn, new Listener() {
public void handleEvent(Event e) {
onFocusIn();
}
});
}
int addItem(TableTreeItem item, int index) {
if (index < 0 || index > items.length)
throw new SWTError(SWT.ERROR_INVALID_ARGUMENT);
TableTreeItem[] newItems = new TableTreeItem[items.length + 1];
System.arraycopy(items, 0, newItems, 0, index);
newItems[index] = item;
System.arraycopy(items, index, newItems, index + 1, items.length
- index);
items = newItems;
/* Return the index in the table where this table should be inserted */
if (index == items.length - 1)
return table.getItemCount();
else
return table.indexOf(items[index + 1].tableItem);
}
/**
*
* Adds the listener to receive selection events.
*
* <p>
*
*
*
* @param listener
* the selection listener
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when listener is null
*
* </ul>
*
*/
public void addSelectionListener(SelectionListener listener) {
if (listener == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener(listener);
addListener(SWT.Selection, typedListener);
addListener(SWT.DefaultSelection, typedListener);
}
/**
*
* Adds the listener to receive tree events.
*
* <p>
*
*
*
* @param listener
* the tree listener
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when listener is null
*
* </ul>
*
*/
public void addTreeListener(TreeListener listener) {
if (listener == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener(listener);
addListener(SWT.Expand, typedListener);
addListener(SWT.Collapse, typedListener);
}
/**
*
* Computes the preferred size of the widget.
*
* <p>
*
* Calculate the preferred size of the widget based
*
* on the current contents. The hint arguments allow
*
* a specific client area width and/or height to be
*
* requested. The hints may be honored depending on
*
* the platform and the layout.
*
*
*
* @param wHint
* the width hint (can be SWT.DEFAULT)
*
* @param hHint
* the height hint (can be SWT.DEFAULT)
*
* @return a point containing the preferred size of the widget including
* trim
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public Point computeSize(int wHint, int hHint) {
return table.ruputeSize(wHint, hHint, true);
}
/**
*
* Computes the widget trim.
*
* <p>
*
* Trim is widget specific and may include scroll
*
* bars and menu bar in addition to other trimmings
*
* that are outside of the widget"s client area.
*
*
*
* @param x
* the x location of the client area
*
* @param y
* the y location of the client area
*
* @param width
* the width of the client area
*
* @param height
* the height of the client area
*
* @return a rectangle containing the trim of the widget.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public Rectangle computeTrim(int x, int y, int width, int height) {
return table.ruputeTrim(x, y, width, height);
}
/**
*
* Deselects all items.
*
* <p>
*
* If an item is selected, it is deselected.
*
* If an item is not selected, it remains unselected.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* </ul>
*
*/
public void deselectAll() {
table.deselectAll();
}
/* Expand upward from the specified leaf item. */
void expandItem(TableTreeItem item) {
if (item == null || item.getExpanded())
return;
expandItem(item.parentItem);
item.setExpanded(true);
Event event = new Event();
event.item = item;
notifyListeners(SWT.Expand, event);
}
/**
*
* Gets the number of items.
*
* <p>
*
* @return the number of items in the widget
*
*/
public int getItemCount() {
return items.length;
}
/**
*
* Gets the height of one item.
*
* <p>
*
* This operation will fail if the height of
*
* one item could not be queried from the OS.
*
*
*
* @return the height of one item in the widget
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_CANNOT_GET_ITEM_HEIGHT when the operation fails
*
* </ul>
*
*/
public int getItemHeight() {
return table.getItemHeight();
}
/**
*
* Gets the items.
*
* <p>
*
* @return the items in the widget
*
*
*
*/
public TableTreeItem[] getItems() {
TableTreeItem[] newItems = new TableTreeItem[items.length];
System.arraycopy(items, 0, newItems, 0, items.length);
return newItems;
}
/**
*
* Gets the selected items.
*
* <p>
*
* This operation will fail if the selected
*
* items cannot be queried from the OS.
*
*
*
* @return the selected items in the widget
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_CANNOT_GET_SELECTION when the operation fails</li>
*
* </ul>
*
*/
public TableTreeItem[] getSelection() {
TableItem[] selection = table.getSelection();
TableTreeItem[] result = new TableTreeItem[selection.length];
for (int i = 0; i < selection.length; i++) {
result[i] = (TableTreeItem) selection[i].getData();
}
return result;
}
/**
*
* Gets the number of selected items.
*
* <p>
*
* This operation will fail if the number of selected
*
* items cannot be queried from the OS.
*
*
*
* @return the number of selected items in the widget
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_CANNOT_GET_COUNT when the operation fails</li>
*
* </ul>
*
*/
public int getSelectionCount() {
return table.getSelectionCount();
}
/**
*
* Returns the underlying Table control.
*
*
*
* @return the underlying Table control
*
*/
public Table getTable() {
return table;
}
void createImages() {
int itemHeight = sizeImage.getBounds().height;
// Calculate border around image.
// At least 9 pixels are needed to draw the image
// Leave at least a 6 pixel border.
int indent = Math.min(6, (itemHeight - 9) / 2);
indent = Math.max(0, indent);
int size = Math.max(10, itemHeight - 2 * indent);
size = ((size + 1) / 2) * 2; // size must be an even number
int midpoint = indent + size / 2;
Color foreground = getForeground();
Color plusMinus = getDisplay().getSystemColor(
SWT.COLOR_WIDGET_NORMAL_SHADOW);
Color background = getBackground();
/* Plus image */
PaletteData palette = new PaletteData(new RGB[] { foreground.getRGB(),
background.getRGB(), plusMinus.getRGB() });
ImageData imageData = new ImageData(itemHeight, itemHeight, 4, palette);
imageData.transparentPixel = 1;
plusImage = new Image(getDisplay(), imageData);
GC gc = new GC(plusImage);
gc.setBackground(background);
gc.fillRectangle(0, 0, itemHeight, itemHeight);
gc.setForeground(plusMinus);
gc.drawRectangle(indent, indent, size, size);
gc.setForeground(foreground);
gc.drawLine(midpoint, indent + 2, midpoint, indent + size - 2);
gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint);
gc.dispose();
/* Minus image */
palette = new PaletteData(new RGB[] { foreground.getRGB(),
background.getRGB(), plusMinus.getRGB() });
imageData = new ImageData(itemHeight, itemHeight, 4, palette);
imageData.transparentPixel = 1;
minusImage = new Image(getDisplay(), imageData);
gc = new GC(minusImage);
gc.setBackground(background);
gc.fillRectangle(0, 0, itemHeight, itemHeight);
gc.setForeground(plusMinus);
gc.drawRectangle(indent, indent, size, size);
gc.setForeground(foreground);
gc.drawLine(indent + 2, midpoint, indent + size - 2, midpoint);
gc.dispose();
}
Image getPlusImage() {
if (plusImage == null)
createImages();
return plusImage;
}
Image getMinusImage() {
if (minusImage == null)
createImages();
return minusImage;
}
/**
*
* Gets the index of an item.
*
*
*
* <p>
* The widget is searched starting at 0 until an
*
* item is found that is equal to the search item.
*
* If no item is found, -1 is returned. Indexing
*
* is zero based. This index is relative to the parent only.
*
*
*
* @param item
* the search item
*
* @return the index of the item or -1
*
*
*
*/
public int indexOf(TableTreeItem item) {
for (int i = 0; i < items.length; i++) {
if (item == items[i])
return i;
}
return -1;
}
void onDispose() {
inDispose = true;
for (int i = 0; i < items.length; i++) {
items[i].dispose();
}
inDispose = false;
if (plusImage != null)
plusImage.dispose();
if (minusImage != null)
minusImage.dispose();
if (sizeImage != null)
sizeImage.dispose();
plusImage = minusImage = sizeImage = null;
}
void onResize() {
Rectangle area = getClientArea();
table.setBounds(0, 0, area.width, area.height);
}
void onSelection(Event e) {
Event event = new Event();
TableItem tableItem = (TableItem) e.item;
TableTreeItem item = getItem(tableItem);
event.item = item;
if (e.type == SWT.Selection
&& e.detail == SWT.CHECK
&& item != null) {
event.detail = SWT.CHECK;
item.checked = tableItem.getChecked();
}
notifyListeners(e.type, event);
}
public TableTreeItem getItem(Point point) {
TableItem item = table.getItem(point);
if (item == null)
return null;
return getItem(item);
}
TableTreeItem getItem(TableItem tableItem) {
if (tableItem == null)
return null;
for (int i = 0; i < items.length; i++) {
TableTreeItem item = items[i].getItem(tableItem);
if (item != null)
return item;
}
return null;
}
void onFocusIn() {
table.setFocus();
}
void onMouseDown(Event event) {
/* If user clicked on the [+] or [-], expand or collapse the tree. */
TableItem[] items = table.getItems();
for (int i = 0; i < items.length; i++) {
Rectangle rect = items[i].getImageBounds(0);
if (rect.contains(event.x, event.y)) {
TableTreeItem item = (TableTreeItem) items[i].getData();
event = new Event();
event.item = item;
item.setExpanded(!item.getExpanded());
if (item.getExpanded()) {
notifyListeners(SWT.Expand, event);
} else {
notifyListeners(SWT.Collapse, event);
}
return;
}
}
}
/**
*
* Removes all items.
*
* <p>
*
* This operation will fail when an item
*
* could not be removed in the OS.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_ITEM_NOT_REMOVED when the operation fails
*
* </ul>
*
*/
public void removeAll() {
setRedraw(false);
for (int i = items.length - 1; i >= 0; i--) {
items[i].dispose();
}
items = EMPTY_ITEMS;
setRedraw(true);
}
void removeItem(TableTreeItem item) {
int index = 0;
while (index < items.length && items[index] != item)
index++;
if (index == items.length)
return;
TableTreeItem[] newItems = new TableTreeItem[items.length - 1];
System.arraycopy(items, 0, newItems, 0, index);
System.arraycopy(items, index + 1, newItems, index, items.length
- index - 1);
items = newItems;
}
/**
*
* Removes the listener.
*
* <p>
*
*
*
* @param listener
* the listener
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when listener is null
*
* </ul>
*
*/
public void removeSelectionListener(SelectionListener listener) {
if (listener == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
removeListener(SWT.Selection, listener);
removeListener(SWT.DefaultSelection, listener);
}
/**
*
* Removes the listener.
*
*
*
* @param listener
* the listener
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when listener is null
*
* </ul>
*
*/
public void removeTreeListener(TreeListener listener) {
if (listener == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
removeListener(SWT.Expand, listener);
removeListener(SWT.Collapse, listener);
}
/**
*
* Selects all items.
*
* <p>
*
* If an item is not selected, it is selected.
*
* If an item is selected, it remains selected.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* </ul>
*
*/
public void selectAll() {
table.selectAll();
}
/**
*
* Sets the widget background color.
*
* <p>
*
* When new color is null, the background reverts
*
* to the default system color for the widget.
*
*
*
* @param color
* the new color (or null)
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setBackground(Color color) {
super.setBackground(color);
table.setBackground(color);
if (sizeImage != null) {
GC gc = new GC(sizeImage);
gc.setBackground(getBackground());
Rectangle size = sizeImage.getBounds();
gc.fillRectangle(size);
gc.dispose();
}
}
/**
*
* Sets the enabled state.
*
* <p>
*
* A disabled widget is typically not selectable from
*
* the user interface and draws with an inactive or
*
* grayed look.
*
*
*
* @param enabled
* the new enabled state
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
table.setEnabled(enabled);
}
/**
*
* Sets the widget font.
*
* <p>
*
* When new font is null, the font reverts
*
* to the default system font for the widget.
*
*
*
* @param font
* the new font (or null)
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setFont(Font font) {
super.setFont(font);
table.setFont(font);
}
/**
*
* Gets the widget foreground color.
*
* <p>
*
* @return the widget foreground color
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setForeground(Color color) {
super.setForeground(color);
table.setForeground(color);
}
/**
*
* Sets the pop up menu.
*
* <p>
*
* Every control has an optional pop up menu that is
*
* displayed when the user requests a popup menu for
*
* the control. The sequence of key strokes/button
*
* presses/button releases that is used to request
*
* a pop up menu is platform specific.
*
*
*
* @param menu
* the new pop up menu
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_MENU_NOT_POP_UP when the menu is not a POP_UP</li>
*
* <li>ERROR_NO_COMMON_PARENT when the menu is not in the same widget tree
* </li>
*
* </ul>
*
*/
public void setMenu(Menu menu) {
super.setMenu(menu);
table.setMenu(menu);
}
/**
*
* Sets the selection.
*
* <p>
*
* @param items
* new selection
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when items is null
*
* </ul>
*
*/
public void setSelection(TableTreeItem[] items) {
TableItem[] tableItems = new TableItem[items.length];
for (int i = 0; i < items.length; i++) {
if (items[i] == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
if (!items[i].getVisible())
expandItem(items[i]);
tableItems[i] = items[i].tableItem;
}
table.setSelection(tableItems);
}
/**
*
* Sets the tool tip text.
*
* <p>
*
* @param string
* the new tool tip text (or null)
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setToolTipText(String string) {
super.setToolTipText(string);
table.setToolTipText(string);
}
/**
*
* Shows the item.
*
* <p>
*
* @param item
* the item to be shown
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* <li>ERROR_NULL_ARGUMENT when item is null
*
* </ul>
*
*/
public void showItem(TableTreeItem item) {
if (item == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
if (!item.getVisible())
expandItem(item);
TableItem tableItem = item.tableItem;
table.showItem(tableItem);
}
/**
*
* Shows the selection.
*
* <p>
*
* If there is no selection or the selection
*
* is already visible, this method does nothing.
*
* If the selection is scrolled out of view,
*
* the top index of the widget is changed such
*
* that selection becomes visible.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* </ul>
*
*/
public void showSelection() {
table.showSelection();
}
}
//TableTreeItem
/*
*
* (c) Copyright IBM Corp. 2000, 2001.
*
* All Rights Reserved
*
*/
/**
*
* A TableTreeItem is a selectable user interface object
*
* that represents an item in a heirarchy of items in a
*
* TableTree.
*
*/
class TableTreeItem extends Item {
TableItem tableItem;
TableTree parent;
TableTreeItem parentItem;
TableTreeItem[] items = TableTree.EMPTY_ITEMS;
String[] texts = TableTree.EMPTY_TEXTS;
Image[] images = TableTree.EMPTY_IMAGES;
boolean expanded;
boolean checked;
/**
*
* Create a new instance of a root item.
*
*
*
* @param parent
* the TableTree that contains this root item
*
* @param style
* the bitwise OR"ing of widget styles
*
*/
public TableTreeItem(TableTree parent, int style) {
this(parent, style, parent.getItemCount());
}
/**
*
* Create a new instance of a root item in the position
*
* indicated by the specified index.
*
*
*
* @param parent
* the TableTree that contains this root item
*
* @param style
* the bitwise OR"ing of widget styles
*
* @param index
* specifies the position of this item in the TableTree
*
* relative to other root items
*
*/
public TableTreeItem(TableTree parent, int style, int index) {
this(parent, null, style, index);
}
/**
*
* Create a new instance of a sub item.
*
*
*
* @param parent
* this item"s parent in the hierarchy of TableTree items
*
* @param style
* the bitwise OR"ing of widget styles
*
*/
public TableTreeItem(TableTreeItem parent, int style) {
this(parent, style, parent.getItemCount());
}
/**
*
* Create a new instance of a sub item in the position
*
* indicated by the specified index.
*
*
*
* @param parent
* this item"s parent in the hierarchy of TableTree items
*
* @param style
* the bitwise OR"ing of widget styles
*
* @param index
* specifies the position of this item in the TableTree
*
* relative to other children of the same parent
*
*/
public TableTreeItem(TableTreeItem parent, int style, int index) {
this(parent.getParent(), parent, style, index);
}
TableTreeItem(TableTree parent, TableTreeItem parentItem, int style,
int index) {
super(parent, style);
this.parent = parent;
this.parentItem = parentItem;
if (parentItem == null) {
/* Root items are visible immediately */
int tableIndex = parent.addItem(this, index);
tableItem = new TableItem(parent.getTable(), style, tableIndex);
tableItem.setData(this);
addCheck();
/*
*
* Feature in the Table. The table uses the first image that
*
* is inserted into the table to size the table rows. If the
*
* user is allowed to insert the first image, this will cause
*
* the +/- images to be scaled. The fix is to insert a dummy
*
* image to force the size.
*
*/
if (parent.sizeImage == null) {
int itemHeight = parent.getItemHeight();
parent.sizeImage = new Image(null, itemHeight, itemHeight);
GC gc = new GC(parent.sizeImage);
gc.setBackground(parent.getBackground());
gc.fillRectangle(0, 0, itemHeight, itemHeight);
gc.dispose();
tableItem.setImage(0, parent.sizeImage);
}
} else {
parentItem.addItem(this, index);
}
}
void addCheck() {
Table table = parent.getTable();
if ((table.getStyle() & SWT.CHECK) == 0)
return;
tableItem.setChecked(checked);
}
void addItem(TableTreeItem item, int index) {
if (item == null)
throw new SWTError(SWT.ERROR_NULL_ARGUMENT);
if (index < 0 || index > items.length)
throw new SWTError(SWT.ERROR_INVALID_ARGUMENT);
/* Now that item has a sub-node it must indicate that it can be expanded */
if (items.length == 0 && index == 0) {
if (tableItem != null) {
Image image = expanded ? parent.getMinusImage() : parent
.getPlusImage();
tableItem.setImage(0, image);
}
}
/* Put the item in the items list */
TableTreeItem[] newItems = new TableTreeItem[items.length + 1];
System.arraycopy(items, 0, newItems, 0, index);
newItems[index] = item;
System.arraycopy(items, index, newItems, index + 1, items.length
- index);
items = newItems;
if (expanded)
item.setVisible(true);
}
/**
*
* Gets the widget bounds at the specified index.
*
* <p>
*
* @return the widget bounds at the specified index
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public Rectangle getBounds(int index) {
if (tableItem != null) {
return tableItem.getBounds(index);
} else {
return new Rectangle(0, 0, 0, 0);
}
}
/**
*
* Gets the checked state.
*
* <p>
*
* @return the item checked state.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public boolean getChecked() {
if (tableItem == null) {
return checked;
}
return tableItem.getChecked();
}
/**
*
* Gets the Display.
*
* <p>
*
* This method gets the Display that is associated
*
* with the widget.
*
*
*
* @return the widget data
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public Display getDisplay() {
TableTree parent = this.parent;
if (parent == null)
throw new SWTError(SWT.ERROR_WIDGET_DISPOSED);
return parent.getDisplay();
}
/**
*
* Gets the expanded state of the widget.
*
* <p>
*
* @return a boolean that is the expanded state of the widget
*
*/
public boolean getExpanded() {
return expanded;
}
/**
*
* Gets the first image.
*
* <p>
*
* The image in column 0 is reserved for the [+] and [-]
*
* images of the tree, therefore getImage(0) will return null.
*
*
*
* @return the image at index 0
*
*/
public Image getImage() {
return getImage(0);
}
/**
*
* Gets the image at the specified index.
*
* <p>
*
* Indexing is zero based. The image can be null.
*
* The image in column 0 is reserved for the [+] and [-]
*
* images of the tree, therefore getImage(0) will return null.
*
* Return null if the index is out of range.
*
*
*
* @param index
* the index of the image
*
* @return the image at the specified index or null
*
*/
public Image getImage(int index) {
if (0 < index && index < images.length)
return images[index];
return null;
}
int getIndent() {
if (parentItem == null)
return 0;
return parentItem.getIndent() + 1;
}
/**
*
* Gets the number of sub items.
*
* <p>
*
* @return the number of sub items
*
*/
public int getItemCount() {
return items.length;
}
/**
*
* Gets the sub items.
*
* <p>
*
* @return the sub items
*
*/
public TableTreeItem[] getItems() {
TableTreeItem[] newItems = new TableTreeItem[items.length];
System.arraycopy(items, 0, newItems, 0, items.length);
return newItems;
}
TableTreeItem getItem(TableItem tableItem) {
if (tableItem == null)
return null;
if (this.tableItem == tableItem)
return this;
for (int i = 0; i < items.length; i++) {
TableTreeItem item = items[i].getItem(tableItem);
if (item != null)
return item;
}
return null;
}
/**
*
* Gets the parent.
*
* <p>
*
* @return the parent
*
*/
public TableTree getParent() {
return parent;
}
/**
*
* Gets the parent item.
*
* <p>
*
* @return the parent item.
*
*/
public TableTreeItem getParentItem() {
return parentItem;
}
/**
*
* Gets the first item text.
*
* <p>
*
* @return the item text at index 0, which can be null
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_CANNOT_GET_TEXT when the operation fails</li>
*
* </ul>
*
*/
public String getText() {
return getText(0);
}
/**
*
* Gets the item text at the specified index.
*
* <p>
*
* Indexing is zero based.
*
*
*
* This operation will fail when the index is out
*
* of range or an item could not be queried from
*
* the OS.
*
*
*
* @param index
* the index of the item
*
* @return the item text at the specified index, which can be null
*
*/
public String getText(int index) {
if (0 <= index && index < texts.length)
return texts[index];
return null;
}
boolean getVisible() {
return tableItem != null;
}
/**
*
* Gets the index of the specified item.
*
*
*
* <p>
* The widget is searched starting at 0 until an
*
* item is found that is equal to the search item.
*
* If no item is found, -1 is returned. Indexing
*
* is zero based. This index is relative to the parent only.
*
*
*
* @param item
* the search item
*
* @return the index of the item or -1 if the item is not found
*
*
*
*/
public int indexOf(TableTreeItem item) {
for (int i = 0; i < items.length; i++) {
if (items[i] == item)
return i;
}
return -1;
}
int expandedIndexOf(TableTreeItem item) {
int index = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] == item)
return index;
if (items[i].expanded)
index += items[i].visibleChildrenCount();
index++;
}
return -1;
}
int visibleChildrenCount() {
int count = 0;
for (int i = 0; i < items.length; i++) {
if (items[i].getVisible()) {
count += 1 + items[i].visibleChildrenCount();
}
}
return count;
}
public void dispose() {
for (int i = items.length - 1; i >= 0; i--) {
items[i].dispose();
}
super.dispose();
if (!parent.inDispose) {
if (parentItem != null) {
parentItem.removeItem(this);
} else {
parent.removeItem(this);
}
if (tableItem != null)
tableItem.dispose();
}
items = null;
parentItem = null;
parent = null;
images = null;
texts = null;
tableItem = null;
}
void removeItem(TableTreeItem item) {
int index = 0;
while (index < items.length && items[index] != item)
index++;
if (index == items.length)
return;
TableTreeItem[] newItems = new TableTreeItem[items.length - 1];
System.arraycopy(items, 0, newItems, 0, index);
System.arraycopy(items, index + 1, newItems, index, items.length
- index - 1);
items = newItems;
if (items.length == 0) {
if (tableItem != null)
tableItem.setImage(0, null);
}
}
/**
*
* Sets the checked state.
*
* <p>
*
* @param checked
* the new checked state.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setChecked(boolean checked) {
if (tableItem != null) {
tableItem.setChecked(checked);
}
this.checked = checked;
}
/**
*
* Sets the expanded state.
*
* <p>
*
* @param expanded
* the new expanded state.
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setExpanded(boolean expanded) {
if (items.length == 0)
return;
this.expanded = expanded;
if (tableItem == null)
return;
parent.setRedraw(false);
for (int i = 0; i < items.length; i++) {
items[i].setVisible(expanded);
}
Image image = expanded ? parent.getMinusImage() : parent.getPlusImage();
tableItem.setImage(0, image);
parent.setRedraw(true);
}
/**
*
* Sets the image at an index.
*
* <p>
*
* The image can be null.
*
* The image in column 0 is reserved for the [+] and [-]
*
* images of the tree, therefore do nothing if index is 0.
*
*
*
* @param image
* the new image or null
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* </ul>
*
*/
public void setImage(int index, Image image) {
int columnCount = Math.max(parent.getTable().getColumnCount(), 1);
if (index <= 0 || index >= columnCount)
return;
if (images.length < columnCount) {
Image[] newImages = new Image[columnCount];
System.arraycopy(images, 0, newImages, 0, images.length);
images = newImages;
}
images[index] = image;
if (tableItem != null)
tableItem.setImage(index, image);
}
/**
*
* Sets the first image.
*
* <p>
*
* The image can be null.
*
* The image in column 0 is reserved for the [+] and [-]
*
* images of the tree, therefore do nothing.
*
*
*
* @param image
* the new image or null
*
*/
public void setImage(Image image) {
setImage(0, image);
}
/**
*
* Sets the widget text.
*
* <p>
*
*
*
* The widget text for an item is the label of the
*
* item or the label of the text specified by a column
*
* number.
*
*
*
* @param index
* the column number
*
* @param text
* the new text
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_NULL_ARGUMENT when string is null</li>
*
* </ul>
*
*/
public void setText(int index, String text) {
int columnCount = Math.max(parent.getTable().getColumnCount(), 1);
if (index < 0 || index >= columnCount)
return;
if (texts.length < columnCount) {
String[] newTexts = new String[columnCount];
System.arraycopy(texts, 0, newTexts, 0, texts.length);
texts = newTexts;
}
texts[index] = text;
if (tableItem != null)
tableItem.setText(index, text);
}
/**
*
* Sets the widget text.
*
* <p>
*
*
*
* The widget text for an item is the label of the
*
* item or the label of the text specified by a column
*
* number.
*
*
*
* @param index
* the column number
*
* @param text
* the new text
*
*
*
* @exception SWTError
* <ul>
*
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
*
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
*
* <li>ERROR_NULL_ARGUMENT when string is null</li>
*
* </ul>
*
*/
public void setText(String string) {
setText(0, string);
}
void setVisible(boolean show) {
if (parentItem == null)
return; // this is a root and can not be toggled between visible and
// hidden
if (getVisible() == show)
return;
if (show) {
if (!parentItem.getVisible())
return; // parentItem must already be visible
// create underlying table item and set data in table item to stored
// data
Table table = parent.getTable();
int parentIndex = table.indexOf(parentItem.tableItem);
int index = parentItem.expandedIndexOf(this) + parentIndex + 1;
if (index < 0)
return;
tableItem = new TableItem(table, getStyle(), index);
tableItem.setData(this);
tableItem.setImageIndent(getIndent());
addCheck();
// restore fields to item
// ignore any images in the first column
int columnCount = Math.max(table.getColumnCount(), 1);
for (int i = 0; i < columnCount; i++) {
if (i < texts.length && texts[i] != null)
setText(i, texts[i]);
if (i < images.length && images[i] != null)
setImage(i, images[i]);
}
// display the children and the appropriate [+]/[-] symbol as
// required
if (items.length != 0) {
if (expanded) {
tableItem.setImage(0, parent.getMinusImage());
for (int i = 0, length = items.length; i < length; i++) {
items[i].setVisible(true);
}
} else {
tableItem.setImage(0, parent.getPlusImage());
}
}
} else {
for (int i = 0, length = items.length; i < length; i++) {
items[i].setVisible(false);
}
// remove row from table
tableItem.dispose();
tableItem = null;
}
}
}