JClass LiveTable

PreviousNextIndex

2

Building a Table

Table Anatomy 101  Setting and Getting Properties  Preset Table Styles  Global Table Properties 

Column Width and Row Height Properties  Cell Styles  Cell and Label Spanning 

Using the JClass LiveTable API, you can customize the appearance of your tables with colors, borders, custom scrollbars, and other display properties. This chapter describes the properties you can set to define the structure and appearance of your tables. The properties are set for rows, columns, and cells. See Appendix B, JClass LiveTable Property Listing, for a reference summary of the properties.

Many of the table's properties are set using methods of the JCTable class. However, some properties are set in the data source. For more information on setting properties using methods in the data source, see Working with Table Data, in Chapter 3, and Displaying and Editing Cells, in Chapter 4. The following descriptions note whether setting the property from the data source is applicable.

JClass LiveTable property accessor methods are also exposed to JavaBeans-compatible IDEs through the LiveTable Bean.


2.1 Table Anatomy 101

JClass LiveTable provides a scrollable viewing area for its cells and labels.

Figure 4 :  The components of a Table.

The following list defines the terminology used with JClass LiveTable:

Label

A label is a non-editable cell appearing in a row at the top or bottom of the table, or in a column at the left or right side of a table. Like cells, labels can contain text or components, or can display an image. Please refer to sections later in this chapter, starting with Section 2.4.5, Row and Column Labels, for more information about labels.

Scrollbar Components

These components are created and displayed if the number of rows or columns in the table is greater than the number of rows or columns visible on the screen. They provide end-users with the ability to scroll through the entire table. You can learn more about scrollbars in Programming User Interactivity, in Chapter 6.

Cell

A cell is an individual container of table data. A cell is visible if it is currently scrolled into view. The entire collection of displayed cells is called the cell area. You can find more information about defining cell appearance later in this chapter.

Current Cell

This is the cell that currently has the user input focus. End-users can enter and edit the value of this cell, unless this ability is disabled.

Cell Rendering, Editing and Management

Cell drawing and editing is handled by the com.klg.jclass.cell package. Specifically, cell rendering and editing are handled by the JCLightCellRenderer, JCComponentCellRenderer, and JCCellEditor interfaces.

Cells are drawn into the cell area by either a JCLightCellRenderer object that understands how to draw that specific type of data, or a JCComponentCellRenderer object that uses a lightweight component such as JLabel to render data.

If the user types or clicks a cell, and there is a JCCellEditor for the data type of the cell, the editor component is displayed over the cell. See Displaying and Editing Cells, in Chapter 4, for more information on cell editors and renderers.


2.2 Setting and Getting Properties

There are two ways to set and retrieve JClass LiveTable properties:

  1. By calling property set and get methods in a Java program
  2. By using a Java IDE at design-time (JavaBeans)

Each method changes the same table property. This manual therefore uses properties to discuss how features work, rather than using the method or Property Editor you might use to set that property.

2.2.1 Table Contexts

A context is composed of a row and column index, both zero-based. The current context specifies the portion of a table's cells and labels for which an application sets and retrieves properties. Specifying a table context is part of any method that sets table properties.

The following table outlines all table contexts. The example set the background color to white for any cells encompassed by the defined context.

Context selection

  Examples

a cell

  (0,1)

  (1,0)

Referenced by a row index and a column index.

all row or column cells

  (0,JCTableEnum.ALLCELLS)

  (JCTableEnum.ALLCELLS,0)

Referenced by the constant JCTableEnum.ALLCELLS in conjunction with a row or column index.

 

This does not include labels.

a range of cells

  (range); /* range defined as JCCellRange(0,1,1,2) */

Referenced by the location of the top-left cell/label and the location of the bottom-right cell/label in the range.

A range be referenced as one context when defining JCCellRange.

a row or column label

  (0,JCTableEnum.LABEL)

  (JCTableEnum.LABEL,0)

Referenced by the constant JCTableEnum.LABEL in conjunction with a row or column index.

all row or column labels

  (JCTabelEnum.ALL,

  JCTableEnum.LABEL)

  (JCTableEnum.LABEL,

  JCTableEnum.ALL)

Referenced by both JCTableEnum.ALL and JCTableEnum.LABEL, the order dependent on which set of labels is being referenced.

all labels

  (JCTableEnum.LABEL,JCTableEnum.LABEL)

Referenced using (JCTableEnum.LABEL, JCTableEnum.LABEL).

an entire row or column

  (1,JCTableEnum.ALL)

  (JCTableEnum.ALL,1)

Referenced by the constant JCTableEnum.ALL in conjunction with a row or column index.

 

The context includes labels.

all table cells

  (JCTableEnum.ALLCELLS,JCTableEnum.ALLCELLS)

Referenced by (JCTableEnum.ALLCELLS, JCTableEnum.ALLCELLS).

 

The context does not include labels.

an entire table

  (JCTableEnum.ALL,JCTableEnum.ALL)

Referenced by (JCTableEnum.ALL, JCTableEnum.ALL).

 

The context includes labels.

2.2.2 Setting Table Properties with Java Code

When setting table properties, you work with either general table properties or Cell Styles. Cell Styles affect specific cell appearance and behavior settings for elements such as color, typefaces, border types, editability and cell text/image alignment. All other non-cell properties are handled as table-wide settings. To learn what can be defined with Cell Styles, please refer to Section 2.6, Cell Styles, later in this chapter.

Setting Regular Cell and Label Properties

Setting cell and label properties that are not handled with Cell Styles involve the straightforward use of set and get methods. Every JClass LiveTable property has a set and get method associated with it.

For example, to set the value of the PixelHeight property to a value of 60 for all labels and the first non-label row, the setPixelHeight() method is called:

  table.setPixelHeight(JCTableEnum.LABEL,60);
  table.setPixelHeight(0,60);

