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 theJCLightCellRenderer
,JCComponentCellRenderer
, andJCCellEditor
interfaces.Cells are drawn into the cell area by either a
JCLightCellRenderer
object that understands how to draw that specific type of data, or aJCComponentCellRenderer
object that uses a lightweight component such asJLabel
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:
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.
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
andget
methods. Every JClass LiveTable property has aset
andget
method associated with it.For example, to set the value of the
table.setPixelHeight(JCTableEnum.LABEL,60);PixelHeight
property to a value of 60 for all labels and the first non-label row, thesetPixelHeight()
method is called:
table.setPixelHeight(0,60);As another example, to set the value of the
table.setPixelPixelWidth
property to a value of 90 for all labels and the first non-label row, thesetPixelWidth()
method is called:Width
(JCTableEnum.LABEL,90);
table.setPixelWidth
(0,90);You can also set properties for the entire table. For example, use the
table.setMarginHeight(10);MarginHeight()
andMarginWidth()
properties to set the distance between cell borders and cell contents:
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 ofCellStyleModel
. 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 cellcolors = new JCCellStyle();JCCellStyle
, but changes the cell colors to black (background) and yellow (text), and applies this change to cell(2, 2):
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 range = new JCCellRange(0,3,2,4);JCCellRange
:
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:
- Cell selection: when users click a single cell, the entire row is selected.
- Label selection: labels are not included in selections.
- Resizing: the table's cell sizes can only be changed by dragging label borders.
- Traversal: individual cells are traversable.
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(Color.blue);setFocusColor()
method. For example:Using the
FOCUS_NONEsetFocusIndicator()
method lets you set the type of focus indicator used. Valid indicators are:
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 tofalse
, 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 totrue
.
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.
- When set to
JCTableEnum.POSITION_BY_CELLS
(default), the scrollbar is attached to the cell/label viewport (that is, the cells that are visible).- When set to
JCTableEnum.POSITION_BY_SIDE
, the scrollbar is attached to the side of the table (that is, the whole of the table).
HorizSBAttachment
sets how the end of the horizontal scrollbar is attached to the table. When set toJCTableEnum.SIZE_TO_CELLS
(default), the scrollbar ends at the edge of the visible cells. When set toJCTableEnum.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
andVertSBOffset
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()
andsetLeftColumn()
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/orVertSBDisplay
toJCTableEnum.SCROLLBAR_ALWAYS
. Set them toJCTableEnum.SCROLLBAR_NEVER
to completely disable the scrollbar display. To display scrollbars only when the table size is greater than the viewing area, set them toJCTableEnum.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()
andsetHorizSB()
methods. The scrollbar must be aJScrollBar
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()
andsetSelectedForeground()
. 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_SELECTED_BACKGROUND
: the selected background color is the same as the color defined in theSelectedBackground
property.USE_CELL_BACKGROUND
: the selected background is the same as the cell background color.USE_CELL_FOREGROUND
: the background and foreground colors are inverted.Use
setSelectedForegroundMode()
to set how selected foreground colors are determined. Valid modes include:
USE_SELECTED_FOREGROUND
: the selected foreground color is the same as the color defined in theSelectedForeground
property.USE_CELL_FOREGROUND
: the selected background is the same as the cell foreground color.USE_CELL_BACKGROUND
: the background and foreground colors are inverted.
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()
andsetColumnLabelPlacement()
methods. If you insert the placement methods in thetable.setColumnLabelPlacement(placement)
ortable.setRowLabelPlacement(placement)
statements, valid values include: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, theColumnLabelOffset
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(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
sets the bordercell width for all cells and labels to a value of two pixels
sets the bordercell width for all cells and labels to a value of five pixels
2.4.7 Cell and Label Margins
The
MarginWidth
andMarginHeight
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). TheMarginHeight
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:
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 ofCellBorderModel
, 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 theCellBorderModel
value, which is used in the statement:table.setFrameBorder(new JCCellBorder(value))
.
2.4.10 Row and Column Definition
Determining the Number of Rows/Columns
The
NumRows
andNumColumns
properties are set using methods in the data source. To retrieve these values, use theJCVectorDataSource.getNumRows()
andJCVectorDataSource.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
andVisibleColumns
properties.1You can force the table to display a particular number of rows or columns by calling
setVisibleRows()
andsetVisibleColumns()
.To retrieve the values of
VisibleRows
orVisibleColumns
, call thegetVisibleRows()
andgetVisibleColumns()
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()
andgetNumVisibleColumns()
, 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
andVisibleColumns
toJCTableEnum.NOVALUE
. Setting either property toNOVALUE
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
table.swapRows(3,9)swapRows()
andswapColumns()
methods. For example, to swap rows 3 and 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()
orresetSwappedColumns()
methods.`Freezing' Rows and Columns
An application can make rows and columns non-scrollable by using the
FrozenRows
andFrozenColumns
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.
setFrozenRows()
specifies the number of rows held at the top or bottom of the window and not scrolled. The default value is zero.setFrozenColumns()
specifies the number of columns held at the left or right side of the window and not scrolled. The default is zero.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()
orswapColumns()
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()
ormoveColumns()
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 setFrozenRows
orFrozenColumns
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 eitherJCTableEnum.PLACE_TOP
orJCTableEnum
.PLACE_BOTTOM
.To change the placement of all frozen columns, set the
FrozenColumnPlacement
property to eitherJCTableEnum.PLACE_LEFT
orJCTableEnum.PLACE_RIGHT
.
2.4.11 Controlling Cell Editor Size
The table can control the size of a cell editing component using the
EditHeightPolicy
andEditWidthPolicy
properties. Each of these properties can take one of three values:
JCTableEnum.EDIT_SIZE_TO_CELL
: resize the component to fit the Table's cell size.JCTableEnum.EDIT_ENSURE_MINIMUM_SIZE
: resize the component to its minimum size.JCTableEnum.EDIT_ENSURE_PREFERRED_SIZE
: resize the cell to editing component's preferred size.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
andPixelHeight
must be set toJCTableEnum.NOVALUE.
To determine the pixel dimensions of a row or column whose height/width was set by
CharWidth
orCharHeight
, use thegetColumnPixelWidth()
orgetColumnPixelHeight()
methods.The following table demonstrates different character height and width settings:
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
andPixelHeight
specify column width and row height in pixels. You can set these properties to an explicit pixel value usingJCTableEnum.NOVALUE
orJCTableEnum.VARIABLE
(this value is discussed in detail in the following section).Unless set to
JCTableEnum.NOVALUE
(default), these properties override theCharWidth
andCharHeight
properties. The next illustration shows settingPixelHeight
to a pixel value.
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
andPixelHeight
toJCTableEnum.VARIABLE
. As your application changes table attributes affecting the cells' contents, the table will resize the rows and columns to fit.3When 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()
andgetColumnPixelWidth()
methods.Defining How Much of the Table is Used in Pixel Estimates
By default, the
JCTableEnum.VARIABLE
value, when used withPixelHeight
andPixelWidth
, 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 theJCTableEnum.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
andPixelWidth
toJCTableEnum.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
andPixelHeight
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()
andsetMinHeight()
to determine the maximum height of any or all rows, all column labels or the whole table. Likewise, usesetMaxWidth()
andsetMinWidth()
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()
andsetColumnHidden()
totrue
.
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:
- background colors and foreground colors
- repeating background and foreground color settings
- font attributes
- horizontal and vertical text alignment
- cell border types
- cell border sides
- clip hints
- boolean editable
- editor (
JCCellEditor
)- renderer (
JCCellRenderer
)- data types
- cell traversal
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 cs = new JCCellStyle();JCCellStyle
object, modifying the desired properties, and applying these changes with thesetCellStyle()
method. For example, the style for cell (2, 2) is changed by using this code:
cs.setBackground(Color.blue);
table.setCellStyle(2, 2, cs);You can also use the
JCCellStyle cs = new JCCellStyle();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:
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
CellStyleModel csm = table.getCellStyle(0, 0);setCellStyle()
if you want to change all the cells that share the style. In other words, the first example which used:
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 col = table.getCellStyle();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:
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());
- The first choice involves the creation of a copy of the style in which you are interested, changing the property, and applying it back to the cell you want changed:
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);
- The second option makes updates automatic, as you implement
mySimpleStyle
as the "parent" ofmyNewStyle
.
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
myNewStyle.setForeground(Color.yellow);anotherFont
typeface. However, since the foreground color inmyNewStyle
was changed to yellow, setting themyOldStyle
foreground color to white will not affectmyNewStyle
.
myOldStyle.setFont(anotherFont);
myOldStyle.setForeground(Color.white);The
CellStyleModel
hasgetParentStyle()
andsetParentStyle()
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 theJCCellStyle
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:
JCCellStyle
does not specify anyDataType
,CellEditor
, orCellRenderer
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).
CellStyleModel csm = table.getDefaultLabelStlye();DefaultLabelStyle
is automatically applied to labels, whileDefaultCellStyle
is applied to all cells. Access the default styles as follows:
csm = table.getDefaultCellStyle();JClass LiveTable handles PLAF through a "parenting" mechanism. When the PLAF changes,
JCTableUI
updatesDefaultLabelStyle
andDefaultCellStyle
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 propertyHorizontalAlignment
. 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
CellStyleModel csm = table.getDefaultCellStyle();JCTableUI
works with default styles, imagine that you are applying this style change:
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 becauseJCTableUI
assumes the PLAF logic set it. If it is a regular object (in this case,Color
), the value will not be updated byJCTableUI
.
2.6.4 Working with Colors
Setting Foreground and Background Colors
The foreground and background colors used for cells are specified by the
JCCellStyle cell = new JCCellStyle();Foreground
andBackground
properties. The following example sets the background color of column 2 to blue:
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
JCCellRange range = new JCCellRange(0,3,2,4);Foreground
andBackground
properties for a range of cells specified by aJCCellRange
object:
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
JCCellStyle colors = new JCCellStyle();RepeatBackgroundColors
andRepeatBackground
properties as shown in the following example:
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.
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
andVerticalAlignment
properties. Cell/label values can be centered or positioned along any side of the cell/label.
Alignment Property
Examples
2.6.6 Cell and Label Fonts
You can specify the font for the text in a cell or label with the
JCCellStyle labelfont = new JCCellStyle();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:
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 theCellBorderModel
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).
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 aCellBorder
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 calleddrawBackground()
. ThedrawBackground()
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
class LiteBorder implements CellBorderModel {CellBorderModel
interface. The following (from the BorderTypes.java example in examples/table/style) defines a single-line border object calledLiteBorder
:
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 theJCCellBorder
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
JCCellStyle borderside = new JCCellStyle();CellBorderSides
values. The following example establishes cell borders on the left and top sides for all cells in column 3:
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. ThesetClipHints()
method can take the following values:
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 thecom.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
andVerticalAlignment
. This aspect of displaying images is handled by theStyles
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 thesetSpannedRanges()
method, which sets aCollection
of ranges of cells or labels. (Please note that aCollection
is typically a vector.) Each element of theVector
is an instance of aJCCellRange
.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
andstart_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:R1C2Overlaps 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:
- The right-most column label has been set to span columns 3 and 4. This produces a heading for both columns.
- The cell values for columns 3 and 4 in row zero have been set to contain the "subheadings" of the spanned label heading.
- The cells in row zero, columns 0 to 2 are empty.
- Row zero has been frozen using
setFrozenRows(1)
so that it stays at the top of the table and acts like a label.- Row zero's cells are not editable (using the
setEditable(false)
method) and not traversable (usingsetTraversable(false)
).- The
FrameBorderWidth
property of the table must be set to zero, so that the labels blend seamlessly into the frozen row.- Finally, using Cell Styles, the
CellBorderSides
,Background
, andForeground
properties for the column labels and row zero are all set to blend the two together.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.