Frage

I am trying to use JTable as property editor. I would like to use different types of JComponents in within a single column.

So far I could get checkbox to be shown whenever property has a boolean value. However, I am not able to get that checkbox clickable and the set the value accordingly. It justs shows in the cell but when I click on it, it's value turn to string.

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;

public class Main extends JFrame {

    public static void main(String[] args) {
        Main main = new Main();
    }

    public Main() {
        this.setBounds(55, 5, 400, 400);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        init();

        this.setVisible(true);
        this.validate();

    }

    private void init() {
        JTable table = new JTable() {
            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if (column == 1) {
                    if (row == 1) {
                        Class cellClass = getValueAt(row, column).getClass();
                        return getDefaultRenderer(Boolean.class);
                    }
                }
                return super.getCellRenderer(row, column);
            }

        };
        table.setModel(new PropertyModel(new Property(true, 1234)));

        getContentPane().add(table);
    }

    public class Property {
        private Integer height;
        private boolean visible;

        public Property(boolean visible, Integer height) {
            super();
            this.visible = visible;
            this.height = height;
        }

        public Integer getHeight() {
            return height;
        }

        public boolean isVisible() {
            return visible;
        }

        public void setHeight(Integer height) {
            this.height = height;
        }

        public void setVisible(boolean visible) {
            this.visible = visible;
        }

        @Override
        public String toString() {
            return "Property [visible=" + visible + ", height=" + height + "]";
        }
    }

    public class PropertyModel extends AbstractTableModel {
        private String HEIGHT = "Height";
        private String VISIBLE = "Visible";

        private Property property;

        private String[] columnNames = { "Name", "Value" };
        private Object[][] data = { { HEIGHT, "", },
                { VISIBLE, new Boolean(false) } };

        public PropertyModel(Property property) {
            super();
            this.property = property;

            initializeData();

            this.addTableModelListener(new CustomPropertyTable());
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        public String getColumnName(int c) {
            return columnNames[c];
        }

        @Override
        public int getRowCount() {
            return data.length;
        }

        @Override
        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        /*
         * Initializes the data as per the world object values.
         */
        private void initializeData() {
            data[0][1] = property.getHeight();
            data[1][2] = property.isVisible();
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            if (col == 0) {
                return false;
            } else {
                return true;
            }
        }

        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }

        public class CustomPropertyTable implements TableModelListener {

            @Override
            public void tableChanged(TableModelEvent e) {
                int row = e.getFirstRow();
                int column = e.getColumn();
                TableModel model = (TableModel) e.getSource();
                String columnName = model.getColumnName(column);
                String propertyName = (String) model
                        .getValueAt(row, column - 1);

                if (propertyName.equals(HEIGHT)) {
                    String propertyValue = (String) model.getValueAt(row,
                            column);
                    property.setHeight(Integer.valueOf(propertyValue));

                } else if (propertyName.equals(VISIBLE)) {
                    String propertyValue = (String) model.getValueAt(row,
                            column);
                    Boolean visible = Boolean.valueOf(propertyValue);
                    property.setVisible(visible);
                }

                System.out.println(property);
            }
        }
    }

}

Screenshots: 1) When it starts

When it starts, it looks something like this

2) When I click or try to uncheck it

When I click or try to uncheck it, it becomes string

What could I be doing wrong?

War es hilfreich?

Lösung

You can provide an editor in the same fashion you already do the renderer. Extend getCellEditor. For example based on the posted code:

@Override
public TableCellEditor getCellEditor(int row, int column) {
    if (column == 1) {
        Object value = getValueAt(row, column);
        if (value != null)
            return getDefaultEditor(value.getClass());
    }
    return super.getCellEditor(row, column);
}          
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top