代码之家  ›  专栏  ›  技术社区  ›  Konrad Garus

JTable-一列中有多个单元格编辑器

  •  11
  • Konrad Garus  · 技术社区  · 14 年前

    我想要我的 JTable 对单个列中的不同单元格使用不同的单元格编辑器。设想一个两列标签值表,如:

    Name          | Value
    --------------+--------------------------------
    Identifier    | ST33442 (string editor)
    Purchase Date | 7/7/10 (custom calendar editor)
    Status        | Broken (combo editor)
    

    如何动态构建编辑器?有点像 TableCellEditorFactory 太完美了。

    2 回复  |  直到 14 年前
        1
  •  8
  •   Guillaume    14 年前

    您必须实现自己的单元编辑器并将其分配给列。您可能应该对单元渲染器执行相同的操作(例如,布尔将作为复选框而不是“true”/“false”进行渲染)。

    public class TableEditorTest {
    
        public static void main(String[] args) {
            Object[][] data = new Object[][] {{"Identifier", "ST33442"}, {"Purchase Date", new Date()}, {"Status", Boolean.FALSE}};
            String[] columnNames = new String[] {"Name", "Value"};
            TableModel model = new DefaultTableModel(data, columnNames);
            JTable table = new JTable(model);
            JScrollPane scrollPane = new JScrollPane(table);
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(scrollPane);
            frame.pack();
            frame.setVisible(true);
    
            table.getColumnModel().getColumn(1).setCellEditor(new CustomTableCellEditor());
        }
    
        public static class CustomTableCellEditor extends AbstractCellEditor implements TableCellEditor {
            private TableCellEditor editor;
    
            @Override
            public Object getCellEditorValue() {
                if (editor != null) {
                    return editor.getCellEditorValue();
                }
    
                return null;
            }
    
            @Override
            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
                if (value instanceof Date) {
                    editor = new DatePickerCellEditor();
                } else if (value instanceof String) {
                    editor = new DefaultCellEditor(new JTextField());
                } else if (value instanceof Boolean) {
                    editor = new DefaultCellEditor(new JCheckBox());
                }
    
                return editor.getTableCellEditorComponent(table, value, isSelected, row, column);
            }
        }
    }
    

    注意。 DatePickerCellEditor

        2
  •  1
  •   Adrien Clerc    13 年前

    我想到了另一个解决方案,因为我想重用默认编辑器,下面的类重新定义getColumnClass以获得不同的答案。据我测试,它运行良好,我可以使用setDefaultEditor等等。您可以注意到,可以增强此行为以仅将其应用于所需的列。

    public class JXMultiTypeColumnTable extends JXTable {
    
    private Map<Integer, Class<?>> viewedClassByColumn = new HashMap<Integer, Class<?>>();
    
    public JXMultiTypeColumnTable(Object[][] rowData, Object[] columnNames) {
        super(rowData, columnNames);
    }
    
    public JXMultiTypeColumnTable(int numRows, int numColumns) {
        super(numRows, numColumns);
    }
    
    public JXMultiTypeColumnTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
        super(dm, cm, sm);
    }
    
    public JXMultiTypeColumnTable(TableModel dm, TableColumnModel cm) {
        super(dm, cm);
    }
    
    public JXMultiTypeColumnTable(TableModel dm) {
        super(dm);
    }
    
    public JXMultiTypeColumnTable() {
    }
    
    @Override
    public Class<?> getColumnClass(int column) {
        Class<?> recordedClass = this.viewedClassByColumn.get(column);
        if (recordedClass != null) {
            return recordedClass;
        }
        return super.getColumnClass(column);
    }
    
    private void recordViewedClass(int row, int column) {
        this.viewedClassByColumn.put(column,
                this.getModel().getValueAt(
                this.convertRowIndexToModel(row), this.convertColumnIndexToModel(column))
                .getClass());
    }
    
    @Override
    public TableCellRenderer getCellRenderer(int row, int column) {
        this.recordViewedClass(row, column);
        return super.getCellRenderer(row, column);
    }
    
    @Override
    public TableCellEditor getCellEditor(int row, int column) {
        this.recordViewedClass(row, column);
        return super.getCellEditor(row, column);
    }
    

    }

    JTable JXTable .