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非常感谢你!我已经想了好几个小时了!