当前位置: 首页 > 知识库问答 >
问题:

Java JTable按下enter键时如何将焦点从编辑模式下的当前单元格转移到下一个单元格

冯流觞
2023-03-14

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

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

下一个需要的行为是enter键作为选项卡键工作,即按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();
        }
    }
}

在阅读了大量文档和文章之后,很明显解决这个问题的最合适的方法是通过使用键绑定,基本上并且在阅读之后,解决方案是将tab键的行为分配给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+entertabshift+tab键的行为。

我尝试使用不同的策略来纠正这种行为,比如重写JTable类的方法EditingStopp,通过TableCelleditor类,以不同的方式使用监听器,等等,但是我无法纠正这种行为,所以现在我陷入了困境。有人有什么建议或解决办法吗?我做错了什么?

问候,

共有1个答案

詹联
2023-03-14

如下所示,您可以获得对与“selectnextcolumncell”相关联的原始操作的引用,该操作通常与选项卡相关联,并在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);
    }
}
 类似资料:
  • 问题内容: 摘要: 在我的桌面应用程序中,我加载了一个Jtable,并且在编辑模式下(如果我按Tab键)我需要将单元格的焦点放在下一个单元格上。 问题: 当我编辑单元格的值,然后按Tab时,焦点丢失。我在网上做了一些搜索,发现发生这种情况是因为在每个Tab上按下Jtable都会重新加载自身。 可能的解决 方案我想到的一个解决方案是获取正在使用的单元格的索引,将其与全局变量相同,然后在Tab键上按一

  • 总结: 在我的桌面应用程序中,我加载一个Jtable,当处于编辑模式时,如果我按选项卡,我需要将单元格的焦点放在下一个单元格上。 问题:当我编辑单元格的值,然后按Tab键时,焦点丢失。我在网上做了一些搜索,发现这是因为在每个选项卡上按Jtable会重新加载自己。 可能的解决方案我正在考虑的一个解决方案是获取我正在处理的单元格的索引,在全局变量中也是如此,然后按Tab键可以获取下一个单元格的索引,并

  • 我在Angular 1.x上发现了一些项目,用户可以通过按Enter键将焦点移到下一个控件上。 但这对Angular 2不起作用。我如何在Ingular 2中设置对下一个控件的焦点?

  • 问题内容: 最好的方法是,在单击表单内部的Enter时,将焦点转到下一个输入,而不是使用angularjs提交表单。 我有一个包含许多字段的表单,客户习惯于按Enter键移至下一个输入(来自桌面应用程序)。当用户点击Enter时,angularjs保存表单。我喜欢改变这个。可能吗 ? 问题答案: 我建议制定一个自定义指令。这样的事情。我还没有测试。 这样的事情应该起作用。您可能不得不周到一些东西。

  • 我需要JavaFX tableView的可编辑单元格。默认的TextFieldTableCell要求用户按enter提交更改。我认为一个典型的用户期望在单元格外单击时保留更改。我想要的所有功能包括: 单击选择单元格并 在选定的单元格中单击另一个单元格,或回车,开始编辑。 双击单元格开始编辑。 按enter提交对单元格的更改 在单元格之外的任何地方更改鼠标焦点都将向单元格提交更改 我在这篇文章中发现