As another example, to set the value of the PixelWidth property to a value of 90 for all labels and the first non-label row, the setPixelWidth() method is called:

  table.setPixelWidth(JCTableEnum.LABEL,90);
  table.setPixelWidth(0,90);

You can also set properties for the entire table. For example, use the MarginHeight() and MarginWidth() properties to set the distance between cell borders and cell contents:

  table.setMarginHeight(10);
  table.setMarginWidth(10);

Setting Cell Style Properties

Setting Cell Style properties involves the implementation of the CellStyleModel interface. This interface provides all information that the cell editors/renderers use.

JClass LiveTable includes the JCCellStyle class, which is the default implementation of CellStyleModel. Also included are default look and feel settings for labels and cells.

For example, the following sample code adopts the default values set in JCCellStyle, but changes the cell colors to black (background) and yellow (text), and applies this change to cell(2, 2):

  JCCellStyle cellcolors = new JCCellStyle();
  cellcolors.setBackground(Color.black);
  cellcolors.setForeground(Color.yellow);
  table.setCellStyle(1, 1, cellcolors);

In this example, the code acquires the default label look and feel for the particular operating system you are using. Then, the foreground and background colors are changed for all labels displayed in the table:

  CellStyleModel labelStyle = table.getDefaultLabelStyle();
  labelStyle.setBackground(Color.blue);
  labelStyle.setForeground(Color.white);

Most properties can be applied to individual cells as well as ranges. You can also set properties for a range of cells defined by a JCCellRange.

The following example sets a property to a range of cells using JCCellRange:

  JCCellRange range = new JCCellRange(0,3,2,4);
  JCCellStyle cell = new JCCellStyle();
  cell.setBackground(Color.red);
  table.setCellStyle(range, cell);

For more information about Cell Styles, please see Section 2.6, Cell Styles, later in this chapter.

2.2.3 Setting Properties with a Java IDE at Design-Time

JClass LiveTable can be used with a Java Integrated Development Environment (IDE), and its properties can be manipulated at design time. Consult the IDE documentation for details on how to load third-party Bean components into the IDE.

See JClass LiveTable Beans and IDEs, in Chapter 9, for complete details on using JClass LiveTable's JavaBeans in IDEs.


2.3 Preset Table Styles

You can quickly build a standard table with a number of default settings by using the JCListTable class. The preset features of this class affect:

These settings are overridden by any properties you specifically set later on in your program.

To view the JCListTable class in action, please look at the Cars example in the JCLASS_HOME/examples/table/layout/ directory, and the Stocks demo in the JCLASS_HOME/demos/table/stocks/ directory.


2.4 Global Table Properties

The following sections outline all properties that globally affect the appearance of your table. When any of these properties are set, they are set for the entire table.

2.4.1 Focus Rectangle Appearance

The focus rectangle visually informs the user which cell currently has the table's focus. You can change the color of the focus rectangle by using the setFocusColor() method. For example:

setFocusColor(Color.blue);

Using the setFocusIndicator() method lets you set the type of focus indicator used. Valid indicators are:

FOCUS_NONE
FOCUS_HIGHLIGHT
FOCUS_RECTANGLE
FOCUS_THIN_RECTANGLE
FOCUS_DASHED_RECTANGLE

2.4.2 Screen Cursor Type

Use the setCursor() method to determine which AWT cursor type is used in your table. If cursor tracking is set to false, then a constant cursor is used (cursor tracking can be used to change the cursor appearance, depending over which part of the table the cursor is). By default, TrackCursor is set to true.

2.4.3 Scrollbars

JClass LiveTable offers control over the appearance and behavior of scrollbars. This section outlines how to program the appearance of scrollbars. For information about programming scrollbar behavior, please refer to Table Scrolling, in Chapter 6.

Positioning Scrollbars

The way scrollbars should be attached to the table depends on the style of table you need for your application. Standard-style tables attach the scrollbars to the cell/label area and move them to match changes to the size of the visible area.

The HorizSBPosition property sets how the horizontal scrollbar is attached to the table. Similarly, VertSBPosition sets how the vertical scrollbar is attached to the table.

HorizSBAttachment sets how the end of the horizontal scrollbar is attached to the table. When set to JCTableEnum.SIZE_TO_CELLS (default), the scrollbar ends at the edge of the visible cells. When set to JCTableEnum.SIZE_TO_TABLE, the scrollbar ends at the edge of the table.

To specify standard-style table scrollbars, leave the position and attachment properties at their default values.

HorizSBOffset and VertSBOffset specify the offset between the scrollbars and the table (default: 0 pixels). This offset usually applies to the space between the scrollbars and the table's cells/labels. However, when the scrollbars are attached to the side of the component, it can also apply to the space between the scrollbars and the side of the component, and only when there is space between the last row/column and the edge of the component.

Setting the Top Row and Left Column

When a table initially appears, you can set it so that a particular row and column are set as the top and left. Scrolling is set up automatically. Use setTopRow() and setLeftColumn() to define the top row and left-most column. This value is updated as a user scrolls through a table.

Setting Scrollbar Display Conditions

By default, JClass LiveTable displays each scrollbar only when the table is larger than the number of rows/columns visible on the screen. To display a scrollbar at all times, set HorizSBDisplay and/or VertSBDisplay to JCTableEnum.SCROLLBAR_ALWAYS. Set them to JCTableEnum.SCROLLBAR_NEVER to completely disable the scrollbar display. To display scrollbars only when the table size is greater than the viewing area, set them to JCTableEnum.SCROLLBAR_AS_NEEDED.

Note: Although scrollbars are removed, a user can still scroll with the keyboard. See Managing Table Scrolling, in Chapter 6, for complete information on disabling interactive scrolling.

Using your own Scrollbar Component

You may want to use a scrollbar component other than the default provided with JClass LiveTable. To do this, use the setVertSB() and setHorizSB() methods. The scrollbar must be a JScrollBar instance.

