我有一个可编辑的JTable并设置了一个DefaultCellEditor,如下所示:
colModel.getColumn( 1 ).setCellEditor( new DefaultCellEditor( txtEditBox ) {
// ...
@Override
public void cancelCellEditing() {
super.cancelCellEditing();
// handling the event
}
// ...
}
但是,在编辑此列中的单元格时按下escape时,虽然编辑模式已完成,但不会调用此方法。有什么想法吗?难道我做错了什么?有没有办法处理这个(除了手动添加KeyListener)?
答案 0 :(得分:11)
官方方式:您可以注册CellEditorListener:AbstractCellEditor.addCellEditorListener(...)。如果取消编辑,则应调用editingCanceled(ChangeEvent e)。 由于SUN错误 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788481,不会调用editCanceled :(
作为解决方法,您可以为ESCAPE键注册自己的操作并自行处理。但它不适用于调整大小事件。
另一个解决方案(快速和脏;-)):覆盖方法JTable.removeEditor()并在超级调用后插入代码。
答案 1 :(得分: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您可以找到更完整的解决方案。
答案 2 :(得分:0)
另一种方式修复此错误:
jTable.addPropertyChangeListener("tableCellEditor", e -> {
Object o = e.getOldValue();
if (o instanceof DefaultCellEditor) {
((DefaultCellEditor) o).cancelCellEditing();
}
});