【问题标题】:how to detect enter pressed while jtable cell is being edited?如何在编辑jtable单元格时检测输入?
【发布时间】:2014-01-25 18:49:50
【问题描述】:

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

我想不通,有人做过或知道怎么做吗?

基本上,现在要完成动作,人们必须按两次回车,一次结束编辑,另一次用于我想要发生的动作,我希望在编辑时只需要一次。

谢谢

【问题讨论】:

  • KeyListener 可能不是你的朋友,它很少是。更新单元格时,会调用模型的 setValueAt 方法,这可能是获取更新的最佳选择。如果那是太多的工作。这应该会触发一个表模型事件,您也可以对其做出反应...
  • 是个好主意,但我无法完成,我覆盖了原来的,但它基本上变成了一个循环,因为我做了 setValue 它调用了一个计算方法,然后再次使用 setValue 等等以此类推,直到它变成一个stackoverflow。
  • 就个人而言,我会有一个名为“刷新”的按钮(例如)和一个键绑定(可能是 F5),它负责更新计算和更新模型的状态。这里的目的是将“计算”与模型和表格分开......但这只是我;)
  • MadProgrammer,是的,这是一个过于简单的想法(我也会自己使用),但对于想要快速轻松地做事的普通用户来说是无法使用的(相信我,我有这么多这些人的问题)基本上,整个事情必须像excel一样,你进行修改,一切都需要更新,没有按钮按下没有任何东西,这就是为什么,editingStopped在这里完美工作
  • 您必须输入@MadProgrammer,然后他才会收到通知。

标签: java swing jtable keylistener tablecelleditor


【解决方案1】:

我在 jtable 上有一个 keylistener 以便当有人按下时输入一些 计算发生。但是,这只发生在该人不是 编辑。我想在一个人完成时应用此操作 正在编辑一个单元格并按 Enter 以完成并关闭编辑。

  • TableCellEditor 没有将 KeyListener 添加到 JTable 中

基本上,现在要完成操作,人们必须按 Enter 两次,一次结束编辑,另一次用于我想要的操作 发生这种情况,我想让它在编辑时只需要一次。

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

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

  • TableCellEditor 暂时是 JComponent,你必须添加 KeyBindings 来调用 stopCellEditing,以防用作 TableCellEditor 的 JComponents 对按下的 ENTER 键没有反应


【讨论】:

  • 更多here关于合适的键绑定。
  • 感谢您提供的所有建议,我无法发布任何有用的 SSCCE,因为其中没有任何内容可以显示我的问题,而不是 jtable 上的 keylistener。感谢您的链接,我已经阅读了自定义渲染器,但阅读更多内容不会有什么坏处
【解决方案2】:

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

编辑:

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 的Table Cell Listener,它提供了对编辑的自定义处理。

【讨论】:

  • -1 Application code will not use these methods explicitly, they are used internally by JTable. 我认为你应该实现一个CellEditorListener
  • @nachokk 是对的;如果您不能使用键绑定,建议使用替代方法here
  • @allegroBegin 如果这是一个解决方案,那么您很可能正在与摇摆之风作斗争-重新访问您的设计将是我能给的最佳建议;-) -1 用于建议核武器
  • @allegroBegin well,如果你覆盖JTable#editingStopped,如果你阅读了oracle的家伙说的链接,JTable内部使用了该方法,Application code will not use these method explicity如果你决定覆盖它,那么你必须调用super.editingStopped 什么是糟糕的设计,也许当您不想被调用时,有时会在内部调用该方法;)..
  • 最好使用TableModel#setValueAt 或实现TableModel 监听器。以这种方式覆盖表格是一种糟糕的设计和反模式。因为该表可能使用多个编辑器,这也意味着您无需担心尝试涵盖所有可能性......恕我直言
【解决方案3】:

您可以自定义自己的编辑器。使用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 相同

【讨论】:

  • 谢谢你,有趣的想法,我会投赞成票,但我不能以我目前的排名
  • @allegroBegin 我删除了继承,因为它没有必要现在它更好更灵活:)
  • 这对于我正在开发的另一个我还没有进入 UI 的程序来说看起来很酷,非常感谢
猜你喜欢
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 2012-04-21
  • 2010-12-07
  • 2019-04-30
  • 1970-01-01
  • 2016-10-15
  • 2011-09-27
相关资源
最近更新 更多