Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 键盘上的JTable编辑_Java_Swing_Jtable - Fatal编程技术网

Java 键盘上的JTable编辑

Java 键盘上的JTable编辑,java,swing,jtable,Java,Swing,Jtable,我试图通过编程方式开始编辑按键上JTable中当前行的第三列 我已经实现了一个KeyListener,它在keyReleased()中包含此代码 if (e.getKeyCode() == KeyEvent.VK_ENTER) { myTab.changeSelection(myTab.getSelectedRow(), 2, true, false); myTab.editCellAt(myTab.getSelectedRow(), 2); } 当我释放enter时,单元格确

我试图通过编程方式开始编辑按键上
JTable
中当前行的第三列

我已经实现了一个KeyListener,它在
keyReleased()
中包含此代码

if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
    myTab.changeSelection(myTab.getSelectedRow(), 2, true, false);
    myTab.editCellAt(myTab.getSelectedRow(), 2);
}
当我释放enter时,单元格确实是可编辑的(我可以在末尾键入),但没有插入符号

当我用鼠标点击时,行为和预期的一样(我可以编辑并且carret在场)

另外,我注意到在keyrelease上,我的celleditor为null,而在mouseclick上,它不是null


我做错了什么?

避免
KeyListener
,当涉及到事件的焦点和调度顺序时,它是不可靠的(有可能在您的侦听器之前使用它们的密钥,因此您永远不会收到通知)

改用

我还怀疑这个
myTab.changeSelection(myTab.getSelectedRow(),2,true,false)呼叫。JavaDocs基本上说

切换:真,扩展:假。如果选择了指定的单元格,请取消选择它。如果未选择,请选择它

这对我来说意味着,如果单元格当前被选中,它将被取消选中

使用工作示例更新

public class TestTableEditor {

    public static void main(String[] args) {
        new TestTableEditor();
    }

    private JTable table;

    public TestTableEditor() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                table = new JTable(new MyTableModel());
                InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                ActionMap am = table.getActionMap();

                KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);

                im.put(enterKey, "Action.enter");
                am.put("Action.enter", new AbstractAction() {
                    public void actionPerformed(ActionEvent evt) {
                        table.changeSelection(table.getSelectedRow(), 1, false, false);
                        if (!table.editCellAt(table.getSelectedRow(), 1)) {
                            JOptionPane.showMessageDialog(table, "Failed to start cell editing");
                        }
                    }
                });

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyTableModel extends AbstractTableModel {

        @Override
        public int getRowCount() {
            return 1;
        }

        @Override
        public int getColumnCount() {
            return 3;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Object value = null;
            switch (columnIndex) {
                case 0:
                    value = "Can't edit";
                    break;
                case 1:
                    value = "Edit me";
                    break;
                case 2:
                    value = "Can't edit";
                    break;
            }
            return value;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 1;
        }
    }
}
已更新

在所有愚蠢、痛苦、难以找到的事情中

添加
table.setUrrendersFocusonKeystroke(true)到您的代码

设置此JTable中的编辑器在 由于JTable转发键盘,编辑器被激活 单元格的事件。默认情况下,此属性为false,并且JTable 除非单击单元格,否则将保留焦点


避免使用
KeyListener
,当涉及到焦点和事件的调度顺序时,这是不可靠的(可能会在侦听器之前使用它们的密钥,因此您永远不会收到通知)

改用

我还怀疑这个
myTab.changeSelection(myTab.getSelectedRow(),2,true,false)呼叫。JavaDocs基本上说

切换:真,扩展:假。如果选择了指定的单元格,请取消选择它。如果未选择,请选择它

这对我来说意味着,如果单元格当前被选中,它将被取消选中

使用工作示例更新

public class TestTableEditor {

    public static void main(String[] args) {
        new TestTableEditor();
    }

    private JTable table;

    public TestTableEditor() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                table = new JTable(new MyTableModel());
                InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                ActionMap am = table.getActionMap();

                KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);

                im.put(enterKey, "Action.enter");
                am.put("Action.enter", new AbstractAction() {
                    public void actionPerformed(ActionEvent evt) {
                        table.changeSelection(table.getSelectedRow(), 1, false, false);
                        if (!table.editCellAt(table.getSelectedRow(), 1)) {
                            JOptionPane.showMessageDialog(table, "Failed to start cell editing");
                        }
                    }
                });

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyTableModel extends AbstractTableModel {

        @Override
        public int getRowCount() {
            return 1;
        }

        @Override
        public int getColumnCount() {
            return 3;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Object value = null;
            switch (columnIndex) {
                case 0:
                    value = "Can't edit";
                    break;
                case 1:
                    value = "Edit me";
                    break;
                case 2:
                    value = "Can't edit";
                    break;
            }
            return value;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 1;
        }
    }
}
已更新

在所有愚蠢、痛苦、难以找到的事情中

添加
table.setUrrendersFocusonKeystroke(true)到您的代码

设置此JTable中的编辑器在 由于JTable转发键盘,编辑器被激活 单元格的事件。默认情况下,此属性为false,并且JTable 除非单击单元格,否则将保留焦点


为什么要在
JTable
上使用
KeyListener
开始编辑?我还应该怎么做?光标选择整行,我想开始编辑一个特定的列。此外,我还使用自定义命令在表格中导航(
j
k
用于向上和向下)。为什么要在
JTable
上使用
KeyListener
来开始编辑?我还应该怎么做?光标选择整行,我想开始编辑一个特定的列。此外,我还使用自定义命令在表格中导航(
j
k
用于向上和向下)。谢谢!我尝试过这种方法,但其工作方式与之前相同(插入符号不可见,myTab.getCellEditor()返回null),然后您需要提供一个我可以修改的工作示例;)@celicni我添加了一个工作示例,您需要让我知道哪些部分不适合您…谢谢!这也表现出同样的行为。当我用鼠标双击时,插入符号是振动的,我可以左右移动它,但当我按enter键时,没有插入符号,我在左/右键上失去焦点。我只能在“编辑我”字符串的末尾添加文本。(如果相关,我使用Windows XP和Java 1.7)它可以工作!:D非常感谢你!我已经想了好几个小时了!谢谢我尝试过这种方法,但其工作方式与之前相同(插入符号不可见,myTab.getCellEditor()返回null),然后您需要提供一个我可以修改的工作示例;)@celicni我添加了一个工作示例,您需要让我知道哪些部分不适合您…谢谢!这也表现出同样的行为。当我用鼠标双击时,插入符号是振动的,我可以左右移动它,但当我按enter键时,没有插入符号,我在左/右键上失去焦点。我只能在“编辑我”字符串的末尾添加文本。(如果相关,我使用Windows XP和Java 1.7)它可以工作!:D非常感谢你!我已经想了好几个小时了!