2.4.4 Cell Selection Colors

When users select a cell or a range of cells, it often helps to highlight them. This section outlines how to control the appearance of selected cells. For information about programming cell selection behavior, please refer to Cell Selection, in Chapter 6.

Setting Cell Selection Colors

The background and foreground colors used for selected cells are specified by setSelectedBackground() and setSelectedForeground(). By default, selected cells are displayed in reverse video (i.e., the normal background and foreground color values have been swapped). The current cell displays the selection colors in its border.

Using the previous methods requires you to select a specific foreground or background color. Instead of committing to one color, you can also use color mode methods that allow you to define selection colors by associating them with other foreground and background colors.

Use setSelectedBackgroundMode() to set how selected background colors are determined. Valid modes include:

Use setSelectedForegroundMode() to set how selected foreground colors are determined. Valid modes include:

2.4.5 Row and Column Labels

A row or column label is a non-editable cell that identifies the row or column to the user. Row and column label values are set in the data source (see Working with Table Data, in Chapter 3). By default, row and column labels are displayed in your table, regardless of whether you have specified contents for the labels in the data source (they will be empty if there are no labels defined in the data source). To prevent row and column labels from displaying, you must use the methods:

  table.setRowLabelDisplay(false);
  table.setColumnLabelDisplay(false);

Placing Labels

You can specify the positioning of row/column labels on the screen using the setRowLabelPlacement() and setColumnLabelPlacement() methods. If you insert the placement methods in the table.setColumnLabelPlacement(placement) or table.setRowLabelPlacement(placement) statements, valid values include:

Column and Row Placement

  Example

JCTableEnum.PLACE_TOP

JCTableEnum.PLACE_RIGHT

 

The labels are displayed at the top and to the right of the table (default).

JCTableEnum.PLACE_TOP

JCTableEnum.PLACE_LEFT

 

The labels are displayed at top and to the left of the table.

JCTableEnum.PLACE_BOTTOM

JCTableEnum.PLACE_RIGHT

 

The labels are displayed at the bottom and to the right of table.

JCTableEnum.PLACE_BOTTOM

JCTableEnum.PLACE_LEFT

 

The labels are displayed at the bottom and to the left of the table (reversed default).

Defining Label Spacing

Normally, there is no space between labels and the cell area. The RowLabelOffset property specifies the distance in pixels between the row labels and the cell area. Similarly, the ColumnLabelOffset property specifies the distance in pixels between the column labels and the cell area. If you specify a negative value, the cell area overlaps the labels.

Offset value examples

 

ColumnLabelOffset(0);

RowLabelOffset(0);

ColumnLabelOffset(15); RowLabelOffset(15);

ColumnLabelOffset(-10); RowLabelOffset(-10);

2.4.6 Cell and Label Border Width

The width of the borders around the cells and labels is specified by the setCellBorderWidth() method. This method's actions apply to the entire table. By default, the borders are 1 pixel wide. The following table demonstrates the effect of different bordercell widths:

CellBorderWidth Examples

 

table.setCellBorderWidth(2);

 

sets the bordercell width for all cells and labels to a value of two pixels

table.setCellBorderWidth(5);

 

sets the bordercell width for all cells and labels to a value of five pixels

2.4.7 Cell and Label Margins

The MarginWidth and MarginHeight properties alter the space between the cell borders and the contents of cells.

The MarginWidth property sets the distance (in pixels) between the inside edge of the cell border and the left and right edge of the cell's contents (default: 2). The MarginHeight property specifies the margin (in pixels) between the inside edge of the cell border and the top and bottom edge of the cell's contents (default: 1).

These properties affect all cells and labels in the table - margins cannot be set for individual cells.

The following table demonstrates the effect of different margin height and width settings:

Cell and Label Margin Examples

 

table.setMarginHeight(2);

table.setMarginWidth(5);

 

sets the margin height to 2 and the width to 5

table.setMarginHeight(10);

table.setMarginWidth(10);

 

sets the margin height and width to 10

2.4.8 Component Borders

The ComponentBorderWidth property sets the spacing between the border of a table's cells and components that are inserted into them. By default, this property is set to 0.

2.4.9 Frame Border Attributes

The FrameBorder property is an instance of CellBorderModel, and sets the border surrounding the cell and label areas.

The FrameBorderWidth property specifies the thickness of the border surrounding the cell and label areas. Its default value is 0 (no frame border).

Border colors are calculated using the table's background color.

The following table outlines all the valid frameborder types, and demonstrates frameborder widths. The FrameBorderWidth property, which specifies the thickness of the border surrounding the cell and label areas, has been set to a value of 6. The code in each cell is the CellBorderModel value, which is used in the statement: table.setFrameBorder(new JCCellBorder(value)).

FrameBorder Attribute Examples

 

JCTableEnum.BORDER_ETCHED_IN

creates a border that appears set in

  JCTableEnum.BORDER_ETCHED_OUT

  creates a raised border

JCTableEnum.BORDER_FRAME_IN

creates a frame border whose enclosed cells and labels appear set in

  JCTableEnum.BORDER_FRAME_OUT

  creates a frame border whose enclosed cells and   labels appear raised

JCTableEnum.BORDER_IN

creates a border whose enclosed cells and labels appear set in

  JCTableEnum.BORDER_OUT

  creates a border whose enclosed cells and labels   appear raised

JCTableEnum.BORDER_PLAIN

creates a plain frame border

  JCTableEnum.BORDER_THIN

  creates a thin frame border

JCTableEnum.BORDER_NONE

creates no frame border (default)

 

2.4.10 Row and Column Definition

Determining the Number of Rows/Columns

The NumRows and NumColumns properties are set using methods in the data source. To retrieve these values, use the JCVectorDataSource.getNumRows() and JCVectorDataSource.getNumColumns() methods. Please see Setting Stock Data Source Properties, in Chapter 3, for information on setting these properties in the data source.

