From the author of

From the author of

What is the most common way to organize many related values? Consider a
table. A table organizes related values in a row-and-column format. Each row
presents a collection of values that describes some entity (such as an
employee), and each column imparts meaning to every row's value that
appears in that column (such as a column of names, a column of addresses, and so
forth). Tables are so pervasive in the computer science world that they form the
basis of relational databases. A Java developer accesses a relational database
(by using the JDBC API) to bring a database table's values into a Java
program. Because it is beneficial to display those values to the program's
users in a tabular format, Java developers often consider Swing's table
component when they need to accomplish that task.

This article is the first in a trilogy of articles that explores Swing's
table component. The first article walks you through a tutorial of most table
component features and provides you with detailed behind-the-scenes information
on how table component features work. The second and third articles expand on
the first article by offering several tips for creating more powerful table
components. Once you complete this trilogy of table component articles, you will
possess a more complete understanding of Swing's table component and will
be able to enhance that component to meet your needs.

NOTE

All programs that appear in these three articles have been tested with
Version 1.4 of Sun's Java 2 Standard Edition SDK.

Introducing the Table Component

What is a table component? My definition is the combination of an object created
from the JTable class and several objects created from other classes
that are referenced from JTable field variables. Once the JTable
object has been added to a container and the container has been made visible,
a rendering of the table component appears on the screen. Figure
1 presents a GUI composed of a single table component.

Figure 1
Swing's table component displays as a crisscrossing grid of rows and columns.
The intersection of a row and a column is known as a cell.

Figure 1 shows
that a table component displays as a crisscrossing grid of rows and columns.
Each of the white rectangles between grid lines, known as a cell, displays a
value. As Figure
1 also shows, a table component is capable of displaying a header of column
names. The header's column names, in Figure
1, are Name and Address.

To effectively use a table component, you need to become familiar with its
architecture. One way to familiarize yourself with table component architecture
is to know what classes and interfaces are involved in the creation and
management of that component. Table 1 summarizes most of those classes and
interfaces.

Table 1 Table Component Classes and Interfaces

Class/Interface

Description

javax.swing.AbstractCellEditor

A convenience class that provides default implementations for most of the
CellEditor interface's methods.

javax.swing.CellEditor

An interface that a class must implement if its objects are to edit cells in
table components, tree components, or list components.

An interface that a class must implement if its objects are to manage the
columns of various table components.

javax.swing.table.TableModel

An interface that a class must implement if its objects are to manage the
cell values of various table components.

javax.swing.plaf.basic.BasicLookAndFeel

The base class of all look-and-feel classes. Among other things,
BasicLookAndFeel associates keystroke names with tasks that a table
component must perform (such as initiating an editing session).

javax.swing.plaf.basic.BasicTableHeaderUI

The base class for look-and-feel classes that serve as UI delegates for
JTableHeader components.

javax.swing.plaf.basic.BasicTableUI

The base class for look-and-feel classes that serve as UI delegates for
JTable components.

After reading Table 1, you might be wondering what the terms
look and feel and UI delegates mean. The next section explores
those terms. As you will discover, the concepts of look and feel and UI
delegates are important to understanding the architecture of table
components.

Delegating Look and Feel

A table component's architecture is based on another architecture known
as the model-view-controller architectureMVC, for short. In the late
1970s, Xerox PARC developed the MVC architecture for use with its Smalltalk
windowing system. That architecture splits a component into a model, one or more
views, and a controller.

A component's state is maintained by a model. For example, button press
information is maintained by a button model. A visual representation of that
model's state is provided by a view. The view gives a component its look.
For example, a button view draws a button so that it appears to be either
pressed or not pressed, depending on the press information contained in the
model. The controller determines whether a component can respond to input events
that originate from input devices (such as keyboards and mice), and it gives a
component its feel. For example, when you press a mouse button over some view of
a button component, the button component's controller contacts the button
component's model to have that model update itself. In turn, the model
contacts the button component's view with a request for the view to redraw
itself.

It is much easier to customize a component by changing its model, view, or
controller than it is to change the entire component. To change a Swing
component's model, either Swing (usually through a constructor) or your own
code calls that component's setModel() method. For example, the
JTable class declares a setModel(TableModel m) method that
either you or one of JTable's constructors calls to establish a
table component's model. The TableModel interface argument
m references the object that will serve as that model. That object
declares several methods for managing and communicating with the table
component's model.

When a component's view and controller are changed, the component is
said to adopt a new look and feel. For example, a button's view and
controller can be changed to take on the look and feel of a Windows button, a
Macintosh OS button, or a Unix Motif button. Because it is more common to change
both a view and a controller than to change either entity separately, many
windowing systems (including Swing) collapse a component's controller and
view into a single entity, which is known as a UI (User Interface) delegate. UI
delegates and models are completely separate, so a UI delegate can associate
with more than one model, and a model can associate with more than one UI
delegate. Typically, a UI delegate contacts a component's model when that
model needs to change. In turn, the model can inform a program that a change has
taken place. To change a Swing component's UI delegate, Swing calls that
component's setUI() method. For example, to change a table
component's UI delegate, Swing calls JTable's
setUI(TableUI ui) method (which overrides JComponent's
setUI(ComponentUI ui) method). The setUI(TableUI ui) method
sets the UI delegate for a table component to the object referenced by
TableUI class argument ui. That object declares several
methods for managing a table component's look and feel, and communicates
with the table component's model.

NOTE

Table 1 lists the BasicTableUI class. BasicTableUI
subclasses the abstract TableUI class and serves as a basic UI delegate
for table components. Other classes build on top of BasicTableUI to
provide additional UI delegates for other looks and feels. The same idea holds
for BasicTableHeaderUI.