【发布时间】:2015-02-19 05:10:15
【问题描述】:
我正在尝试将 UndoableEditListener 附加到 JTextPane 或 JTextArea 以将编辑排队到 UndoManager。
textPane.getDocument().addUndoableEditListener(new UndoableEditListener() {
@Override
public void undoableEditHappened(UndoableEditEvent event) {
undoQueue.addEdit(event.getEdit());
}
});
但是当我在文本窗口中输入“aaa”时,永远不会调用undoableEditHappened。
认为这是 Java 的错,不是我的错,我破解了AbstractDocument.class 用 Eclipse 调试器打开以观察事件触发。它有一个私有的listeners 数组。 AbstractDocument 将其所有侦听器存储在 listeners 数组的奇数索引中,侦听器的类型 Class 存储在偶数索引中。
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)这一行了吗?当我添加撤消更改侦听器时,调试器会显示包含我的侦听器的listeners,以及它之前的索引中的UndoableEditListener.class。但是,当调试器遇到该 if 语句时,数组listeners 中的所有偶数索引在调试器中显示为DocumentListener.class。因此,if 语句始终为 false,并且从未调用过侦听器。
什么鬼?这是 Java 8 的错误吗?还是我错过了示例忘记提及的步骤?
【问题讨论】:
-
您是否尝试过 Swing 教程的 Implementing Undo/Redo 部分中的演示代码?该代码适用于我在 Windows 7 上使用 JDK7。
-
我从演示代码重新开始,果然成功了。谢谢你的建议。它让我注意到我已经自定义了我的 JTextPane。
标签: java swing jtextarea jtextpane undo-redo