I l@ve RuBoard |
![]() ![]() |
15.6 Editing CellsIn 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 InterfaceThis 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:
15.6.1.1 EventsThe 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.
15.6.1.2 Methods
15.6.2 The TableCellEditor InterfaceTo 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:
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 InterfaceThe 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.
15.6.4 The DefaultCellEditor ClassSwing 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 PropertiesThe 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.
15.6.4.2 EventsAs 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:
15.6.4.3 ConstructorsYou 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.
15.6.4.4 Tree and table editor methodsMost 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.
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![]() 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; } } } |
I l@ve RuBoard |
![]() ![]() |