1
`Hello Table' -
JClass LiveTable TutorialThe Basic Table Overview of Table Changes Improving the Table's Appearance
Adding Interactivity Proceeding from Here Internationalization
You can immediately learn about some fundamental JClass LiveTable programming concepts by compiling and running an example program1. This program displays information about orders for "The Musical Fruit", a fictional wholesale coffee distributor, based on the following data:
1.1 The Basic Table
The following code is from ExampleTable1.java, found in the examples/table/intro directory of your JClass LiveTable installation directory. The code creates a very plain looking table, without column labels or any other JClass LiveTable features to improve usability and appearance.
package examples.table.intro;
// import the necessary java classes, including the Table package
import java.awt.Component;
import javax.swing.JPanel;
import com.klg.jclass.util.swing.JCExitFrame;
import com.klg.jclass.table.JCTable;
import com.klg.jclass.table.data.JCVectorDataSource;
// initiate the class declaration
public class ExampleTable1 extends JPanel {
// set the cell values as a matrix of strings
String cells[][] = {
{"The Cuppa","11/11/97","French Mocha","60","$7.01"},
{"The Underground Cafe","11/14/97", "Brazilian Medium", "112","$6.80"},
{"RocketFuel and Cake","10/30/97","Espresso Dark","300","$8.02"},
{"WideEyes Coffee House","11/12/97","Colombian/Irish Cream Flavored","120","$5.30"},
{"Jitters Caffeine Cavern","10/01/97","Ethiopian Medium Roast","80","$7.50"},
{"Twitchy's on the Mall","12/06/97","French Roast Kona","160","$14.50"},
{"Quest Software Inc.","12/12/97", "Colombian","22,000","$5.28"}
};
// initialize the Table object
protected JCTable table;
// Build the table, point to the data source and define the table properties.
public ExampleTable1() {
setLayout(new java.awt.GridLayout());
// Create a default table object
table = new JCTable();
// Create a vector data source to contain our data
JCVectorDataSource ds = new JCVectorDataSource();
// Turn off column labels
table.setColumnLabelDisplay(false);
// Turn off row labels
table.setRowLabelDisplay(false);
// Set the data source to the vector data source from earlier
table.setDataSource(ds);
// Set the number of rows in the data source.
ds.setNumRows(7);
// Set the number of columns in the data source.
ds.setNumColumns(5);
// Set the cell data in the data source.
ds.setCells(cells);
this.add(table);
}
public static void main(String args[]) {
JCExitFrame f = new JCExitFrame("ExampleTable1");
ExampleTable1 et = new ExampleTable1();
f.getContentPane().add(et);
f.setSize(600, 200);
f.setVisible(true);
}
}Note: As you change the ExampleTable1.java file throughout this tutorial, it may be necessary to resize the frame to fit the content.
How the Table Handles Data
The table uses a Model-View-Controller (MVC) data mechanism; the table data is stored in a separate object. For this table example, we have used
JCVectorDataSource
, a class provided with JClass LiveTable that retrieves data from the data source and stores it in memory (see Using Stock Data Sources, in Chapter 3, for more information).The data source is set using the
table.setDataSource(ds);table.setDataSource()
method:
ds.setNumRows(7);
ds.setNumColumns(5);
ds.setCells(cells);Once the data source is set to the
JCVectorDataSource
(ds) object, that object handles the data, including setting the number of rows and columns, and accessing the cell values. The data in the cells is of type String.What the Table Looks Like
If you compile and run the modified ExampleTable1.java program,2 the following table is displayed:
The clip arrows indicate that the cells are not large enough to display their entire contents. By default, users can resize rows and columns to view the contents of the cell. Notice that if you click a cell, a focus rectangle appears, showing the current cell.
1.2 Overview of Table Changes
The following sections walk you through the modification of the example table. It is assumed that you are changing the code in the ExampleTable1.java file, compiling and then running it after each step to view the results. Of course, it is recommended that you make a copy of the original file.
For each of the table's modifications, all the code that needs to be added is provided. Since some code segments rely on the presence of code from previous steps, it is recommended that you perform all modifications in the order in which they appear in this chapter.
Additionally, all changes made in this tutorial are reflected in the other example files found in the examples/table/intro directory. You can also compile and run those files to compare and verify the changes you make to ExampleTable1.java. Throughout the chapter, you will be alerted when the cumulative changes can be seen in another example file.
1.3 Improving the Table's Appearance
Using some of the properties for modifying a table's appearance, you can easily move from the basic, drab table in ExampleTable1.java, to a table that is easier to understand, easier to use, and more visually appealing.
All properties for a table can be specified when you create the table, or they may be changed at any time as the program runs by using event listeners. Each property has two accessor methods:
set
andget
. An example of a set method for a property issetBackground()
, which sets the background color of a cell or label. You can retrieve the current value of any property using the property'sget
method, as ingetBackground()
.
1.3.1 Adding and Formatting Labels
Background
The table displayed by the ExampleTable1.java program is not very useful to an end-user. Not only is it uninteresting to look at, but you cannot tell what kinds of information the cells contain because there are no column labels. In the original data outline for the table (at the beginning of the chapter), we specified the following column headers or labels:
Labels are cells that can never be edited and can contain any Object, (for example, Strings, images, integers). You can apply labels to rows and columns. The label values, like cell values, are set in the data source object.
Procedure
In ExampleTable1.java, set the labels as a String by inserting this line immediately after the cell values String statement:
String labels[] = {"Customer Name","Order Date","Item", "Quantity
(lbs.)","Price/lb."};Once you have defined the values for the column labels, you have to instruct the Table object to display labels. The program currently contains the line:
table.setColumnLabelDisplay(false);By default, column labels are set to
table.setColumnLabelDisplay(true);true
. Change the label setting back to this default by entering this code:Once the
ds.setColumnLabels(labels);ColumnLabelDisplay
property is set totrue
, you can set the column labels in the data source. Afterds.setCells(cells);
, add the line:This uses the data source to set the values of the column labels from the data specified in the String
cells
.Compile and run the modified ExampleTable1.java file. The table now looks like this:
Note: You can also run ExampleTable2.java, which already contains these changes.
Notice that the column labels are now part of the table. Also note that if you click a label, you do not get the focus rectangle that would appear on a selected cell, as labels cannot be edited and are not included in cell traversal. In certain situations, clicking a label performs an action (this will be discussed in Section 1.4, Adding Interactivity). However, in this case, the labels do not perform any interactive function.
1.3.2 Introduction to Cell Styles
Cell Styles provide a very flexible model for changing the appearance (and some behavior) of a table's cells or labels. A style contains attributes that can be applied to cells and labels, including color, text properties, and text/image alignment.
JClass LiveTable comes with several constructs that are part of Cell Styles:
CellStyleModel
: An interface that defines the methods required by an object to specify the attributes of a cell.JCCellStyle
: The default implementation of theCellStyleModel
interface.- The default cell and label styles: These are preset styles (one for labels, one for cells) whose look and feel change with any changes to the pluggable look and feel (PLAF) implementation of a table.
The visual table changes found in the next four sections are defined using these Cell Style constructs.
For in-depth coverage of cells styles, please refer to Building a Table, in Chapter 2.
1.3.3 Changing Foreground and Background Colors
Background
There are thirteen AWT color constants that can be used in Java. The color constant values are:
Color.black
Color.magenta
Color.blue
Color.orange
Color.cyan
Color.pink
Color.darkGray
Color.red
Color.gray
Color.white
Color.green
Color.yellow
Color.lightGray
Procedure
In order to make changes with AWT colors, you need to include the
import java.awt.Color;java.awt.Color
package to the ExampleTable1.java file that you are modifying. Add this to your list of import statements:Since you are using default styles in the examples, you need to import the interface with which you implement the style. To do this, import the
import com.klg.jclass.table.CellStyleModel;CellStyleModel
class by adding this line to your list of import statements:Now that the required AWT color and Cell Style classes are accessible, set the background color of the labels to blue, and the foreground color (text) to white. Do this by inserting the following lines into the file's
CellStyleModel labelStyle = table.getDefaultLabelStyle();ExampleTable1
class:
labelStyle.setBackground(Color.blue);
labelStyle.setForeground(Color.white);Here, you acquire the default label style. You then tweak the default label color attributes by changing the default colors to blue and white. Recompile and run the modified ExampleTable1.java file. The table now looks like this:
Note: You can also run ExampleTable3.java, which already contains these changes.
1.3.4 Changing Alignment
Background
Another way to visually differentiate the text that appears within a table is to change its alignment within a cell relative to the text alignment in other cells. By default, text (or anything else you insert into specific cells in a table) is shifted to the top and left margins of the cell. With Cell Styles, the horizontal and vertical positioning of a cell's contents can be defined.
If you want to set the labels in the sample program to appear horizontally centered and at the top of the label, continue to modify the default label style that was set in the previous step.
Procedure
Add this line to your set of import statements:
import com.klg.jclass.table.JCTableEnum;Then, append these lines to the
labelStyle.setHorizontalAlignment(JCTableEnum.CENTER);labelStyle
statements that were added in the previous step:
labelStyle.setVerticalAlignment(JCTableEnum.TOP);
1.3.5 Changing the Fonts
Background
It is also possible to change fonts and their appearance. This is another way to visually distinguish one part of a table from another, or to change the overall appearance of the table.
Java defines five different platform-independent font names that are found (or have close equivalents) on most computer platforms. Valid Java AWT font names are:
Note: Font names are case-sensitive.
There are also four standard font style constants that can be used. Valid Java AWT font style constants are:
Procedure
We want to change the text column labels in the modified ExampleTable1.java, from their default to a 14 point, bold-italic, Times Roman text. In order to make changes with AWT fonts, you need to include the
import java.awt.Font;java.awt.Font
package to the program. Add this to your list of import statements:Append this line to the
labelStyle.setFont(new Font("TimesRoman", Font.BOLD +labelStyle
statements added in the last two steps:
Font.ITALIC, 14));Recompile and run your modified ExampleTable1.java file. Having changed the text font and alignment, your table now looks like this:
Note: You can also run ExampleTable4.java, which already contains these changes.
The type of font displayed on a user's system depends entirely on the fonts that are local to that user's computer. If a font name specified in a Java program is not found on a user's system, the closest possible match is used as determined by the Java AWT.
1.3.6 Adding Color to an Individual Cell
Background
In some cases, you will want the information in a certain cell or range of cells to stand out from the rest. As previously mentioned, Cell Styles can be used with individual or ranges of cells.
In our modified ExampleTable1.java file, we want to highlight the premium coffee order using different foreground and background colors - in this case, Twitchy's on the Mall (row 6, column 1).
When we originally made changes to the labels using Cell Styles (the first change made was to the label colors), we retrieved the default label style and implemented them into the
CellStyleModel
class. This made a change to all labels. Now that you are working with a single cell, using the default Cell Style for non-label cells requires a similar action, but with an added step.Procedure
First, import
import com.klg.jclass.table.JCCellStyle;JCCellStyle
by adding this line to your set of import statements:Then, similarly to what was done with the labels' style, retrieve the default style for non-label cells by adding this new line to the
CellStyleModel cellStyle = table.getDefaultCellStyle();ExampleTable1
class:Next, add this line to create a Cell Style for the single "Twitchy's on the Mall" cell, which creates a new unique Cell Style that inherits all the style settings from the default Cell Style:
CellStyleModel specialStyle = new JCCellStyle((JCCellStyle)cellStyle);Since we want to change the specific cell's color, but do not want these changes applied to all the cells, the
specialStyle.setForeground(Color.red);specialStyle
object was created. Now, change the colors of the cell by adding these lines:
specialStyle.setBackground(Color.yellow);
table.setCellStyle(5, 0, specialStyle);Note: The cell found at row 6, column 1 in the displayed table is designated as row 5, column 0 in the code. This is because row and column indexes begin at zero. The top left cell in the table is at location (0, 0).
Recompile and run the modified ExampleTable1.java file. The colors in cell (5, 0) have changed, and the table now looks like this:
1.3.7 Changing the Cell Borders and Spacing
Background
There are a number of properties that can be used to define cell/frame borders and cell spacing. These are outlined in Building a Table, in Chapter 2. For the example program, we are going to thicken the cell borders, as well as the table's frame border. Also, the border style for the cells (not labels) and frame will be changed.
Procedure
First, in order to work with borders, import the
import com.klg.jclass.table.JCCellBorder;JCCellBorder
class by adding this line to your list of import statements in your modified ExampleTable1.java:Next, add these lines to the
cellStyle.setCellBorder(new JCCellBorder(JCTableEnum.BORDER_OUT));ExampleTable1
class:
table.setCellBorderWidth(5);
table.setFrameBorderWidth(3);
table.setFrameBorder(new JCCellBorder(JCTableEnum.BORDER_OUT));Now that you have made these additions to the code, recompile and run the modified ExampleTable1.java file. Having changed the cell and frame border properties, the table now looks like this:
Note: You can also run ExampleTable5.java, which already contains these changes.
1.3.8 Displaying More of the Cells
Background
The example table has come a long way after setting only a few properties, but there is still a small problem: the table may clip the cell's contents. This means that the user has to resize the rows or columns in order to read the contents of some cells. By default, JClass LiveTable sets all of the cells to a width of 10 characters and a height of one character. You could specify the height and width of the cells in rows and columns in terms of lines and characters using the
CharHeight
andCharWidth
properties. However, in this program we want the cells to size themselves to display the entire contents (if possible).Procedure
Add the following lines of code to the modified ExampleTable1.java:
table.setPixelHeight(JCTableEnum.ALLCELLS, JCTableEnum.VARIABLE);
table.setPixelWidth(JCTableEnum.ALLCELLS, JCTableEnum.VARIABLE);These lines set the
PixelHeight
andPixelWidth
properties to a variable size for all rows and all columns, ensuring that the table will attempt to display the entire contents of each cell. Recompile and run the modified ExampleTable1.java. The table looks like this:
You can also set these properties to specific pixel values for rows and columns; see the section on how to set Column Width and Row Height Properties, in Chapter 2, for more details.
So far, all the changes that have been made to ExampleTable1.java have centered around a table's set of visual properties. Keeping the changes made thus far, we will continue by making changes to some of ExampleTable1.java's interactive properties.
1.4 Adding Interactivity
In a hypothetical scenario, our example table could be used to track orders and accounts with a large number of customers. Your users will likely want to update the data, sort the information displayed in the table, and select sections of the table to perform operations on them.
We will add some basic user-interactivity to our example table to give you a sense of some of the things you can do with JClass LiveTable. You can explore user-interactivity further in Programming User Interactivity, in Chapter 6.
1.4.1 Making the Cells Editable
Background
As far as user interaction goes, one of the problems with this example table is that it is not editable. If a user clicks a cell, the focus changes, but nothing else happens. To make the cell editable, we have to change the data source object to an editable data source. The
JCVectorDataSource
class we used as our data source has an editable counterpart calledJCEditableVectorDataSource
.Procedure
The modified ExampleTable1.java currently contains the lines:
import com.klg.jclass.table.data.JCVectorDataSource;
JCVectorDataSource ds = new JCVectorDataSource();
import com.klg.jclass.table.data.JCEditableVectorDataSource;
JCEditableVectorDataSource ds = new JCEditableVectorDataSource();Once you change these lines, recompile and run the modified ExampleTable1.java file. The table now looks like this:
Figure 1 : The table with editable cells. Note cell (3, 2) is being edited.
Note: You can also run ExampleTable6.java, which already contains these changes.
Clicking a cell will bring up the editing component for the type of data in the cell. Since all of the cells contain Strings, the editing component is a text editor. For more information, see Displaying and Editing Cells, in Chapter 4.
1.4.2 Enabling Cell Selection
Background
JClass LiveTable provides methods that set how users can select cells, ranges of cells, and entire rows and columns. Selection is enabled by setting the
SelectionPolicy
property. By default, cell selection reverses the foreground and background colors of the cells to highlight the selection.Procedure
You can enable selection by adding the following code to the example program:
table.setSelectionPolicy(JCTableEnum.SELECT_RANGE);This allows users to select one or more cells in rows or columns by clicking and dragging the mouse, or using keyboard combinations.
By default, setting the
SelectionPolicy
property enables selection of entire rows or columns by clicking on the row or column label. When the user clicks on the column label, the column display (including the label) is reversed to highlight the selection. Similarly, when the user clicks on the row label, the row display (including the label) is reversed and the selection is highlighted.You can configure the table not to highlight the label by using the following line of code:
table.setSelectIncludeLabels(false);You can also change the default highlighting colors by setting the
SelectedForeground
andSelectedBackground
properties. See Customizing Cell Selection, in Chapter 6, for more information.
1.4.3 Resizing Using Labels Only
Background
By default, users can resize rows, columns, and labels by clicking their borders and dragging. You can change this functionality so that the resize capability is available only from the label. To resize a column, the user resizes its label instead of its cells. JClass LiveTable provides the
AllowResizeBy
property to enable this feature.Procedure
In the modified ExampleTable1.java, add this line to the
table.setAllowResizeBy(JCTableEnum.RESIZE_BY_LABELS);ExampleTable1
class:Recompile and run the modified ExampleTable1.java file. The mouse cursor becomes a "resize" cursor only when it is located over the borders of the column labels.
Figure 2 : A table with cell selection and exclusive label resizing. Note that the cell range of (2, 0) through (2, 2) has been selected.
Note: You can also run ExampleTable7.java, which already contains these changes.
1.4.4 Enabling Column Sorting
Background
It might be easier for your users to find certain information if they can sort the table based on cell values in a column. For example, that way they can find a customer name alphabetically or find large orders by sorting the "Quantity (lbs.)" column.
A simple way to allow your users to sort a row or column is to add a trigger that maps a column or row event onto a label. Since the program currently selects a column when you click its corresponding label, you need a way to differentiate between a selection and a call to sort the column.
Procedure
You can allow users to sort the column by using a Shift-click combination. Add these lines to your list of import statements in the modified ExampleTable1.java:
import com.klg.jclass.table.MouseActionInitiator;
import java.awt.event.InputEvent;These will allow your program to work with different mouse events. Now, to add the action, add this line to the
table.addAction(new MouseActionInitiator(ExampleTable1
class:
MouseActionInitiator.ANY_BUTTON_MASK,InputEvent.
SHIFT_MASK),JCTableEnum.COLUMN_SORT_ACTION);When you recompile and run the program, you will see that holding down the Shift key and clicking a column label sorts the rows in ascending alphabetical/numerical order, based on the contents of the column.
Figure 3 : Before enabling column sorting, when the third column's label was clicked, all column cells were selected (left). After inserting the code, Shift-clicking the column's label resulted in an alphabetical sort (right).
Note: You can also run ExampleTable8.java, which already contains these changes.
1.5 Proceeding from Here
This exercise has given you a simple overview of some of the types of things you can do with JClass LiveTable.
- For detailed information on the design elements of JClass LiveTable, see Building a Table, in Chapter 2. Appendix B, JClass LiveTable Property Listing, contains the JClass LiveTable Properties in table format.
- To learn about using the new JClass LiveTable data model, see Working with Table Data, in Chapter 3, and Displaying and Editing Cells, in Chapter 4.
- To learn about the formulae package in com.klg.jclass.util, which has special capabilities for working with mathematical objects, see Adding Formulas to JClass LiveTable, in Chapter 5.
- To learn about user-interaction with JClass LiveTable, see Programming User Interactivity, in Chapter 6.
- To try this same tutorial in a JavaBeans development environment, see JClass LiveTable Beans and IDEs, in Chapter 9.
You can find many more examples of ways to customize and enhance applications and applets in the demos directory of your JClass LiveTable distribution.
1.6 Internationalization
Internationalization is the process of making software that is ready for adaptation to various languages and regions without engineering changes. JClass products have been internationalized.
Localization is the process of making internationalized software run appropriately in a particular environment. All Strings used by JClass that need to be localized (that is, Strings that will be seen by a typical user) have been internationalized and are ready for localization. Thus, while localization stubs are in place for JClass, this step must be implemented by the developer of the localized software. These Strings are in resource bundles in every package that requires them. Therefore, the developer of the localized software who has purchased source code should augment all .java files within the /resources/ directory with the .java file specific for the relevant region; for example, for France, LocaleInfo.java becomes LocaleInfo_fr.java, and needs to contain the translated French versions of the Strings in the source LocaleInfo.java file. (Usually the file is called LocaleInfo.java, but can also have another name, such as LocaleBeanInfo.java or BeanLocaleInfo.java.)
Essentially, developers of the localized software create their own resource bundles for their own locale. Developers should check every package for a /resources/ directory; if one is found, then the .java files in it will need to be localized.
For more information on internationalization, go to: http://java.sun.com/j2se/1.4.2/docs/guide/intl/index.html.
1 This exercise assumes that you are familiar with Java programming concepts and have previously written and compiled Java programs. It also begs forgiveness for yet another play on the coffee theme of Java.
2Note that the example programs in your JClass LiveTable distribution contain a package name. To run the compiled class, you must type the full package name, for example:
java examples.table.intro.ExampleTable1