The number of rows/columns must be greater than the number of frozen rows/columns. For more information on frozen rows/columns, see `Freezing' Rows and Columns.

Setting and Getting Visible Rows and Columns

The number of rows and columns currently visible in the window is specified by the VisibleRows and VisibleColumns properties.1

You can force the table to display a particular number of rows or columns by calling setVisibleRows() and setVisibleColumns().

To retrieve the values of VisibleRows or VisibleColumns, call the getVisibleRows() and getVisibleColumns() methods. These methods return the number of visible non-frozen rows or columns. These values determine the preferred size of the table and are not updated dynamically as a user resizes the table.

To get live values of the table, use getNumVisibleRows() and getNumVisibleColumns(), which return the total number of visible rows or columns.

To work with cells instead of rows or columns, use the getVisibleCells() method, which returns the range of non-frozen visible cells.

Displaying the Entire Table

To display the entire table, set VisibleRows and VisibleColumns to JCTableEnum.NOVALUE. Setting either property to NOVALUE sets a special flag that causes the table to attempt to resize to make all rows or columns visible.

Swapping Rows or Columns

You can make two rows or columns switch places by using the swapRows() and swapColumns() methods. For example, to swap rows 3 and 9:

  table.swapRows(3,9)

These methods do not affect the data source, but use an internal mapping table to keep track of row and column locations.

To reset the rows or columns to their original locations, based on the data source, use the resetSwappedRows() or resetSwappedColumns() methods.

`Freezing' Rows and Columns

An application can make rows and columns non-scrollable by using the FrozenRows and FrozenColumns properties. You can use frozen rows or columns to hold important information on the screen as a user scrolls through the table (such as totals at the bottom of a table). You could also use frozen rows or columns as additional rows or columns that act like labels; see Section 2.7.1, Using Spanning to Create Multiline Headers for an example.

Frozen rows/columns always start from the beginning of the table. By default, they are editable and traversable, but not sorted and cannot be dragged. The following figure shows an example of frozen rows.

Figure 5 :  Visible and Frozen Rows and Columns- note absence of scrollbar to right of frozen rows.

Setting frozen rows or columns sets the number of columns from the left or the number of rows from the top. For example:

  table.setFrozenRows(2);

freezes the first two rows of the table, and

  table.setFrozenColumns(4);

freezes the first four columns of the table.

If you want to freeze a single column or row in the middle of the table, you can easily move the specified row or column to the beginning of the table by using the swapRows() or swapColumns() method (described above), then freeze the row or column.

To move and freeze more than one column or row, you will have to call the moveRows() or moveColumns() method in the data source (see Using Stock Data Sources, in Chapter 3) to move the desired rows/columns to the beginning of the table, then set FrozenRows or FrozenColumns to the number of rows/columns that you want to freeze.

Placing Frozen Rows/Columns

You can place frozen rows at either the top or bottom of the table. Frozen columns can be placed at either the left or right of the table. The placement of frozen rows/columns does not affect the location of the rows/columns in the data source.

To change the placement of the frozen rows, set the FrozenRowPlacement property to either JCTableEnum.PLACE_TOP or JCTableEnum.PLACE_BOTTOM.

To change the placement of all frozen columns, set the FrozenColumnPlacement property to either JCTableEnum.PLACE_LEFT or JCTableEnum.PLACE_RIGHT.

2.4.11 Controlling Cell Editor Size

The table can control the size of a cell editing component using the EditHeightPolicy and EditWidthPolicy properties. Each of these properties can take one of three values:

These properties allow the table to have better control over cell editors created using the com.klg.jclass.cell.JCCellEditor interface. For more information about cell editors, see Displaying and Editing Cells, in Chapter 4.


2.5 Column Width and Row Height Properties

By default, JClass LiveTable sets the height of rows to display one line of text. The width of columns is set by default to display 10 characters of text. If a cell value, image file, or component does not fit in its cell, the cell displays clipping arrows by default. Each row can have its own height, and each column its own width.

JClass LiveTable provides two different ways to specify row height and column width: character and pixel. Character specification determines the height/width by the number of characters or lines that the row/column can display. Pixel specification determines the height/width by the explicit number of pixels.

Only one method can be used for a row or column. Pixel specification overrides character specification.

Note: When users interactively resize rows/columns, the row height/column width is specified by pixel regardless of how your application specified it.

Figure 6 :  The difference between Character and Pixel Row/Column specification.

2.5.1 Character Height and Width

The CharWidth property specifies the number of characters a column can display. CharHeight specifies the number of lines of text a row can display. For these properties to control row height/column width, PixelWidth and PixelHeight must be set to JCTableEnum.NOVALUE.

To determine the pixel dimensions of a row or column whose height/width was set by CharWidth or CharHeight, use the getColumnPixelWidth() or getColumnPixelHeight() methods.

The following table demonstrates different character height and width settings:

For Column Width:

 

table.setCharHeight(0,1);

sets the first row's height to 1 character

table.setCharHeight(0,4);

sets the first row's height to four characters

For Row Height:

 

table.setCharWidth(4,3);

sets the fifth column's width to 3 characters

table.setCharWidth(4,10);

sets the fifth column's width to 10 characters

Character specification is convenient when you know how many characters you want a row/column to display. It works best with non-proportional2 fonts because JClass LiveTable uses the widest character along with the largest ascender/descender to guarantee that the specified number of characters will fit in the cell or label.

2.5.2 Absolute Pixel Height and Width

PixelWidth and PixelHeight specify column width and row height in pixels. You can set these properties to an explicit pixel value using JCTableEnum.NOVALUE or JCTableEnum.VARIABLE (this value is discussed in detail in the following section).

