Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Search this book:
 
Search the site:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


The user gesture to begin editing a cell is look-and-feel specific. It also depends on the editor. For example, an editor built on a JTextField requires a double-click to commence editing, while the editor built on the JCheckBox for Boolean data requires only a single click to edit the cell. This type of inconsistency is annoying to the user and gives editing the table a bad feel. The editCellAt method is used to start a cell editing if the cell allows editing.

The default cell editor for Number and Object instances doesn’t have a way to cancel editing. Editing is stopped by pressing the Enter key or selecting a different cell in the table. However, if the cell had been edited, the change is set in the data model. It is desirable to give the user a way to cancel editing without changing the data model. The following cell editor provides this functionality. When the escape key is pressed, editing is canceled without changing the data model. The editor is then registered as the editor for the Number class. A similar editor that contains left-aligned text should be registered for the Object class if your tables contain any columns that use the Object editor. If this editor is going to be used in multiple tables, it should be encapsulated in its own class that can be used as the editor for each table.

JTextField textField = new JTextField();
final DefaultCellEditor cancelCellEditor =
                          new DefaultCellEditor( textField );
textField.setHorizontalAlignment( SwingConstants.RIGHT );
textField.addKeyListener( new KeyAdapter() {
    public void keyReleased( KeyEvent event ) {
        if( event.getKeyCode() == KeyEvent.VK_ESCAPE )
            cancelCellEditor.cancelCellEditing();
        }
    } );
table.setDefaultEditor( Number.class, cancelCellEditor );

The renderer for the column’s header can be specified also. A common need for this is for multiline headers. The MutliLineHeaderRenderer class shown in Listing 12.9 implements a multiline column header renderer. This class extends the JTextArea class to provide a multiline textual display region. In the getTableCellRendererComponent method, the color and border are set to those defined in the current JTableHeader contained in the table. The proper border is obtained from the UIManager. This ensures that the multiline header will look the same as default renderers used on other tables. A complete description of obtaining component properties from the UIManager is presented in Part V, “Extending JFC Components,” and in Chapter 30, “Pluggable Look-and-Feel.”

The problem with the current implementation of the MultiLineHeaderRenderer class is that it doesn’t dynamically obtain multiline data from the header or data model. The current table package is designed for single-line headers. Using multiple line headers requires overriding methods in one of the standard classes or using “known” models. For example, a custom data model can return String instances with embedded line-feed characters from its getColumnName method. However, if this is done, the header will not display properly using the default column header renderer.

A single instance of the MultiLineHeaderRenderer can be shared among all TableColumn instances in the TableColumnModel. The code fragment to query the columns from the table and set the renderer is shown next. If columns can be dynamically added to the table, a TableColumnModelListener would need to be added to the TableColumnModel to set the renderer for new columns. The table using the MultiLineHeaderRenderer is shown in Figure 12.9.

Listing 12.9 The MultiLineHeaderRenderer Class, and Adding It to a Table

//
// Create a multiline renderer, and set it for each column in
// the table.
//
MultiLineHeaderRenderer headerRenderer = new MultiLineHeaderRenderer();
TableColumnModel columnModel = table.getColumnModel();
for( Enumeration e = columnModel.getColumns(); e.hasMoreElements(); ) {
    TableColumn column = ( TableColumn )e.nextElement();
    column.setHeaderRenderer( headerRenderer );
}

/**
 * An example of a multiline table header.
 * To be used effectively, known header value types
 * would need to be specified in an interface that
 * could be tested for here. This would allow useful
 * data to be queried for the additional rows in the header.
 * This could be done by a specialized table model that
 * returns column headers with breaks in the returned
 * String from the getColumnName method that could be
 * interpreted here.
 **/
class MultiLineHeaderRenderer extends JTextArea
    implements TableCellRenderer, Serializable {

    /**
     * MultiLineHeaderRenderer, default Constructor.
     * Set the number of rows to two. For a production
     * header renderer, the number of rows would probably
     * be determined dynamically depending on the header value.
     **/
    public MultiLineHeaderRenderer() {
        super( 2, 20 );
        setOpaque( true );
    }

    /**
     * Configure in the standard table header colors and border.
     * The multiline string is a bit contrived here. Would need
     * to get a real multiline header from the table model, or
     * values of known types, i.e. interfaces.
     **/
    public Component getTableCellRendererComponent(JTable table,
                         Object value, boolean isSelected,
                         boolean hasFocus, int row, int column) {

        if (table != null) {
            JTableHeader header = table.getTableHeader();
            if (header != null) {
                setForeground(header.getForeground());
                setBackground(header.getBackground());
                setFont(header.getFont());
            }
        }

        setText( (value == null) ? “Column ” + column :
                “Column ” + column + “\n” + value.toString() );
        setBorder( UIManager.getBorder(“TableHeader.cellBorder”) );
        return this;
    }
}


Figure 12.9  Multiline table headers.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.