在JTable中对行选择进行受控编辑 [英] Controlled editing of a row selection in JTable

查看:67
本文介绍了在JTable中对行选择进行受控编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JTable displaying rows from an SQL database. The table is relatively small (only 4 columns and up to 1000 rows).

我想让用户有机会编辑表中的任何单元格,但要避免过多地限制它,以至于他们必须使用编辑对话框(这样可以使错误检查和验证更加容易,但不那么直观)

I would like to give the user the opportunity to edit any cells in the table but want to avoid restricting it so much so that they must use an edit dialog box (this makes for far easier error checking and validation but is less intuitive)

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

I have tried a few different ways of controlling edit selections using the valueChanged method of my JTable but haven't had much luck.

我希望在编辑结束时对每一行进行编辑并将其写入数据库.我希望一旦单击一个单元格以开始对该行的编辑,就无法选择其他行,直到用户完成对该行的编辑为止(其他行显示为灰色).编辑每个单元格并按Enter后,编辑选择应跳到同一行的下一列.

I would like each row to be edited and written to the database at the conclusion of editing. I would like that once a cell has been clicked to start the editing of that row, no other rows can be selected until the user has finished editing the row (other rows are grayed out). After editing each cell and pressing enter, the edit selection should jump to the next column in the same row.

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

Can anyone give pointers on how I can achieve this?

//  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);
        }

    };

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

Edit - custom cell editor with table pointer seems to be a start

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;
}

}

推荐答案

The default renderer and editor is typically adequate for most data types, but you can define custom renderers and editors as needed.

附录:我不熟悉您的片段中显示的方法.相反,如下所示,在模型中注册一个TableModelListener,并使用所保证的粒度更新数据库.另请参见 如何使用表:侦听数据更改 .

Addendum: I'm unfamiliar with the approach shown in your fragment. Instead, register a TableModelListener with your model, as shown below, and update the database with whatever granularity is warranted. See also How to Use Tables: Listening for Data Changes.

附录:@kleopatra关于您的TableCellEditor是正确的.通知侦听器的一种便捷方法是调用超级实现,如此处所示.请注意,delegate调用fireEditingStopped().

Addendum: @kleopatra is correct about your TableCellEditor. One convenient way to notify listeners is to invoke the super implementation, as shown here. Note that the delegate invokes 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();
            }
        });
    }
}

这篇关于在JTable中对行选择进行受控编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