Unless set to JCTableEnum.NOVALUE (default), these properties override the CharWidth and CharHeight properties. The next illustration shows setting PixelHeight to a pixel value.

Absolute Pixel Height Examples

 

table.setPixelHeight(4,15);

sets the fifth row's height to 15 pixels

table.setPixelHeight(4,30);

sets the fifth row's height to 30 pixels

2.5.3 Variable Pixel Height and Width

An application can have JClass LiveTable automatically size rows and columns to fit the contents of the table by setting PixelWidth and PixelHeight to JCTableEnum.VARIABLE. As your application changes table attributes affecting the cells' contents, the table will resize the rows and columns to fit.3

When a cell contains a component, JClass LiveTable sizes the cell to fit the component's preferred size.

To determine the pixel dimensions of a row or column with variable height or width, call the getRowPixelHeight() and getColumnPixelWidth() methods.

Defining How Much of the Table is Used in Pixel Estimates

By default, the JCTableEnum.VARIABLE value, when used with PixelHeight and PixelWidth, uses the entire row or column to calculate pixel dimensions.

Using VARIABLE with large tables can result in general table slowdowns due to the large number of cells involved in the height calculation. For large tables, use the JCTableEnum.VARIABLE_ESTIMATE value instead, which sets the pixel dimension to the highest value found in a range that you define.

You can explicitly control the range of cells used in the variable height calculation by using setVariableEstimateCount(). Typically, this value is set to the number of cells expected to be visible at any time.

Changing Variable Row and Height Dimensions to Fixed Values

Setting PixelHeight and PixelWidth to JCTableEnum.AS_IS does not change the pixel dimensions, and makes the current height and width settings fixed values.

Additionally, if you have set your row and column dimensions to be of variable height and width, and the user interactively resizes a row or column, the PixelWidth and PixelHeight values are converted to fixed values.

2.5.4 Maximum and Minimum Pixel Height and Width

While you can work with varying pixel height and width dimensions, you can still set the absolute maximum and minimum pixel dimensions for a table.

Use setMaxHeight() and setMinHeight() to determine the maximum height of any or all rows, all column labels or the whole table. Likewise, use setMaxWidth() and setMinWidth() to determine the minimum width of any or all columns, all row labels, or the whole table.

2.5.5 Displaying and Editing Multiple Lines in Cells

When you set the height and width of your cells, you adjust how much of the data can be displayed in the cell. If your cell contains text, then JClass LiveTable makes it possible for you to display and edit multiple lines.

For cell rendering, if the data displayed in the cells contains a newline character (\n), the cell is automatically displayed as a multiline cell.

For cell editing, by default, text is edited on a single line. For multiline editing, you must set the multiline editor. To set a multiline editor, you need to set the Cell Style's editor properties. Create a Cell Style and set the editor for it, then call setCellStyle() with a row, column, or range. Please refer to Section 2.6, Cell Styles, for more information about setting editor properties.

2.5.6 Using Row Height and Width to Hide Rows and Columns

An application can "hide" rows and columns from the end-user by setting the PixelHeight/PixelWidth properties to zero pixels (the current cell should not be in the hidden row/column). Though the row/column appears to have vanished, the application can set attributes or change cell values.

Note: The recommended way of hiding rows and columns is to set the boolean value of setRowHidden() and setColumnHidden() to true.

Figure 7 :  Hiding the "Order Date" column.


2.6 Cell Styles

While the classes and properties mentioned in previous sections define table-wide or row/column properties, you can use Cell Styles to set the properties of individual cells or labels, or ranges of cells.

Every cell in a table is associated with a style that defines how the cell looks, how the data is edited, and whether the cell is traversable and editable.

2.6.1 Cell Style Properties and Implementation

A Cell Style is any object that implements the CellStyleModel interface. With this interface, the style properties that you can define are:

Cell Styles make it easier to define and manage the appearance of a table. Instead of working with a myriad of visual properties for ranges of cells, you can define a particular Cell Style (which encompasses all of these properties), and then apply the style to any cells or labels.

Getting and setting Cell Styles

In order to set a Cell Style, you can use one of two methods:

  // this applies a style to a cell
  setCellStyle(int row, int column, CellStyleModel csm);
  // this applies a style to a range of cells
  setCellStyle(JCCellRange cr, CellStyleModel csm);

To retrieve the style for a cell, use:

  CellStyleModel getCellStyle(int row, int column);

2.6.2 Defining Your Own or Changing Built-In Cell Styles

You can easily modify Cell Styles by making property changes to the JCCellStyle implementation, as well as default cell and label styles.

Changing Cell Styles

You can change a Cell Style by creating a new JCCellStyle object, modifying the desired properties, and applying these changes with the setCellStyle() method. For example, the style for cell (2, 2) is changed by using this code:

  JCCellStyle cs = new JCCellStyle();
  cs.setBackground(Color.blue);
  table.setCellStyle(2, 2, cs);

You can also use the getCellStyle() method to retrieve the style properties from a particular cell. Consider this example, which gets the properties of cell (0, 0), then sets the background color to red:

  JCCellStyle cs = new JCCellStyle();
  cs.setBackground(Color.blue);
  table.setCellStyle(JCTableEnum.ALL, JCTableEnum.ALL, cs);

  CellStyleModel csm = table.getCellStyle(0, 0);
  csm.setBackground(Color.red);

The problem with using getCellStyle() is that the style obtained from an individual cell may not be unique to that cell. Styles can also be applied to ranges, or an entire table. In the above example, you might expect the code to produce a table whose cells have a blue background, with the exception of cell (0, 0) which should have a red background. However, since the style you are retrieving from cell (0, 0) is used for the whole table, all cell backgrounds will be red.

If you wanted to change the background color for cell (0, 0) to red, even though that cell's style is also being used for the whole table, you can work with a unique Cell Style:

  CellStyleModel csm = table.getUniqueCellStyle(0, 0);
  csm.setBackground(Color.red);
  table.setCellStyle(0, 0, csm);

