JTextArea中的撤销功能

6

我正在尝试在 JTextArea 中实现撤销功能。在 Google 上搜索了教程,并按照其中一个教程编写了以下代码。当按下 Ctrl+Z 键时触发事件。但是对我来说它不起作用。我有什么遗漏的吗?

private void undoActionPerformed(java.awt.event.ActionEvent evt) {
    Document doc = editorTextArea.getDocument();
    final UndoManager undo = new UndoManager();

    doc.addUndoableEditListener(new UndoableEditListener() {
        @Override
        public void undoableEditHappened(UndoableEditEvent e) {
            undo.addEdit(e.getEdit());
        }
    });
}

3
不确定您阅读了哪个教程,但是我从这个教程中的代码可以正常工作。 - Pshemo
2个回答

22

从你的例子中,很难知道你做了多少工作,但是我成功地让这个工作起来了...

private UndoManager undoManager;

// In the constructor

undoManager = new UndoManager();
Document doc = textArea.getDocument();
doc.addUndoableEditListener(new UndoableEditListener() {
    @Override
    public void undoableEditHappened(UndoableEditEvent e) {

        System.out.println("Add edit");
        undoManager.addEdit(e.getEdit());

    }
});

InputMap im = textArea.getInputMap(JComponent.WHEN_FOCUSED);
ActionMap am = textArea.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Undo");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Redo");

am.put("Undo", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            if (undoManager.canUndo()) {
                undoManager.undo();
            }
        } catch (CannotUndoException exp) {
            exp.printStackTrace();
        }
    }
});
am.put("Redo", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            if (undoManager.canRedo()) {
                undoManager.redo();
            }
        } catch (CannotUndoException exp) {
            exp.printStackTrace();
        }
    }
});

2
1+键绑定是这里的最佳选择。 - Hovercraft Full Of Eels
CTRL+SHIFT+Z 通常也被用作重做快捷键,我建议添加以下代码:im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | Event.SHIFT_MASK), "Redo"); - Emmanuel Bourg
同时创建 UndoableEditListener 并不是必要的,可以用 doc.addUndoableEditListener(undoManager); 替代。 - Emmanuel Bourg
@EmmanuelBourg 使用监听器的目的是为了展示它能够正常工作。 - MadProgrammer
@EmmanuelBourg 我想我从NetBeans或Word中复制了"redo",记不清了:P - MadProgrammer
显示剩余2条评论

-1

我不确定,但也许你不能为你的GUI添加addKeyListener。
例如:

class Example implements KeyListener{

  .
  .
  .

  this.addKeyListener(this); // if want to add key listener for main container

  .
  .
  .

}

this 是关于如何使用键盘监听器的。


键盘监听器已添加。我正在使用NetBeans。撤销是一个菜单项。 - FirmView
6
不要使用KeyListener,因为它太底层了。Swing组件使用按键绑定,这是MadProgrammer推荐的方法。 - Hovercraft Full Of Eels

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接