【问题标题】:Java JTable How to transfer focus from the current cell in edit mode to the next cell when key enter is pressedJava JTable如何在按下键时将焦点从编辑模式下的当前单元格转移到下一个单元格
【发布时间】:2016-10-27 12:30:42
【问题描述】:

让我介绍一下我的问题的场景。我希望在 JTable 中呈现数据库表的内容。有了这个 JTable,我应该能够插入新行、删除行以及更新现有行的字段内容。

第一个期望的行为是当一个单元格获得焦点时,如果它是可编辑的,它会直接进入编辑模式,如果它是一个字母数字内容,它的所有内容都会被选中。 (文字、数字、日期等)

下一个期望的行为是Enter 键作为Tab 键工作,即按下Enter 键焦点必须转移到下一个单元格(如果这是可编辑的,则进入编辑模式)两者向前(从左到右)或向后。

为了满足第一个需求,我用下面的方法覆盖了JTable类的changeSelection方法。

@Override
public void changeSelection(int row, int column, boolean toggle, boolean extend) {
    super.changeSelection(row, column, toggle, extend);
    if (editCellAt(row, column)) {
        Component editor = getEditorComponent();
        editor.requestFocusInWindow();
        if (editor instanceof JFormattedTextField) {
            ((JFormattedTextField) editor).select(0,
                    ((JFormattedTextField) editor).getText().length());
        } else if (editor instanceof JTextField) {
            ((JTextField) editor).selectAll();
        }
    }
}

在阅读了大量文档和帖子之后,很明显解决问题的最合适方法是通过使用键绑定,基本上并且在阅读之后,解决方案是分配 @987654325 的行为@ 键到Enter 键,所以我做到了。

private void tableConfiguration() {
    //Configuramos la tabla para que en el caso de que pierda el foco finalice la edición 
    putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);        
    //Cambiamos el comportamiento por defecto de la tecla enter para que actue como TAB
    getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "selectNextColumnCell");
    // cambiamos Shift+Enter para que se comporte como Shift+Tab
    getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK),
            "selectPreviousColumnCell");
    //configuramos el comportamiento por defecto que queremos que tenga nuestro grid
    setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//seleccion simple de celda
    setCellSelectionEnabled(true);//muestra la celda activa seleccionada
    getTableHeader().setReorderingAllowed(false);//no permite reordenar por columnas
    setRowHeight(26);//altura de la fila
}

正如您在代码部分中看到的,它们被分配给EnterShift+Enter Tab Shift+Tab 键的行为。

我遇到的问题是Enter 键有意外行为。当单元格获得焦点时,直接进入编辑模式,当我按下Enter 键时,它会完成编辑,但不会将焦点转移到下一个单元格,我需要再次按下Enter 键才能获得它. TabShift+Tab 键按预期工作,奇怪的是,Shift+Enter 键也能正常工作,完成编辑,移动到上一个单元格并开始编辑模式。

我试图按照不同的策略纠正这种行为,覆盖 JTable 类的方法 editingStopped,通过 TableCellEditor 类,以不同的方式使用侦听器等,但我无法纠正这种行为所以我现在被困住了。有人有建议或解决方案吗?我做错了什么?

你好,

【问题讨论】:

  • ((JTextField) 编辑器).selectAll();应该在 invokeLater 内(将此事件移动到 EDT 队列的末尾)
  • 你好 @mKorbel 谢谢你的帮助,我按照你的建议做了,但它对 JTable 的行为没有影响,它仍然像上面描述的那样工作,TabShift+Tab 和 @987654342 @ 随心所欲,完成单元格的编辑,使用Tab 切换到下一个单元格,使用Shift+TabShift+Enter 切换到上一个单元格,并在新单元格中自动重新进入编辑模式,同时,您必须按两次Enter 键退出编辑并切换到下一个单元格进行编辑。我正在寻找避免这种行为的方法。谢谢

标签: java swing jtable key-bindings tablecelleditor


【解决方案1】:

here 所示,您可以获得与"selectNextColumnCell" 关联的原始Action 的引用,该引用通常与Tab 关联,并在您的editingStopped() 实现中调用它.下面的简化示例还将操作与按 Enter 相关联。结果是按下 Enter 将与按下 Tab 具有相同的效果,即使按键也结束了编辑。

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;

public class TestTableKeyBinding {

    private final String name = "selectNextColumnCell";

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new TestTableKeyBinding();
        });
    }

    TestTableKeyBinding() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        String[] headers = new String[]{"apples", "bananas"};
        String[][] data = new String[][]{{"1", "2"}, {"3", "4"}, {"5", "6"}};
        JTable table = new JTable(data, headers) {
            @Override
            public void editingStopped(ChangeEvent e) {
                super.editingStopped(e);
                this.getActionMap().get(name).actionPerformed(
                    new ActionEvent(this, ActionEvent.ACTION_FIRST, name));
            }
        };
        table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
            .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), name);
        table.setCellSelectionEnabled(true);
        f.add(new JScrollPane(table));
        f.pack();
        f.setSize(new Dimension(320, 240));
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

【讨论】:

  • 谢谢,但遗憾的是,如果您处于编辑模式,Enter 会移动到下一个单元格,Shift+Enter 也会移动,如果您使用 Tab关键它现在有一个奇怪的行为,因为编辑与聚焦单元格不同。我唯一的问题是如何更改其他键没有的Enterkey 的这种特殊行为。
  • 我不明白。请根据我上面的简化示例编辑您的问题以包含minimal reproducible example,以显示您当前的方法。
  • 你好垃圾神,提前感谢你的帮助,因为我不能在这里放一个完整的例子,我把它上传到我的Google drive,在那里你可以得到它,看看我是什么在我之前的评论中说。请特别注意使用Tab 键和Shift 键的行为。再次提前感谢。问候。
猜你喜欢
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多