15.6 Editing Cells


In addition to custom renderers, you can also create custom editors for your table cells. (Actually, the basic stuff in this section also applies to the JTree class.) You have several options ranging from straightforward to completely homegrown.

15.6.1 The CellEditor Interface

This interface governs the basic functionality required of an editor. It has methods for retrieving a new value and determining when to start and stop editing. The basic process for editing is:

  • The user clicks the required number of times on the cell (varies from editor to editor).

  • The component (usually JTree or JTable) replaces the cell with its editor.

  • The user types or chooses a new value.

  • The user ends the editing session (e.g., pressing Enter in a text field).

  • The editor fires a change event to interested listeners (usually the tree or table containing the cell), stating that editing is finished.

  • The component reads the new value and replaces the editor with the cell's renderer.

15.6.1.1 Events

The CellEditor interface requires methods for adding and removing cell editor listeners, which are objects interested in finding out whether editing is finished or canceled. The CellEditorListener class is discussed later in the chapter.

public abstract void addCellEditorListener(CellEditorListener l)
public abstract void removeCellEditorListener(CellEditorListener l)
15.6.1.2 Methods
public Object getCellEditorValue( )

Access the only property of a cell editor, which is the cell's current value. After successful editing, a table or tree calls this method to retrieve the new value for the cell.

public abstract boolean isCellEditable(EventObject anEvent)

Should return true if anEvent is a valid trigger for starting this kind of editor. For example, if you want the user to double-click on a field to invoke the editor, this method would test whether anEvent is a double-click mouse event. If it was only a single-click, you could return false. If it was a double-click, you could return true.

public abstract boolean shouldSelectCell(EventObject anEvent)

This method should return true if the cell to be edited should also be selected. While you usually want to select the cell, there are some situations in which not selecting the cell is preferable. For example, you might be implementing a table that lets the user edit cells that are part of an ongoing selection. Since you want the selection to remain in place, you would implement this method to return false. The cell can still be edited.

public abstract boolean stopCellEditing( )
public abstract void cancelCellEditing( )

You should use these methods to tell the editor to stop editing the cell. The stopCellEditing( ) method indicates that editing is over and that the new value supplied should replace the old value of the cell. The cancelCellEditing( ) method indicates that editing is over and that the new value the user entered (if any) should be ignored. The stopCellEditing( ) method can return a false value if the editor is unable to stop editing. (This might occur if your editor validates input and currently contains an invalid entry.) As an example, you can use these to programmatically stop or cancel editing before starting to edit another cell or upon losing focus.

15.6.2 The TableCellEditor Interface

To begin any custom cell editor devoted to tables, we need to start with the TableCellEditor interface. This interface defines one method that returns our editor:

public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column)

Return a component capable of editing a value. This method should initialize the editor (to reflect the value and isSelected arguments) and may also affect the table. You could dull the color of the rest of the row or table while editing one cell, for example.

The DefaultCellEditor class (discussed below) provides a good implementation of this interface. Unless you're doing something exotic, you should be able to base your cell editors on the DefaultCellEditor class. (In Chapter 16, we do have a slightly exotic example that uses a JSlider and a pop-up window to create an editor in .)

15.6.3 The CellEditorListener Interface

The CellEditorListener interface defines how an object can listen for events generated by a cell editor. Cell editors generate a ChangeEvent when editing is canceled or stopped (a better term might be "finished"). Typically, the object "hosting" the editor (for example, a JTree allowing the user to enter a new filename) would register as a listener. When the event occurs, the JTree reads the cell's new value from the editor, tears down the editor, and repaints the cell with its new value.

public void editingStopped(ChangeEvent e)

Indicate that successful editing has been completed. You can get the new value of the cell from the editor component, which is contained in the source property of the change event.

public void editingCanceled(ChangeEvent e)

Indicate editing has been canceled. You should ignore any partially edited value that might be present in the editor.

15.6.4 The DefaultCellEditor Class

Swing provides a default editor with a fair amount of flexibility. The DefaultCellEditor class implements the CellEditor interface and provides constructors that let you use a text field, checkbox, or combo box for entering the new value.

15.6.4.1 Properties

