How to use custom JTable cell editor and cell renderer

Harsha picture Harsha · Aug 8, 2012 · Viewed 54.5k times · Source

I have created a JTable with a custom table render and custom cell editor which gives the result in the image

enter image description here

I created the panel shown in the first table cells using a separate class which extended JPanel. and add table values as,

        tbl.setCellEditor(new customCell());
        tbl.getColumnModel().getColumn(0).setCellRenderer(new customCell());

        DefaultTableModel dtm = (DefaultTableModel) tbl.getModel();

        Vector v = new Vector();
        v.add(new Panel());
        v.add("Test");
        dtm.addRow(v);

        v.clear();
        v.add(new Panel());
        v.add("Test 2");
        dtm.addRow(v);

And this is my table custom class to create this table,

class customCell extends DefaultTableModel implements TableCellRenderer, TableCellEditor {

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Panel p = new Panel();            
            table.setRowHeight(row, p.getHeight());
            return p;
        }

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

            return new Panel();
        }

        public Object getCellEditorValue() {
            return "";
        }

        public boolean isCellEditable(EventObject anEvent) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return true;
        }

        public boolean stopCellEditing() {
            return true;
        }

        public void cancelCellEditing() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void addCellEditorListener(CellEditorListener l) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        public void removeCellEditorListener(CellEditorListener l) {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

My problem is thought the panel is shown as I expected I can't type into the text field or change check box or click the button. please tell me how to solve this.

Answer

Robin picture Robin · Aug 8, 2012

I would strongly suggest to reuse the functionality made available in the default table renderers and editors, as there are many things wrong with your code

  1. Please split your editor, renderer and table model. Having them all in the same class is just weird
  2. For your renderer, do not create new instances of a Component each time. Instead, reuse the same component and just modify that Component in the getTableCellRendererComponent method
  3. Same goes for the editor Component
  4. Extend a default editor instead of implementing the methods with UnsupportedOperationExceptions or by just returning empty Strings

To back-up my forth point, a little quote from the Editors part in the JTable tutorial:

What if you want to specify an editor other than a text field, check box, or combo box? As DefaultCellEditor does not support other types of components, you must do a little more work. You need to create a class that implements the TableCellEditor interface. The AbstractCellEditor class is a good superclass to use. It implements TableCellEditor's superinterface, CellEditor, saving you the trouble of implementing the event firing code necessary for cell editors.

Your cell editor class needs to define at least two methods — getCellEditorValue and getTableCellEditorComponent. The getCellEditorValue method, required by CellEditor, returns the cell's current value. The getTableCellEditorComponent method, required by TableCellEditor, should configure and return the component that you want to use as the editor.

As clearly explained there you must implement the event firing code:

saving you the trouble of implementing the event firing code necessary for cell editors.

which you clearly neglected. Therefore my advise to start from AbstractCellEditor instead of implementing the interface from scratch