【问题标题】:Why would UndoManager.canRedo() return false even though redo() works fine?即使 redo() 工作正常,为什么 UndoManager.canRedo() 会返回 false?
【发布时间】:2020-09-29 02:28:18
【问题描述】:

我使用 Java 的 undo 包中的某些方法得到了相互冲突的结果。在我的程序中,我在 UndoManager 实例上调用 canRedo(),它返回 false。这会让我相信我当时无法重做 UndoManager 中存储的任何操作。然而,当我尝试时,最后一次撤消的操作被正确重做,并且没有抛出 CannotRedoException。对我来说,这种行为似乎是矛盾的,我不确定是什么原因造成的。

下面的代码是一个独立的、单线程的临时文件,专门为这个问题创建。

import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

class UndoManagerRedoScratch {
    public static void main(String[] args) {
        UndoManager actionList = new UndoManager();
        actionList.addEdit(new SomeUndoableEdit());

        /* See whether SomeUndoableEdit is undoable. */
        try {
            System.out.println("Action can be undone: " + actionList.canUndo());
            actionList.undo();
        } catch (Exception e) {
            System.out.println("Undo failed");
        }

        /* See whether SomeUndoableEdit is redoable. */
        try {
            System.out.println("Action can be redone: " + actionList.canRedo());
            actionList.redo();
        } catch (Exception e) {
            System.out.println("Redo failed");
        }
    }
}

class SomeUndoableEdit extends AbstractUndoableEdit {

    public SomeUndoableEdit() {
        System.out.println("SomeUndoableEdit has been created");
    }

    @Override
    public void undo() throws CannotUndoException {
        System.out.println("SomeUndoableEdit has been undone.");
    }

    @Override
    public void redo() throws CannotRedoException {
        System.out.println("SomeUndoableEdit has been redone.");
    }
}

输出:

SomeUndoableEdit has been created
Action can be undone: true
SomeUndoableEdit has been undone.
Action can be redone: false
SomeUndoableEdit has been redone.

如您所见,redo() 成功执行,没有抛出CannotRedoException,但canUndo() 返回false。再一次,这对我来说似乎是矛盾的。

有什么想法吗?

【问题讨论】:

    标签: java undo-redo redo


    【解决方案1】:

    根据像javax.swing.undo.StateEdit 这样的jre 中的一些实现,您应该调用super.undo()super.redo() 作为覆盖方法中的第一个调用。

    所以你的情况:

    class SomeUndoableEdit extends AbstractUndoableEdit {
    
        public SomeUndoableEdit() {
            System.out.println("SomeUndoableEdit has been created");
        }
    
        @Override
        public void undo() throws CannotUndoException {
            super.undo();
            System.out.println("SomeUndoableEdit has been undone.");
        }
    
        @Override
        public void redo() throws CannotRedoException {
            super.redo();
            System.out.println("SomeUndoableEdit has been redone.");
        }
    }
    

    【讨论】:

    • 非常感谢,这似乎解决了它!关于我在哪里可以找到这样的信息的任何建议?我在 AbstractUndoableEdit 或 StateEdit 的 Oracle 文档中没有看到它。
    • 我直接去了jre源。基本搜索了AbstractUndoableEdit的类型层次结构中的一些例子。
    猜你喜欢
    • 2021-08-15
    • 1970-01-01
    • 2022-12-11
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    相关资源
    最近更新 更多