The DefaultCellEditor class contains the properties listed in Table 15-16. The cellEditorValue property contains the value of the cell editor. This value can be used or ignored when editing stops, depending on whether editing is stopped or canceled. The clickCountToStart property determines how many clicks it takes to begin editing a cell. For checkboxes and combo boxes, this value is 1; for text fields, the default value of this property is 2, meaning that the user has to double-click to start editing. The component property contains the actual component that the cell editor returns when getTableCellEditorComponent( ) or getTreeCellEditorComponent( ) is called.

Table 15-16. DefaultCellEditor properties

Property

Data type

get

is

set

Default value

cellEditorValueo

Object

·

   

null

clickCountToStart

int

·

 

·

Determined by constructor

component

Component

·

   

Determined by constructor

ooverridden

15.6.4.2 Events

As dictated by the CellEditor interface, the DefaultCellEditor class implements the add and remove methods for cell editor listeners. It also provides these convenience methods for generating those events:

protected void fireEditingStopped( )
protected void fireEditingCanceled( )

Both of these methods notify registered listeners that editing has stopped. The cell editor is listed as the source of these events.

15.6.4.3 Constructors

You can create your own cell editor using any of the following constructors. You can also preconfigure any of the components you pass in. For example, you might pass in a right-justified text field or a checkbox with custom icons.

public DefaultCellEditor(JTextField x)
public DefaultCellEditor(JCheckBox x)
public DefaultCellEditor(JComboBox x)

These constructors create editors with the most common components: a JCheckBox for boolean values, a JComboBox for a list of well-defined choices, and a JTextField for any value that can be represented as a String.

15.6.4.4 Tree and table editor methods

Most of the methods in DefaultCellEditor are implementations of the CellEditor methods. The only other methods in the DefaultCellEditor class that are new are the methods required to implement the TableCellEditor and TreeCellEditor interfaces.

public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row)

Return a valid tree cell editor (discussed in more detail in Chapter 17).

public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)

Return a valid table cell editor (discussed earlier).

Figure 15-10 shows an example of a JTable outfitted with a DefaultCellEditor made out of a combo box.

Figure 15-10. A JTable with a pop-up cell editor built from the DefaultCellEditor class
figs/swng2.1510.gif

The data in the table is entirely contrived, but look at how simple it was to set up the combo box editor. In our data model we say that one column has a particular type (a simple inner class called ColorName in our case). Then we register a new DefaultCellEditor as the default editor for that type. Here's the complete source code:

// ColorTable.java //  import javax.swing.table.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ColorTable extends JFrame {   ColorName colors[] = {     new ColorName("Red"), new ColorName("Green"), new ColorName("Blue"),     new ColorName("Black"), new ColorName("White")   };   public ColorTable( ) {     super("Table With DefaultCellEditor Example");     setSize(500,300);     setDefaultCloseOperation(EXIT_ON_CLOSE);     JTable table = new JTable(new AbstractTableModel( ) {         ColorName data[] = {           colors[0], colors[1], colors[2], colors[3], colors[4],           colors[0], colors[1], colors[2], colors[3], colors[4]         };         public int getColumnCount( ) { return 3; }         public int getRowCount( ) { return 10;  }         public Object getValueAt(int r, int c) {           switch (c) {           case 0:  return (r + 1) + ".";           case 1:  return "Some pithy quote #" + r;           case 2:  return data[r];           }           return "Bad Column";         }         public Class getColumnClass(int c) {           if (c == 2) return ColorName.class;           return String.class;         }         // Make Column 2 editable.         public boolean isCellEditable(int r, int c) {           return c == 2;         }         public void setValueAt(Object value, int r, int c) {           data[r] = (ColorName)value;         }       });     table.setDefaultEditor(ColorName.class,                            new DefaultCellEditor(new JComboBox(colors)));     table.setDefaultRenderer(ColorName.class, new DefaultTableCellRenderer( ));     table.setRowHeight(20);     getContentPane( ).add(new JScrollPane(table));   }   public static void main(String args[]) {     ColorTable ex = new ColorTable( );     ex.setVisible(true);   }   public class ColorName {     String cname;     public ColorName(String name) { cname = name; }     public String toString( ) { return cname; }   } }  


Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net