Java 如何在编辑jtable单元格时检测按下enter键?

Java 如何在编辑jtable单元格时检测按下enter键?,java,swing,jtable,keylistener,tablecelleditor,Java,Swing,Jtable,Keylistener,Tablecelleditor,我在jtable上有一个keylistener,这样当有人按下enter键时,就会发生一些计算。但是,只有当用户未进行编辑时,才会发生这种情况。当某人完成编辑单元格并按enter键完成并关闭编辑时,我希望应用此操作 我搞不懂,有人做过或者知道怎么做吗 基本上,现在对于要执行的操作,人们必须按两次enter键,一次结束编辑,另一次对于我想要执行的操作,我希望在编辑时只需要按一次 多谢各位 我在jtable上有一个keylistener,这样当有人按下时,可以输入一些 计算会发生。但是,只有当此人不

我在jtable上有一个keylistener,这样当有人按下enter键时,就会发生一些计算。但是,只有当用户未进行编辑时,才会发生这种情况。当某人完成编辑单元格并按enter键完成并关闭编辑时,我希望应用此操作

我搞不懂,有人做过或者知道怎么做吗

基本上,现在对于要执行的操作,人们必须按两次enter键,一次结束编辑,另一次对于我想要执行的操作,我希望在编辑时只需要按一次

多谢各位

我在jtable上有一个keylistener,这样当有人按下时,可以输入一些 计算会发生。但是,只有当此人不在时,才会发生这种情况 编辑。我希望在某人完成时应用此操作 编辑单元格并按enter键完成并关闭编辑

  • TableCellEditor没有将KeyListener添加到JTable中
基本上,现在要执行操作,必须按enter键 两次,一次结束编辑,另一次完成我想要的动作 为了实现这一点,我希望在编辑时只需要一次

  • JComponents(用作TableCellEditor)默认情况下对按下ENTER键作出反应

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

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


  • 这个问题与标准无关,为了获得更好的帮助,请尽快为JTable/XxxTableModel发布一个简短的、可运行的、可编译的、带有硬编码的valur

  • 在阅读甲骨文教程之前,尤其是零件

您可以覆盖,编辑完成时会调用该方法,并在该方法中应用您的操作

编辑:

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();
            }
        });
    }
}
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();
            }
        });
    }
}
另一种选择是添加
CellEditorListener
以捕获editingStopped事件。例如:

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();
            }
        });
    }
}
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提供的编辑自定义处理功能。

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

看看这个例子

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

阅读教程中的更多内容,也许你会遇到与我之前看到的相同的问题,KeyListener可能不是你的朋友,很少是。更新单元格时,将调用models setValueAt方法,这可能是获取更新的最佳选择。如果那需要很多工作的话。这应该会触发一个表模型事件,你也可以对此做出反应…这是一个好主意,但我无法实现,我覆盖了原始的,但它基本上变成了一个循环,因为我做了setValue,它调用一个方法,该方法计算,然后再次使用setValue等等,直到它变成stackoverflow。就我个人而言,我会有一个名为“刷新”的按钮(例如)和一个键绑定(可能是F5),负责更新计算和更新模型的状态。这里的意图是将“计算”与模型和表格分离……但这只是我;)MadProgrammer,是的,这是一个过于简单的想法(我自己也会这么做),但是对于那些想快速简单地做事情的普通用户来说是不可用的(相信我,我和这些人有很多问题)基本上,整个事情都必须像excel一样运行,你需要修改,所有的东西都需要更新,没有按钮,没有任何东西,这就是为什么,EditingStock在这里工作得非常好。你必须把@MadProgrammer放在这里,然后通知他。关于合适的密钥绑定的更多信息。谢谢你所有的建议,我无法发布任何有用的SSCE,因为我在那里没有任何东西可以显示我的问题,而不是jtable上的密钥侦听器。我很感激你的链接,我已经阅读了自定义渲染器,但阅读更多也无妨-1
应用程序代码不会显式使用这些方法,它们由JTable内部使用。
我认为你应该实现一个
CellEditorListener
@nachokk是正确的;如果您不能使用键绑定,则建议您使用另一种方法。@allegroBegin如果这是一种解决方案,您很可能正在与swing抗争-重新访问您的设计将是我能给出的最佳建议;-)-1.建议进行核试验weapon@allegroBegin好吧,如果你覆盖了
JTable#editingStopped
如果你读到了甲骨文公司的人说JTable内部使用这种方法的链接,
应用程序代码不会明确地使用这些方法
如果您决定重写它,那么您必须调用
super.editingStopped
什么是糟糕的设计,并且当您不想被调用时,可能会在内部调用该方法;)。。最好使用
TableModel#setValueAt
或实现
TableModel
侦听器。以这种方式重写表是一种糟糕的设计和反模式。因为表格可能使用多个编辑器,这也意味着您不必担心试图覆盖所有可能性…IMHOthank you,有趣的想法,我会投票,但我现在不能rank@allegroBegin我删除继承是因为现在不需要了,它更好、更灵活:)对于我正在开发的另一个程序来说,这看起来很酷,我还没有进入UI,非常感谢