The Echo Table
component is used for the display of column/row formatted data. It is very much different from the previously introduced Grid
component, most notably because a Table
visualizes data held in an external model. Table
is one of the most robust of the built-in components provided by the Echo framework. A side-effect of its robustness is that it has a steeper learning curve than most of the previously introduced components.
The Table
component itself simply provides a view of data. The data is represented by an object which implements the TableModel
model interface. TableModel
specifies methods which must be implemented to determine the number of columns and rows in the table, as well as to retrieve the values of particular cells. The Table
component will query the model for this data and then render it into an appropriate visual representation.
AbstractTableModel
provides an abstract implementation of TableModel
. It includes simple default versions of most of the required methods, so as to reduce the number of methods that must be implemented by the developer. AbstractTableModel
s also handle the addition and removal of TableModelListener
s, and provide an array of convenience methods through which the listeners can be notified of events. The only methods that this abstract implementation does not provide are those that return the dimensions of the table (getRowCount()
and getColumnCount()
), as well as the getValueAt()
method which returns the value of a specific table cell.
The DefaultTableModel
class is derived from AbstractTableModel
, and provides a full implementation based on ArrayList
s. DefaultTableModel
features the ability to insert and remove rows, and also provides a constructor that accepts a two-dimensional array containing the model data. More often than not however, you will probably find that it is more efficient to create your own TableModel
implementation based off AbstractTableModel
than it is to use a DefaultTableModel
.
An example implementation of a TableModel
is displayed in Figure 1. This TableModel
describes a 12x12 multiplication table. It is based on the AbstractTableModel
implementation, and as such, only three methods are left to be implemented by the developer. Its dimensions are defined by the getRowCount()
and getColumnCount()
methods. The getValueAt()
method simply multiplies the requested column value by the requested row value to return the appropriate product for the specified coordinate in the multiplication table.
class MultiplicationTableModel extends AbstractTableModel { public Object getValueAt(int column, int row) { return new Integer((column + 1) * (row + 1)); } public int getColumnCount() { return 12; } public int getRowCount() { return 12; } }
Figure 1: Source code for a table model used to produce a 12x12 multiplication table.
A TableModel
returns the data of each cell as a Java Object
. These objects are "run through" a TableCellRenderer
, which is responsible for creating Echo Component
representations of the Object
values returned by the model. These Components
are then displayed within the rendered table cells.
TableCellRenderer
InterfaceThe TableCellRenderer
interface contains only a single method, getTableCellRendererComponent()
. It is the responsibility of this method to return an Echo Component
representation of the cell passed to it. It must return a unique component for every invocation. The method is provided with the value of the cell (as returned by the TableModel
), the Table
itself, and the column/row coordinate of the cell to be rendered.
class ValueColorRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(Table table, Object value, int column, int row) { Label label = new Label(value.toString()); int colorValue = 255 - ((Integer) value).intValue(); label.setHorizontalAlignment(EchoConstants.RIGHT); label.setBackground( new Color(colorValue, colorValue, 255)); return label; } }
Figure 2: Source code for a table cell rendererer that creates cells with background colors based on the numeric value displayed within them.
So far we've discussed and demonstrated the use of TabelModel
and TableCellRenderer
. It's time to put it all together and show off a finished Table
based on the previous snippets of example code. As you can see in Figure 3, final assembly of the Table
is done with just a few lines of code.
TableModel model = new MultiplicationTableModel(); Table table = new Table(model); table.setDefaultRenderer(Object.class, new ValueColorRenderer());
Figure 3: Creating the Table.
The net result of all this code is a 12x12 multiplication table. The background colors of smaller numbers are white, and larger numbers appear in blue:
Figure 4: The finished product.