UndoableEditListener从未在JTextPane/JTextArea中调用过



我正在尝试将UndoableEditListener附加到JTextPaneJTextArea,以便将编辑排入UndoManager

textPane.getDocument().addUndoableEditListener(new UndoableEditListener() {
    @Override
    public void undoableEditHappened(UndoableEditEvent event) {
        undoQueue.addEdit(event.getEdit());
    }
});

但是当我在文本窗口中键入"aaa"时,undoableEditHappened永远不会被调用。

我认为这是Java的错,而不是我的错,所以我用Eclipse调试器打开AbstractDocument.class来观察事件触发器。它有一个专用的listeners阵列。AbstractDocument将其所有侦听器存储在listeners数组中的奇数索引中,侦听器的类型为Class<>'s在偶数指数中。

protected void fireUndoableEditUpdate(UndoableEditEvent e) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length - 2; i >= 0; i -= 2) {
        if (listeners[i] == UndoableEditListener.class) {
            // Lazily create the event:
            // if (e == null)
            // e = new ListSelectionEvent(this, firstIndex, lastIndex);
            ((UndoableEditListener) listeners[i + 1]).undoableEditHappened(e);
        }
    }
}

看到if (listeners[i] == UndoableEditListener.class)行了吗?当我添加undo-change监听器时,调试器会显示包含我的监听器的listeners,以及它之前的索引中的UndoableEditListener.class。但是,当调试器使用if语句时,数组listeners中的所有偶数索引在调试器中都显示为DocumentListener.class。因此,if语句始终是false,并且侦听器从未被调用。

怎么了?这是Java 8的错误吗?还是我错过了一个例子忘记提及的步骤?

问题出现在JTextPane中。我重写了它的setText方法,迫使它调用read,这是setText的替代方法,它在记住各种换行符的同时对它们进行规范化。但是JTextPane.read似乎没有在文档上触发UndoableEditEvent

如果我不去管setText,那么UndoManager.undo就行了。

最新更新