Java/SWT JFace Eclipse/TableTree
Demonstrates TableTree (Table Tree)
<source lang="java">
//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(); }
}
</source>
Demonstrates TableTreeViewer 2
<source lang="java">
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 }
}
</source>
SWT Table Tree
<source lang="java">
/*
* (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. **
*
* The item children that may be added to instances of this class
*
* must be of type TableTreeItem
.
*
*
*
* Note that although this class is a subclass of Composite
,
*
* it does not make sense to add Control
children to it,
*
* or set a layout on it.
*
*
* *
-
*
*
- Styles: *
- SINGLE, MULTI, CHECK, FULL_SELECTION * *
- Events: *
- Selection, DefaultSelection, Collapse, Expand * *
* */
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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when listener is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when listener is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_CANNOT_GET_ITEM_HEIGHT when the operation fails * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_ITEM_NOT_REMOVED when the operation fails * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when listener is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when listener is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ public void setFont(Font font) { super.setFont(font); table.setFont(font); } /** * * Gets the widget foreground color. * * <p> * * @return the widget foreground color * * * * @exception SWTError*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
**
* */ public void setMenu(Menu menu) { super.setMenu(menu); table.setMenu(menu); } /** * * Sets the selection. * * <p> * * @param items * new selection * * * * @exception SWTError*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when items is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ public void setToolTipText(String string) { super.setToolTipText(string); table.setToolTipText(string); } /** * * Shows the item. * * <p> * * @param item * the item to be shown * * * * @exception SWTError*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
- ERROR_NULL_ARGUMENT when item is null * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * *
- ERROR_WIDGET_DISPOSED when the widget has been disposed * *
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
* */ 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*
-
*
*
- ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
**
**
**
* */ 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; } }
}
</source>