避免KeyListener
,它關注焦點和事件發送的順序是不可靠的(可能讓它們在你的監聽器之前消耗掉,所以你永遠不會被通知)。
使用key bindings代替
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(), 2, false, false);
if (!table.editCellAt(table.getSelectedRow(), 2)) {
JOptionPane.showMessageDialog(table, "Failed to start cell editing");
}
}
});
我也懷疑這個myTab.changeSelection(myTab.getSelectedRow(), 2, true, false);
通話。 JavaDocs基本上說...
toggle:true,extend:false。如果指定的單元格被選中,請取消選擇它。如果未選中,請選擇它。
對我來說,如果當前選中單元格,它將被取消選中。
更新與工作示例
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.setSurrendersFocusOnKeystroke(true);
到你的代碼...
設置由於單元的JTable轉發鍵盤 事件而激活編輯器 時,此JTable中的編輯器是否獲得鍵盤焦點。默認情況下,該屬性爲false,除非單擊單元格,否則JTable 將保留焦點。
爲什麼在JTable上使用'KeyListener'來開始編輯? – MadProgrammer
我該怎麼做呢?光標選擇整行,我想開始編輯一個特定的列。 – celicni
P.S.另外,我使用自定義命令瀏覽表格(例如,「j'和'k'上下)。 – celicni