2010-12-20 77 views
7

我有一個可編輯的JTable,並且已經設置的DefaultCellEditor像這樣:爲什麼在編輯JTable單元時按escape鍵時不調用cancelCellEditing()?

colModel.getColumn(1).setCellEditor(new DefaultCellEditor(txtEditBox) { 
     // ... 
     @Override 
     public void cancelCellEditing() { 
      super.cancelCellEditing(); 
      // handling the event 
     } 
     // ... 
    } 

不過,按下逃跑的時候,同時編輯在此列的單元格,雖然編輯模式結束,這種方法不叫。任何想法爲什麼?難道我做錯了什麼?有沒有辦法來處理(除了手動添加一個KeyListener)?

回答

10

官方方式:您可以註冊一個CellEditorListener:AbstractCellEditor.addCellEditorListener(...)。如果編輯被取消,應該調用editingCanceled(ChangeEvent e)。 由於一個Sun錯誤http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788481editingCanceled不叫 :(

至於解決方法,你可以自己註冊自己的Esc鍵的動作和處理它。但它不會調整大小事件工作。

另一個解決方案(快速和骯髒;-)):覆蓋方法JTable.removeEditor()並在超級調用後插入代碼。

+0

好,吸。謝謝。 – Epaga 2010-12-20 15:43:54

0

我也有這個問題。我寫了另一個涉及ActionListener和FocusListener的解決方法。這是它:

public class TableEditorListenerHelper { 

// dealing with events 
private final EventListenerList listeners = new EventListenerList(); 
private ChangeEvent changeEvent; 

// cell editor that we're helping 
private CellEditor editor; 

// transient state 
private boolean editing = false; 
private JTable table; 

public TableEditorListenerHelper(CellEditor editor, JTextField field) { 
    this.editor = editor; 
    field.addActionListener(new ActionListener() { 
     @Override public void actionPerformed(ActionEvent e) { 
      fireEditingStopped(); 
     } 
    }); 
    field.addFocusListener(new FocusListener() { 

     @Override public void focusGained(FocusEvent e) { 
      editing = true; 
     } 

     @Override public void focusLost(FocusEvent e) { 
      JTable table = TableEditorListenerHelper.this.table; 
      if (editing && isEditing(table)) { 
       fireEditingCanceled(); 
      } 
     } 

     private boolean isEditing(JTable table) { // a hack necessary to deal with focuslist vs table repaint 
      return table != null && table.isEditing(); 
     } 

    }); 
} 

public void setTable(JTable table) { 
    this.table = table; 
} 

public void addCellEditorListener(CellEditorListener l) { 
    listeners.add(CellEditorListener.class, l); 
} 

public void removeCellEditorListener(CellEditorListener l) { 
    listeners.remove(CellEditorListener.class, l); 
} 

public CellEditorListener[] getCellEditorListeners() { 
    return listeners.getListeners(CellEditorListener.class); 
} 

protected void fireEditingCanceled() { 
    for (CellEditorListener l : getCellEditorListeners()) { 
     l.editingCanceled(getOrCreateEvent()); 
    } 
    resetEditingState(); 
} 

protected void fireEditingStopped() { 
    for (CellEditorListener l : getCellEditorListeners()) { 
     l.editingStopped(getOrCreateEvent()); 
    } 
    resetEditingState(); 
} 

private void resetEditingState() { 
    table = null; 
    editing = false; 
} 

private ChangeEvent getOrCreateEvent() { 
    return changeEvent = changeEvent == null ? new ChangeEvent(editor) : changeEvent; 
} 

Here你可以找到多一點完整的解決方案。

0

另一種方式修復錯誤

jTable.addPropertyChangeListener("tableCellEditor", e -> { 
    Object o = e.getOldValue(); 
    if (o instanceof DefaultCellEditor) { 
     ((DefaultCellEditor) o).cancelCellEditing(); 
    } 
}); 
相關問題