在编辑jtable单元格时如何检测输入?

时间:2014-01-07 21:47:45

标签: java swing jtable keylistener tablecelleditor

我在jtable上有一个keylistener,这样当有人按下输入时会发生一些计算。但是,这仅在此人未编辑时才会发生。当一个人完成编辑单元格并按Enter键完成并关闭编辑时,我想应用此操作。

我无法弄清楚这一点,有人做过这件事还是知道怎么做?

基本上,现在对于要完成的操作,人们必须按两次输入,一次结束编辑,另一次按我想要发生的操作,我想在编辑时只需要输入一次。

谢谢

3 个答案:

答案 0 :(得分:4)

您可以自定义自己的编辑器。使用DefaultCellEditor而不是使用KeyListener,您应该使用KeyBindings

见这个例子。

            JTable table = new JTable(myModel);
            JTextField cell = new JTextField();
            final TableCellEditor cellEditor = new DefaultCellEditor(cell);
            table.getColumnModel().getColumn(column).setCellEditor(cellEditor);
            InputMap iMap = cell.getInputMap(JComponent.WHEN_FOCUSED);
            iMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),    KeyEvent.getKeyText(KeyEvent.VK_ENTER));
            ActionMap aMap = cell.getActionMap();
            aMap.put(KeyEvent.getKeyText(KeyEvent.VK_ENTER), new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if(callSomeOperationsIsOk()){
                      cellEditor.stopCellEditing();
                    }else{
                      cellEditor.cancelCellEditing();
                    }
                }
            });
    }

在教程How to use Tables中阅读更多内容,也许您遇到的问题与我之前的question

相同

答案 1 :(得分:3)

  

我在jtable上有一个keylistener,以便当有人按下时输入一些   计算发生了。但是,只有当这个人没有时,才会发生这种情况   编辑。我想在一个人完成时应用这个动作   编辑单元格并按Enter键完成并关闭编辑。

  • TableCellEditor没有将KeyListener添加到JTable
  

基本上,现在要完成行动,人们必须按回车键   两次,一次结束编辑,另一次结束我想要的动作   要发生这种情况,我想在编辑时只需要一次。

  • JComponents(用作TableCellEditor)默认响应按下ENTER键

  • 不要将JComponent放到TableModel中,应该只存储由TableCellRenderer绘制的值和TableCellEditor的初始值

  • TableCellEditor暂时是JComponent,如果JComponents用作TableCellEditor不响应按下ENTER键,则必须添加KeyBindings来调用stopCellEditing


答案 2 :(得分:1)

您可以覆盖JTable.editingStopped,在编辑完成时调用该Table Cell Listener并在该方法中应用您的操作。

编辑:

JTable.editingStopped不适用于应用程序扩展。为了避免复杂化,特别是平台相关的复杂化,更好的方法是覆盖模型的setValueAt或注册TableModelListener。这是一个例子:

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class DemoTable3 {
    private static void createAndShowUI() {
        JFrame frame = new JFrame("DemoTable");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Object[][] rows = { { "Column 1", "Column 2" },
                { "Column 1", "Column 2" } };
        Object[] columns = { "Column 1", "Column 2" };

        DefaultTableModel model = new DefaultTableModel(rows, columns);
        model.addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                System.out.println("apply additional action");
            }
        });

        JTable table = new JTable(model);
        frame.add(new JScrollPane(table));
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

另一种方法是添加CellEditorListener以捕获 editingStopped 事件。例如:

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.DefaultTableModel;

public class DemoTable2 {

    private static void createAndShowUI() {
        JFrame frame = new JFrame("DemoTable");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Object[][] rows = { { "Column 1", "Column 2" },
                { "Column 1", "Column 2" } };
        Object[] columns = { "Column 1", "Column 2" };

        final JTable table = new JTable(new DefaultTableModel(rows, columns));

        table.getDefaultEditor(String.class).addCellEditorListener(
                new CellEditorListener() {
                    public void editingCanceled(ChangeEvent e) {
                        System.out.println("editingCanceled");
                    }

                    public void editingStopped(ChangeEvent e) {
                        System.out.println("editingStopped: apply additional action");
                    }
                });

        frame.add(new JScrollPane(table));
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

另请查看@camickr的{{3}},它提供编辑的自定义处理。