![]() ![]() ![]() |
4
Creating Tables
Overview
Using JCPageTable
Table Structure
Creating a Table
Adding Data to Tables
Customizing Tables
Customizing Cells
Table Wrapping
Converting Tables
Tables in JClass PageLayout are implemented using the
JCPageTable
class. Tables contain column objects and row objects; the row objects contain the cells of the table. Table content is stored either inJCFrame
objects belonging to individual cells or as objects in the entries of aTableDataModel
associated with the table. Tables are printed by the flow, which breaks the table into rectangular ranges which are fit into flow frames.
4.1 Overview
The
JCPageTable
class provides methods and attributes for printing tables from your Java application. This chapter shows you how to:
- add a table to your document
- flow data into the table
- add a header row to the table
- add borders and background colors
- customize cell vertical alignment, margins, and borders
- span cells
- wrap tables
- convert table data from other Java sources
4.2 Table Structure
A table is created with a given number of columns, and a column object is created for each. The number of rows in a table is not fixed, and row objects are added to the table either explicitly, by using a method such as
JCPageTable.addRow()
, or implicitly, through reference to cell objects beyond the current last row of the table. The table'srowList
attribute stores all the rows created within the table.Cells of the table are stored in lists associated with particular rows. A row object with no cells containing content will have a cell list with no entries. As cells are created, the cell object will be stored at the correct position in the row's
cellList
. As with the table'srowList
, blank (null) entries are created for non-existent cells. The content of a cell can be stored in aJCFrame
object allocated by the cell; as a standardJCFrame
, it can contain any content that is valid for aJCFrame
object, up to and including anotherJCPageTable
.In addition to ordered lists of row and column objects, the table object can also (conditionally) own another
JCPageTable
object. The secondaryJCPageTable
object defines the headers of the parent table, but a headerJCPageTable
cannot own a header table. The structure of a headerJCPageTable
is identical to the structure of a main table, except that the column layout of the header table is defined implicitly by reference to the parent table.There are also dummy cell objects attached to the table, and to each row and column object. These cell objects store column-, row-, and table-wide default cell attributes.
4.3 Using JCPageTable
Here is an overview of the general steps required to use
JCPageTable
.
- Create a
JCPageTable
object and pass in:- Create table header by calling
createHeaders()
, if desired.- Customize cells by setting borders and margins on table, rows, columns, or individual cells and by setting up any cell spans that are required.
- Size table to frame using
fitToFrame()
, if desired.- Add data to tables (for example, call
JCPageTable.printToCell()
orJCPageTable.addRow()
).- Print the table by calling
flow.print(table)
, whereflow
is an instance ofJCFlow
.
4.4 Creating a Table
By the end of this chapter, we will produce the following table:
Figure 3 : A Table example in JClass PageLayout.
To begin, we define a table with three columns, each of which is one inch wide. Here is the relevant code.
JCPageTable table = new JCPageTable(document, 3,
new JCUnit.Measure(JCUnit.INCHES, 1.0));The
JCPageTable
parameters indicate theJCDocument
to which this table belongs and that this table should contain three columns, each one inch wide.
4.5 Adding Data to Tables
To print data into cells, use the
table.printToCell(2, 1, style, "Calico");JCPageTable.printToCell()
method. It prints text to the cells you specify, generating them if necessary. For instance, the following code prints the text "Calico", using the currentJCTextStyle
(thestyle
in the code sample below), to the cell found in row2
, column1
.Note: Cell indices start at (0, 0), independent of the presence of a header row.
4.5.1 Creating Body Rows
When you print to a cell frame that does not yet exist, you create a row of cells that correspond to the number of columns in the table. The following example populates the first three body rows of the table shown in Figure 3.
table.printToCell(0, 0, style, "Labrador");
table.printToCell(0, 1, style, "Persian");
table.printToCell(0, 2, style, "Shetland");
table.printToCell(1, 0, style, "Collie");
table.printToCell(1, 1, style, "Siamese");
table.printToCell(1, 2, style, "Arabian");
table.printToCell(2, 0, style, "Terrier");
table.printToCell(2, 1, style, "Calico");
table.printToCell(2, 2, style, "Clydesdale");To actually print the table, call
flow.print(table);where
flow
is an instance ofJCFlow
.Note that JClass PageLayout identifies each cell by numbering cells in a
row, column
format, starting from zero (0
).Note that if a row cannot fit in the current page, then that row will be placed on the following page. However, if the height of that row is larger than the height of the entire page (for example, in the case that the row contains particularly extensive data, such as a long String), then that row is truncated.
The table is beginning to take shape:
Figure 4 : Table with body rows.
4.5.2 Adding Body Rows
You can also add rows of cells to the end of a table using
table.addRow(style, newString[]{"Setter", "Tabby", "Palomino"});JCPageTable.addRow()
.The example produces the following results:
Figure 5 : Table with additional body row.
4.5.3 Adding Header Rows
Suppose you wanted to create a table header row. Although a header row may look as though it is part of the table containing the body rows, in actuality it is a separate table unto itself. You build the header table using
JCPageTable header = table.createHeaders();JCPageTable
.createHeaders()
. Once you have created the header table, you can populate its cells, much as you did the body rows.
try {
JCFrame frame = header.getCellFrame(0, 0);
frame.print(style, "Dogs");
frame = header.getCellFrame(0, 1);
frame.print(style, "Cats");
frame = header.getCellFrame(0, 2);
frame.print(style, "Horses");
}
catch (EndOfFrameException e) {}Adding the header row produces the following results:
Figure 6 : Table with header row.
4.6 Customizing Tables
Now that you've laid out your table and printed data into it, you may want to customize its appearance by defining borders and background colors or by defining various line styles and shadings. This section describes how.
4.6.1 Table Styles
The simplest way to customize a table is to choose one of the numerous built-in table styles in
JCTableStyle
. Table styles are constants, such asJCTableStyle.STYLE_DEFAULT
, orJCTableStyle.STYLE_
n, where n ranges from 1 to 17.Table styles are cloneable. You can further customize a table style by cloning the one you wish to use as a base for making changes.
// Create a table style with orange headers and alternating colored
// rows
JCTableStyle tableStyle =
(JCTableStyle)JCTableStyle.STYLE_DEFAULT.clone();
tableStyle.getHeaderStyle().setBackground(Color.orange);
tableStyle.setAlternate( new JCAlternate(Color.lightGray,
Color.white, true));
JCTableStyle Methods
Method
Description
See Alternating row or column colors for details.
Sets the border between the header and the first row of the table.
Sets a
JCTableStyle
instance to be used as a table style for the header table.Sets the default text style to be used when drawing text in table cells.
Alternating row or column colors
It is often desirable to shade every other row or column differently for easier reading. The
JCAlternate
class is used for this purpose, and thesetAlternate()
method inJCTableStyle
takes an instance ofJCAlternate
to specify the alternating colors. There are two default styles, one for columns and one for rows.To show rows alternating between gray and light gray, use
tableStyle.setAlternate(new JCAlternate(Color.red, Color.blue, true));JCAlternate.ROW
. To show columns alternating between gray and light gray, useJCAlternate.COLUMN
. To choose your own colors, create an instance ofJCAlternate
and pass its constructor the two colors you want, and a Boolean flag specifying whether the alternation is to take place over rows or over columns. If the flag is set totrue
, rows alternate in color, if the flag is set tofalse
, columns alternate in color. For example, the following causes rows to alternate between red and blue:Row/Column Dominance
To control the order of border and cell color drawing, use the
RowColumnDominance
property of the table. A value ofROW_DOMINANCE
forces column background colors and borders to draw before the equivalent properties of the table's row. In contrast, a value ofCOLUMN_DOMINANCE
forces row background colors and border to draw before the equivalent properties of the table's columns. This property is set on the table class (JCPageTable
orJCFlowTable
) with thesetRowColumnDominance()
method.
4.6.2 Adding Borders
To define the appearance of a table border, you must select or create a
table.setAllBorders(JCDrawStyle.LINE);JCDrawStyle
with the required attributes and apply the style to the border. For information on controlling the appearance of borders, refer to Creating Draw Styles, in Chapter 6.
table.setLeftBorder(JCDrawStyle.LINE_2POINT);
table.setRightBorder(JCDrawStyle.LINE_2POINT);This example uses
setAllBorders()
to apply the default single line style to all borders in the table, and then uses setLeftBorder and setRightBorder to apply thick side borders. If we were to apply this style to the table we developed earlier, the result would be as follows:
Figure 7 : Table with borders.
JCDrawStyle
makes the following line styles available for table borders:
JCPageTable
provides numerous methods for applying line styles to table borders:The behavior of perimeter borders at page breaks is determined by the
BorderMode
property of the table. A value ofBORDER_USE_EXTERNAL
forces perimeter borders to be used on each section of the multi-page table. A value ofBORDER_USE_INTERNAL
forces perimeter borders to be used only at the beginning and end of the table. Internal cell borders will be used for the table sections broken across pages. For example:
Figure 8 : External and internal border behavior.
4.6.3 Adding Header Borders
As mentioned in Section 4.5.3, Adding Header Rows, the header row is a separate table unto itself. Modifying header borders is just like modifying borders in the main table. For example, to apply a double line to the top and bottom of the header row, enter:
table.setTopBorder(JCDrawStyle.LINE_DOUBLE);
table.setHeaderBorder(JCDrawStyle.LINE_DOUBLE);
Figure 9 : Table with double header borders.
4.6.4 Applying Background Colors
You can further customize tables by applying background colors to cells, rows, columns, or the entire table. Colors and greyscale are defined by
java.awt.Color
. For more information on the colors and greys available to you, refer to the Java 1.3 API Specification at http://java.sun.com/j2se/1.3/docs/api/index.html.For example, suppose you wanted to apply a green background to all of the cells in the first column of the table.
table.getColumn(0).setBackgroundColor(Color.green);This example uses the
getColumn()
method to identify the column to be colored, and then uses thesetBackgroundColor()
method to apply the specified static color.
4.6.5 Adjusting the Size of a Table
If you wish to adjust the size of a table so that it occupies all the space available in its parent frame, use the
fitToFrame()
method. The method takes two parameters: the frame to which the table should fit itself and the currentJCTextStyle
. It should only be called after all table borders, cell borders, and margins have been finalized.
4.7 Customizing Cells
JCPageTable
has three inner classes:JCPageTable.Cell
,JCPageTable.Column
, andJCPageTable.Row
, written to allow for more precise control over the description of individual table components.
JCPageTable.Column
andJCPageTable.Row
provide methods that allow you to customize the cells in an entire column or row by modifying their alignment, background color, borders, and margins.
JCPageTable.Cell
provides attributes and methods that allow you to customize cell appearance, including settings for vertical alignment, borders, margins, and spans.
4.7.1 Setting the Vertical Alignment
You can use the
JCPageTable.Cell.setCellAlignment()
method to adjust the vertical alignment of text in a cell.Adding the words "Retriever" and "Scottish" to cells
0,0
and2,0
increases the height of all of the cells in rows0
and2
. By default, the other cells in the same row align their text to the top of the cell.
Figure 10 : Table cells with vertical alignment set to Top.
Suppose, for example, you want to vertically align that text to the middle of the cell. Here is the relevant code and how the altered table will appear:
table.setDefaultCellAlignment(JCPageTable.CELL_ALIGNMENT_CENTER);
Figure 11 : Table cells with vertical alignment set to Center.
You may also control the alignment in cells individually. The first three code snippets show how to align a cell to the bottom, top, and center of a cell, respectively. The last code snippet shows how to revert to the last alignment specified.
cell = table.getCell(0,1);
cell.setCellAlignment(JCPageTable.CELL_ALIGNMENT_BOTTOM);
cell = table.getCell(0,2);
cell.setCellAlignment(JCPageTable.CELL_ALIGNMENT_TOP);
cell = table.getCell(2,2);
cell.setCellAlignment(JCPageTable.CELL_ALIGNMENT_CENTER);
cell = table.getCell(2,1);
cell.setCellAlignment(JCPageTable.CELL_ALIGNMENT_NONE );
JCPageTable.getCell()
identifies the cells containing text we want to vertically re-align.JCPageTable.Cell.setCellAlignment()
adjusts their vertical alignment in the cell, in this case, to the center of the cell. Our adjustments produce the following results:
Figure 12 : Table cells with vertical alignment set to Center.
JCPageTable
provides the following cell vertical alignment options:
4.7.2 Defining Cell Margins
To control the space between the cell border and the text it contains, you adjust the cell margins. An enlarged version of one of the cells in the sample table provides a good example.
Figure 13 : Enlarged table cell.
The program has left gaps between the text and the left, right, top, and bottom borders of the cell. You can adjust the size of these gaps using
cell = table.getCell(1,1);JCPageTable.Cell
methods.
cell.setBottomMargin(new JCUnit.Measure(JCUnit.POINTS, 8));
cell.setTopMargin(new JCUnit.Measure(JCUnit.POINTS, 8));
cell.setLeftMargin(new JCUnit.Measure(JCUnit.POINTS, 2));
cell.setRightMargin(new JCUnit.Measure(JCUnit.POINTS, 2));The preceding example identifies the cell (
1,1
- remember that the header row is numbered separately) for which margins are to be adjusted, and then calls the appropriateJCPageTable.Cell
methods to set the top and bottom margins to 8 points and the left and right margins to 2 points.
Figure 14 : Enlarged table cell with margins illustrated.
4.7.3 Customizing Cell Borders
You can customize individual cells by overriding the border style specified by the
JCDrawStyle cellstyle = (JCDrawStyle)JCDrawStyle
and applied by the appropriateJCPageTable
method. To override the style for a particular cell's borders, identify the cell, create a newJCDrawStyle,
and apply it using a method from theJCPageTable.Cell
class.
JCDrawStyle.stringToStyle("default line").clone();
cellstyle.setLineType(JCDrawStyle.LINE_TYPE_DOUBLE);
cellstyle.setLineWidth(new JCUnit.Measure(JCUnit.POINTS, 1));
JCPageTable.Cell cell = table.getCell(1, 1);
cell.setBottomBorderStyle(cellstyle);
cell.setRightBorderStyle(cellstyle);Note that style changes can also be made in one line as follows:
table.getCell(0, 1).setBottomBorderStyle(cellstyle);
table.getCell(1, 0).setRightBorderStyle(cellstyle);After applying the above style changes to our table, this is the result:
Figure 15 : Table cell with customized borders.
In order to prevent cells from overriding each other's border styles, you can only specify the appearance of a cell's right and bottom borders. To achieve the results shown in the example, the program applies the
JCDrawStyle
to the right and bottom borders of the cell in question (Siamese), then applies the style to the bottom border of the cell immediately above it (Persian), and to the right border of the cell to its left (Collie).
4.7.4 Spanning Cells
Spanning cells is the process by which the borders between specified cells are eliminated, creating one merged cell. The merged cell can cross multiple row and column borders, but does not alter the structure of the remaining cells, rows or columns in the table. Note that you should span cells before populating the cells.
To span cells, you pass to the
table.spanCells(startRow, startColumn, numRows, numColumns);JCPageTable.spanCells()
method the row and column number of the cell that is the upper left-hand corner of the span, along with the number of rows to span down and the number of columns to span to the right. Follow this format:For example, to span four cells down the first column of a table, beginning with the upper left-hand corner cell in the table, enter:
table.spanCells(0, 0, 4, 1);
Figure 16 : Table with spanned cells.
4.8 Table Wrapping
If a table is too long for the current frame, the extra rows flow to the next frame, along with the header row, which appears at the top of every frame to which the table rows flow.
If a table is too wide for the current frame, use
JCPageTable.setOverflowMode()
to handle the extra column data.To wrap the extra column(s) so that they appear below the table:
table.setOverflowMode(JCPageTable.OVERFLOW_WRAP_COLUMNS);
Figure 17 : Table with wrapped column.
To wrap the extra column(s) onto the following page:
table.setOverflowMode(JCPageTable.OVERFLOW_WRAP_COLUMNS_NEXT);
Figure 18 : Table with column wrapped to the next page.
To clip an equal amount of data from the left and right-most columns in the table:
table.setOverflowMode(JCPageTable.OVERFLOW_CLIP_COLUMNS);
Figure 19 : Table with clipped columns.
4.9 Converting Tables
You can use JClass PageLayout to convert data from other Java table classes into
JCPageTable
tables. You can extract table data along with simple text formatting from JClass JCTables and Swing JTables. You can also extract the data from a JDBC result set and reconstruct it as aJCPageTable
.
4.9.1 Converting JClass LiveTables
If you installed JClass LiveTable with your JClass DesktopViews installation, you can flow data from a JClass LiveTable
JCTable
into aJCPageTable
in your JClass PageLayout application.Creating a New JCPageTable
To flow
JCTable
data into a new instance of a JCPageTable, useJCPageTableFromJTable.createTable()
. You have the following options:Populating an Existing JCPageTable
To flow
JCTable
data into an existingJCPageTable
, useJCPageTableFromJCTable.populateTable()
. You have the following options:
4.9.2 Converting Swing JTables
You can also convert tables created with
javax.swing.JTable
intoJCPageTable
instances.Creating a New JCPageTable
To create a new
JCPageTable
from an existing SwingJTable
orJTable
TableModel
, use theJCPageTableFromJTable.createTable()
method. You have the following options:Populating an Existing JCPageTable
To flow data and text styles from an existing Swing
JTable
orJTable
TableModel
into an existingJCPageTable
, use theJCPageTableFromJTable.populateTable()
method. You have the following options:Examples
To perform a complete conversion of an existing
JCPageTable pageTable =JTable
to a JClass PageLayoutPageTable
:
JCPageTableFromJTable.create(document, jTable, true);To convert an existing
// create JCPageTable with same number of columns as JTableJTable
to a JClass PageLayoutPageTable
, without preserving text formatting from the existingJTable
so that new formatting can be applied:
JCPageTable pageTable =
JCPageTableFromJTable.create(document, jTable, false);
// apply our own text formatting to headers and body
JCPageTable headerTable = pageTable.getHeaders();
headerTable.getRow(0).setDefaultStyle(JCTextStyle.HEADING5);
pageTable.setDefaultStyle(JCTextStyle.CODE);
// populate JCPageTable with data from JTable
JCPageTableFromJTable.populate(pageTable, jTable, false);
4.9.3 Converting JDBC Databases
JDBC (Java DataBase Connectivity) is the part of the Java API (
java.sql
) that allows you to send SQL queries to a database. You can format the result set of an SQL query into aJCPageTable
.
- Create the
JCPageTable
and theResultSet
. protected JCPageTable createTable(JCDocument doc) {
ResultSet resultSet = null;
JCPageTable table = null;- Load the JDBC driver. try {
Class.forName(driver); // Example: sun.jdbc.odbc.JdbcOdbcDriver
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}- Conduct the SQL query and return the
JCPageTable
. try {
Connection connection = DriverManager.getConnection(url, login, password);
Statement statement = connection.createStatement();
resultSet = statement.executeQuery(query);
table = com.klg.jclass.page.JCPageTableFromJDBC.createTable(doc, resultSet);
// clean up
resultSet.close();
statement.close();
connection.close();
} catch (SQLException sqle) {
JOptionPane.showMessageDialog(null, sqle.toString(), "SQL error", JOptionPane.ERROR_MESSAGE);
return null;
}
// return the JCPageTable
return table;
![]() ![]() ![]() |