2013-01-07 100 views
0

我試圖以編程方式在按鍵上按JTable開始編輯當前行的第三列。JTable在按鍵上編輯

我實現了這keyReleased()包含此代碼

if (e.getKeyCode() == KeyEvent.VK_ENTER) 
{ 
    myTab.changeSelection(myTab.getSelectedRow(), 2, true, false); 
    myTab.editCellAt(myTab.getSelectedRow(), 2); 
} 

當我釋放進入,細胞的確是可編輯的(我可以在末尾鍵入),但沒有插入符的KeyListener的。

當我用鼠標點擊時,行爲與預期的一樣(我可以編輯並且卡爾特存在)。

此外,我已經注意到,在keyrelease上,我的celleditor是null,並且在鼠標點擊它不是null。

我在做什麼錯?

+0

爲什麼在JTable上使用'KeyListener'來開始編輯? – MadProgrammer

+0

我該怎麼做呢?光標選擇整行,我想開始編輯一個特定的列。 – celicni

+0

P.S.另外,我使用自定義命令瀏覽表格(例如,「j'和'k'上下)。 – celicni

回答

6

避免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 將保留焦點。

+0

謝謝!我已經嘗試了這種方法,但它的工作方式與之前相同(插入符號是不可見的,myTab.getCellEditor()返回null) – celicni

+0

然後,您需要提供一個可以修補的示例;) – MadProgrammer

+0

@celicni我已添加一個工作的例子,你需要讓我知道哪個部分不適合你... – MadProgrammer