java - JTable 中行选择的受控编辑

标签 java swing jtable

我有一个 JTable 显示来自 SQL 数据库的行。该表相对较小(只有 4 列,最多 1000 行)。

我想让用户有机会编辑表格中的任何单元格,但希望避免对其进行过多限制,以至于他们必须使用编辑对话框(这使得错误检查和验证更加容易,但不太直观)

我尝试了几种不同的方法来使用我的 JTable 的 valueChanged 方法来控制编辑选择,但运气不佳。

我希望编辑每一行并在编辑结束时将其写入数据库。我希望一旦单击一个单元格开始编辑该行,在用户完成该行的编辑之前不能选择其他行(其他行显示为灰色)。编辑每个单元格并按回车键后,编辑选择应跳转到同一行的下一列。

任何人都可以指点我如何实现这一目标吗?

//  Create table with database data
   table = new JTable(new DefaultTableModel(data, columnNames)) {
        public Class getColumnClass(int column) {
            for (int row = 0; row < getRowCount(); row++) {
                Object o = getValueAt(row, column);
                if (o != null){
                    return o.getClass();
                }
            }
            return Object.class;
        }

        @Override
        public boolean isCellEditable(int row, int col){
            return true; 
        }

        @Override
        public boolean editCellAt(int row, int column) {
            boolean ans = super.editCellAt(row, column);
            if (ans) { 
                Component editor = table.getEditorComponent();
                editor.requestFocusInWindow();
            }
            return ans;
        }

        @Override
        public void valueChanged(ListSelectionEvent source) {
            super.valueChanged(source);
            if (table!=null)
                table.changeSelection(getSelectedRow(), getSelectedColumn()+1, false, false);
        }

    };

编辑 - 带有表格指针的自定义单元格编辑器似乎是一个开始

public class ExchangeTableCellEditor  extends AbstractCellEditor implements TableCellEditor {

private JTable table;

JComponent component = new JTextField();

public ExchangeTableCellEditor(JTable table) {
    this.table = table;
}

public boolean stopCellEditing() {
    boolean ans = super.stopCellEditing();
    //now we want to increment the cell count
    table.editCellAt(table.getSelectedRow(), table.getSelectedColumn()+1);
    return ans;
}

@Override
public void cancelCellEditing() {
    //do nothing... must accept cell changes 
}

@Override
public Object getCellEditorValue() {
    return ((JTextField)component).getText();
}

@Override
public Component getTableCellEditorComponent(JTable arg0, Object value,
        boolean arg2, int arg3, int arg4) {
    ((JTextField)component).setText((String)value);
    return component;
}

最佳答案

default renderer and editor通常适用于大多数数据类型,但您可以定义自定义 rendererseditors根据需要。

附录:我不熟悉您片段中显示的方法。相反,向您的模型注册一个 TableModelListener,如下所示,并以保证的任何粒度更新数据库。另见 How to Use Tables: Listening for Data Changes .

附录:@kleopatra 关于您的 TableCellEditor 是正确的。通知监听器的一种便捷方式是调用 super 实现,如图所示 here .请注意,delegate 调用了 fireEditingStopped()

/** @see https://stackoverflow.com/questions/9155596 */
public class NewJavaGUI extends JPanel {

    private final JTable table;

    public NewJavaGUI() {
        String[] colNames = {"C1", "C2", "C3"};
        DefaultTableModel model = new DefaultTableModel(colNames, 0) {

            @Override
            public boolean isCellEditable(int row, int col) {
                // return your actual criteria
                return true;
            }

            @Override
            public Class getColumnClass(int col) {
                // return your actual type tokens
                return getValueAt(0, col).getClass();
            }
        };
        // Add data; note auto-boxing
        model.addRow(new Object[]{"A1", "A2", 42});
        model.addRow(new Object[]{"B1", "B2", 42d});
        model.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                // DML as indicated
            }
        });
        table = new JTable(model);
        this.add(table);
    }

    private void display() {
        JFrame f = new JFrame("NewJavaGUI");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new NewJavaGUI().display();
            }
        });
    }
}

关于java - JTable 中行选择的受控编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9155596/

相关文章:

java - JTable 帮助(调整标题和数据源的大小)

java - 让 JCheckbox 变大..?

java - ARM REST API 需要哪些权限

java - 使用多个 ManyToOne 连接进行查询

java 。集合中的通配符

Java JPanels 在框架中不可见

java - 如何使用 Hibernate 填充 JTable?

java - JVM 可以内联 native 方法吗?

java - 当我导出 Java 程序时,为什么出现框架而不出现面板?

java - 将两个 Jtable 添加到 JScrollPane