The bottom line is that you do not need to apply specific style changes with setCellStyle() if you want to change all the cells that share the style. In other words, the first example which used:

  CellStyleModel csm = table.getCellStyle(0, 0);
  csm.setBackground(Color.red);

is correct if your intention is to set the background color to red for all cells that share the same style as cell (0, 0).

Retrieving all Styles Used in a Table

You can easily work through all Cell Styles found in a table (even without knowing what they all are) by calling Collection getCellStyles(). You can use this to change a property for all styles in your table. The following example performs this operation, as it retrieves all the table's styles, and changes the foreground color to blue:

  Collection col = table.getCellStyle();
  Iterator it = col.iterator();
  while(it.hasNext()){
    CellStyleModel csm = (CellStyleModel)it.next();
    csm.setForeground(Color.blue);
  }

Creating "Parent" Styles

JClass LiveTable allows you to create styles that inherit property values from a parent style. For example, imagine you have a style (mySimpleStyle) with white background and black foreground (text) settings. If you want to change the style properties for a particular cell, or cell range, but retain the original properties for the other cells, you have two choices.

  CellStyleModel myNewStyle = (CellStyleModel)(mySimpleStyle.clone());
  myNewStyle.setBackground(Color.red);
  table.setCellStyle(0, 0, myNewStyle);

The problem with this approach is that if mySimpleStyle changes (for example, the font is changed), myNewStyle will not pick up this change. Updating styles to match changes in other styles can be tedious.

  CellStyleModel myNewStyle = new JCCellStyle(mySimpleStyle);
  myNewStyle.setBackground(Color.red);
  table.setCellStyle(0, 0, myNewStyle);

By creating a JCCellStyle with another style as an argument, you create a link between the new style and the original one. Any property that is changed to the new style overrides the setting that comes from the original style, and any changes made to the original style (that are not overridden) are picked up by the new style.

The following example demonstrates the relationship between parent and child styles. Here, both styles end up using the anotherFont typeface. However, since the foreground color in myNewStyle was changed to yellow, setting the myOldStyle foreground color to white will not affect myNewStyle.

  myNewStyle.setForeground(Color.yellow);
  myOldStyle.setFont(anotherFont);
  myOldStyle.setForeground(Color.white);

The CellStyleModel has getParentStyle() and setParentStyle() methods in addition to using the special constructor.

2.6.3 Using and Modifying JClass LiveTable's Built-In Styles

To define Cell Styles, use the CellStyleModel interface. CellStyleModel is an interface that defines the methods required by an object to specify the attributes of a cell.

JCCellStyle: the Default CellStyleModel Implementation

JClass LiveTable provides an implementation of the CellStyleModel interface in the JCCellStyle class. Creating an instance of this class in your table program is a quick way of setting up a Cell Style. It has the following defaults:

Background

System control color

Border

BORDER_IN

BorderSides

BORDERSIDE_ALL

CellBorderColor

based on the background color of the cell

ClipHints

SHOW_ALL

Data Type

null

Editable

true

Editor

null

Foreground

System control text color

Font

Dialog-Plain-12

HorizontalAlignment

LEFT

Renderer

null

RepeatBackground

NONE

RepeatForeground

NONE

Traversable

true

VerticalAlignment

TOP

JCCellStyle does not specify any DataType, CellEditor, or CellRenderer properties. Editors and renderers are determined by the type of data in the data source if an editor/renderer is not set. Please see Displaying and Editing Cells, in Chapter 4, for more information.

Pluggable Look and Feel (PLAF) Styles

There are two default styles that are used and changed by the current system's PLAF. Use these if you want your table to look and behave in accordance with the host machine's properties (e.g. Swing Metal, Windows). DefaultLabelStyle is automatically applied to labels, while DefaultCellStyle is applied to all cells. Access the default styles as follows:

  CellStyleModel csm = table.getDefaultLabelStlye();
  csm = table.getDefaultCellStyle();

JClass LiveTable handles PLAF through a "parenting" mechanism. When the PLAF changes, JCTableUI updates DefaultLabelStyle and DefaultCellStyle as required.

If you create a cell that uses this default style, but want to change a cell property while maintaining PLAF support for all other cell properties, you have to create a unique style for a cell.

