7

我有一个可编辑的 JTable 并设置了一个 DefaultCellEditor,如下所示:

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

但是,在编辑该列中的单元格时按下escape,虽然编辑模式已经结束,但不会调用该方法。任何想法为什么?难道我做错了什么?有没有办法处理这个问题(除了手动添加 KeyListener 之外)?

4

3 回答 3

11

官方方式:可以注册一个CellEditorListener:AbstractCellEditor.addCellEditorListener(...)。如果编辑被取消,应该调用editingCanceled(ChangeEvent e)。由于 SUN 错误 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788481没有调用editingCanceled :(

作为解决方法,您可以为 ESCAPE 键注册自己的操作并自己处理。但它不适用于调整事件大小。

另一个解决方案(快速而肮脏的;-)):覆盖方法 JTable.removeEditor() 并在超级调用之后插入您的代码。

于 2010-12-20T15:43:27.797 回答
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;
}

在这里您可以找到更完整的解决方案。

于 2014-10-15T22:32:46.943 回答
0

修复错误的另一种方法:

jTable.addPropertyChangeListener("tableCellEditor", e -> {
    Object o = e.getOldValue();
    if (o instanceof DefaultCellEditor) {
        ((DefaultCellEditor) o).cancelCellEditing();
    }
});
于 2017-08-25T15:21:21.210 回答