For example, you can create a style for your table that has PLAF support, but changes the text alignment:

  CellStyleModel csm = new JCCellStyle(table.getDefaultCellStyle();
  csm.setHorizontalAlignment(JCTableEnum.CENTER);
  table.setCellStyle(0, 0, csm);

Here, you have created a new style based on DefaultCellStyle, and changed one property HorizontalAlignment. Applying this to cell (0, 0) changes the text alignment, but the other properties (background/foreground color, font, border type) will only change if the host machine's look and feel changes.

To gain a better understanding of how JCTableUI works with default styles, imagine that you are applying this style change:

  CellStyleModel csm = table.getDefaultCellStyle();
  csm.setBackground(Color.blue);

You might think that when the user changes the PLAF, the blue background color will be cancelled out with the new PLAF defaults. This will not happen because JCTableUI uses special wrapper objects to set values (e.g. ColorUIResource), and checks the current value to see if it is an instance of a UI Resource. If so, the property value is changed because JCTableUI assumes the PLAF logic set it. If it is a regular object (in this case, Color), the value will not be updated by JCTableUI.

2.6.4 Working with Colors

Setting Foreground and Background Colors

The foreground and background colors used for cells are specified by the Foreground and Background properties. The following example sets the background color of column 2 to blue:

  JCCellStyle cell = new JCCellStyle();
  cell.setBackground(Color.blue);
  table.setCellStyle(JCTableEnum.ALL,2,cell);

In that example, the JCCellStyle default Cell Styles are used, with one overriding change for the background color.

The same applies in the next example, in which the foreground color value for cell (1, 4) is set to the color white:

  JCCellStyle cell2 = new JCCellStyle();
  cell2.setForeground(Color.white);
  table.setCellStyle(0,3,cell2)

In addition to the row, column indexed contexts, you can set the Foreground and Background properties for a range of cells specified by a JCCellRange object:

  JCCellRange range = new JCCellRange(0,3,2,4);
  JCCellStyle cell = new JCCellStyle();
  cell.setBackground(Color.red);
  table.setCellStyle(range,cell);

Repeating Colors

JClass LiveTable makes it easy to create rows or columns whose background and foreground colors alternate or cycle in a repeating pattern. To create a repeating pattern of background colors, set the RepeatBackgroundColors and RepeatBackground properties as shown in the following example:

  JCCellStyle colors = new JCCellStyle();
  Color[] repeating = {Color.orange, Color.green, Color.white};
  colors.setRepeatBackgroundColors(repeating);
  colors.setRepeatBackground(JCTableEnum.REPEAT_COLUMN);
  table.setCellStyle(JCTableEnum.ALLCELLS,
    JCTableEnum.ALLCELLS, colors);

You can define as many repeating colors as you like. The colors are always selected in the order listed.

Repeating Color Property

  Example

JCTableEnum.REPEAT_COLUMN

 

sets repeating background or foreground colors by rows

 

use as value for setRepeatBackground or setRepeatForeground methods

JCTableEnum.REPEAT_ROW

 

sets repeating background or foreground colors by columns

 

use as value for setRepeatBackground or setRepeatForeground methods

2.6.5 Text and Image Alignment

The horizontal and vertical alignment of text and images within cells and labels is specified by the HorizontalAlignment and VerticalAlignment properties. Cell/label values can be centered or positioned along any side of the cell/label.

Alignment Property

  Examples

 

setVerticalAlignment(JCTableEnum.TOP)

setHorizontalAlignment(JCTableEnum.LEFT)

setVerticalAlignment(JCTableEnum.TOP)

setHorizontalAlignment(JCTableEnum.CENTER)

setVerticalAlignment(JCTableEnum.TOP)

setHorizontalAlignment(JCTableEnum.RIGHT)

setVerticalAlignment(JCTableEnum.CENTER)

setHorizontalAlignment(JCTableEnum.LEFT)

setVerticalAlignment(JCTableEnum.CENTER)

setHorizontalAlignment(JCTableEnum.CENTER)

setVerticalAlignment(JCTableEnum.CENTER)

setHorizontalAlignment(JCTableEnum.RIGHT)

setVerticalAlignment(JCTableEnum.BOTTOM)

setHorizontalAlignment(JCTableEnum.LEFT)

setVerticalAlignment(JCTableEnum.BOTTOM)

setHorizontalAlignment(JCTableEnum.CENTER)

setVerticalAlignment(JCTableEnum.BOTTOM)

setHorizontalAlignment(JCTableEnum.RIGHT)

2.6.6 Cell and Label Fonts

You can specify the font for the text in a cell or label with the Font property. JClass LiveTable supports the use of one or more fonts in each cell/label. The example below sets a bold, serif font for all labels:

  JCCellStyle labelfont = new JCCellStyle();
  labelfont.setFont(new Font("TimesRoman",Font.BOLD,10));
  table.setCellStyle(JCTableEnum.LABEL,JCTableEnum.LABEL,labelfont);

JClass LiveTable can use any of the fonts available to Java. See your Java documentation for details on finding and setting fonts, or refer to Appendix D.

2.6.7 Border Types

All cells and labels have a border around them, and the appearance of the cell or label border can be customized for individual cells and labels.

The border width, as well as the border around the table's frame, are not part of the Cell Style, as they are specified for the entire table. Please refer to Section 2.4, Global Table Properties, for information about setting table-wide properties.

Cell and Label Border Types

Cell and label border types are defined by the JCCellBorder class. JCCellBorder implements the CellBorderModel interface, and can be set like any other Cell Style property.

The following table outlines all the valid cell and label border types. The code in each cell is the JCCellBorderModel value, which is used in the statement: border.setCellBorder(new JCCellBorder(value)).

Note: In order for any different cell or label border type to be visible, the width of the border must be 5 pixels or greater (default: 1).

Cell or Label Border Type Properties

 

JCTableEnum.ETCHED_IN

sets an etched border whose enclosed cells appear raised.

 JCTableEnum.ETCHED_OUT

  sets an etched border whose enclosed cells   appear set in.

JCTableEnum.FRAME_IN

sets a framed border whose enclosed cells appear set in.

  JCTableEnum.FRAME_OUT

  sets a framed border whose enclosed cells appear   raised.

JCTableEnum.IN

sets a plain border whose enclosed cell appears set in.

  JCTableEnum.OUT

  sets a plain border whose enclosed cell appears   raised.

JCTableEnum.PLAIN

set a plain border.

  JCTableEnum.THIN

  sets a plain border that appears thin.

JCTableEnum.NONE

sets no border.

 

The following example sets a blank border for all cells in the first row:

  JCCellStyle border = new JCCellStyle();
  border.setCellBorder(new JCCellBorder(JCTableEnum.BORDER_NONE));
  table.setCellStyle(0, JCTableEnum.ALLCELLS, border);

To retrieve the border style for a cell, use the getCellBorderType() method. This returns a CellBorder object (see below).

Custom Cell and Label Borders

JClass LiveTable includes an interface that allows you to define your own cell borders and backgrounds for cells and labels. The CellBorderModel interface has a single method called drawBackground(). The drawBackground() method allows you to specify the border width, the sides of the cell on which to draw the border, the colors of the border sides, and the dimensions of the rectangle that gets drawn.

To define a new type of border, you have to create an Object that implements the CellBorderModel interface. The following (from the BorderTypes.java example in examples/table/style) defines a single-line border object called LiteBorder:

  class LiteBorder implements CellBorderModel {

  Color color;

  public LiteBorder(Color color) {
    this.color = color;
  }

  public void drawBackground(Graphics gc, int border_thickness, int
    border_sides, int x, int y, int width, int height,
    Color top_color, Color bottom_color, Color plain_color) {

    gc.setColor(color);
    gc.drawRect(x, y, width, height);
    }
  };

Now that the new type of border has been defined, you can use it as you would any cell style property:


JCCellStyle cellborder = new JCCellStyle();
cellborder.setCellBorder(new LiteBorder(Color.gray));
table.setCellStyle(JCTableEnum.ALLCELLS,
  JCTableEnum.ALLCELLS, cellborder);

The examples/table/style directory also contains a program called TextureTable.java, which illustrates how you can use the custom border features to insert a background graphic into cells.

Caution: If you create many different CellBorder objects, it will have an impact on your table's performance.

2.6.8 Cell and Label Border Sides

The CellBorderSides property specifies the sides of a cell or label that display the border type (specified by the JCCellBorder class). By default, the border type is displayed on all sides of a cell or label. The following figure illustrates one of the visual effects that can be achieved.

Figure 8 :  Customized Cell Borders.

The valid values for CellBorderSides are:

  • JCTableEnum.BORDERSIDE_LEFT
  • JCTableEnum.BORDERSIDE_BOTTOM
  • JCTableEnum.BORDERSIDE_RIGHT
  • JCTableEnum.BORDERSIDE_ALL
  • JCTableEnum.BORDERSIDE_TOP
  • JCTableEnum.BORDERSIDE_NONE
  • Specifying border sides is accomplished by OR-ing together all desired CellBorderSides values. The following example establishes cell borders on the left and top sides for all cells in column 3:

      JCCellStyle borderside = new JCCellStyle();
      borderside.setCellBorderSides(JCTableEnum.BORDERSIDE_LEFT |
        JCTableEnum.BORDERSIDE_TOP);
      table.setCellStyle(JCTableEnum.ALL, 2, borderside);

    2.6.9 Text and Image Clipping

    When cell and label contents do not fit in their defined area, JClass LiveTable can clip the display of the cell value. The ClipHints property determines which method is used. The setClipHints() method can take the following values:

    Clip Hints Properties

     

    JCTableEnum.SHOW_HORIZTONAL

    JCTableEnum.SHOW_VERTICAL

    JCTableEnum.SHOW_NONE

    JCTableEnum.SHOW_ALL (default)

    2.6.10 Displaying Images in Table Cells

    JClass LiveTable can display an image in each cell or label in the table. The image appears inside the margin of the cell. Images are displayed using the JCImageCellRenderer class in the com.klg.jclass.cell package. For more information, please see Displaying and Editing Cells, in Chapter 4.

    JClass LiveTable supports the image file formats supported by the Java AWT: GIF and JPEG. For more information on available file formats, see your Java documentation.

    The position of the image within the cell is specified in the same way as Strings, using HorizontalAlignment and VerticalAlignment. This aspect of displaying images is handled by the Styles property. This is covered in Section 2.6.5, Text and Image Alignment.


    2.7 Cell and Label Spanning

    Spanning is a way to join a range of cells or labels together and treat them as a single cell/label. A spanned range looks and acts like one cell/label that covers several rows and/or columns. There are many potential uses for spanning, including designing complex forms, displaying large images or components, and creating multiline headers.

    When you create a spanned range, the top-left cell in the range is extended over the entire range. The top-left cell is the source cell, and its value and attributes apply over the entire span, overriding any values or attributes set for the other cells/labels in the range. Spanned ranges must begin at the top-left corner of the range. A span cannot contain both cells and labels, or frozen and non-frozen elements. There must also be more than one cell/label in a spanned range. When a single-cell range is specified, it is removed from the list.

    The next figure shows an example of a table containing spanned ranges.

    Figure 9 :  Table design using spanned cells.

    JClass LiveTable handles spanning cells with the SpanHandler class. This class contains the setSpannedRanges() method, which sets a Collection of ranges of cells or labels. (Please note that a Collection is typically a vector.) Each element of the Vector is an instance of a JCCellRange.

    A spanned range is a range of cells or labels that appear joined and can be treated as one cell. The top-left cell (specified by the start_row and start_column members) is the source cell for the spanned range. The cell/label value and attributes of the source cell are displayed in the spanned cell. Attributes for the spanned range must be set on the source cell.

    Note: Spanned ranges may not overlap. If you have overlapping Spans, you will get a System.err message similar to the following:

      spanlist.overlap: Range R1C2:R1C4 overlaps R1C1:R1C2

    Overlaps are determined by the order of cell ranges in the Span Vector.

    To remove all of the spanned ranges, use the clearSpannedRanges() method.

    The following example defines a cell that spans three columns and two rows (columns 2 through 4, and rows 2 through 3):

      JCCellRange spanrange = new JCCellRange(1,1,2,3);
      table.addSpannedRange(spanrange);

    Figure 10 :  Color properties of source cell (1,1) in the original table (left) are retained over the spanned cells in the table after the listed code has been added (right).

    2.7.1 Using Spanning to Create Multiline Headers

    You may want to create tables that contain multiline column headers where a top header is divided into two columns by sub-headers, as in the following illustration.

    Figure 11 :  Multiline headers.

    While JClass LiveTable does not support multi-row column labels, this effect can be achieved by setting some table-wide cell appearance and behavior properties, and some Cell Style properties. Use a frozen row at the top of the table to mimic the appearance of the column labels as follows:

    1Rows/columns that are only partially visible are also included in the value of these properties.

    2All of the characters in a fixed-width font have the same width

    3When width are height are set to zero, the row/column becomes hidden.


    PreviousNextIndex