在 JComponent 上具有 UndoManager 和 Listeners 时的 OO 概念
OO Conception when having UndoManager and Listeners on a JComponent
在 Swing 中构建 GUI 时,我总是遇到一个概念问题,即我以糟糕的方式结束了黑客攻击。我想知道关于它的好的做法。
举个简单的例子
我有一个 JComponent,我想在其上实现 undo/redo 操作,以及一些 add/remove 其他组件的操作。所以,我会开始写作:
public class MyComponent extends JComponent {
private UndoManager undo = new UndoManager();
public void addComponent(JComponent comp) {
this.add(comp);//Add the component to the view
undo.addEdit(new ComponentAddedEdit(comp));//make this action undoable
fireComponentAdded(comp);//warn the listeners that the action occured
}
}
接下来开始做题。在我的 ComponentAddedEdit
中,我会想到类似的东西:
public class ComponentAddedEdit extends AbstractUndoableEdit {
private final JComponent comp;
public ComponentAddedEdit(JComponent comp) {this.comp = comp;}
@Override
public void undo() throws CannotUndoException {
MyComponent.this.removeComponent(comp);
}
@Override
public void redo() throws CannotRedoException {
MyComponent.this.addComponent(comp);
}
}
当然,它不起作用,因为重做操作将创建一个新的 Edit 到 UndoManager。所以我需要创建一个这样的新方法:
public void addComponentNoUndo() {
this.add(comp);//Add the component to the view
fireComponentAdded(comp);//warn the listeners that the action occured
}
最后,仅针对 "add" 操作,我得到了 3 个名称相似的方法:add
、addComponent
和 addComponentNoUndo
。如果我有更多的动作,更复杂的动作,它会变得非常混乱。那你会怎么做呢?
我不是很喜欢摇摆,所以我可能不会给你一个具体的实现答案,但是看到这个tutorial on memento pattern。
您当然需要根据自己的需要进行调整,但我认为这是正确的方法。
尝试编写您自己的 "state"-class 而不是简单地使用字符串。
然后你想撤消一些东西,加载旧状态。如果您不希望用户能够撤消某些操作,只需不要加载以前的状态,告诉用户这是不可能的。考虑将布尔标志 "undoable" 添加到 "state"-class.
编辑
类似
class state extends JComponent {
private boolean undoable;
private JComponent toSave;
public state (boolean undoable, JComponent toSave, ...) {
this.undoable = undoable;
this.toSave = toSave;
...
}
...
}
在 Swing 中构建 GUI 时,我总是遇到一个概念问题,即我以糟糕的方式结束了黑客攻击。我想知道关于它的好的做法。
举个简单的例子
我有一个 JComponent,我想在其上实现 undo/redo 操作,以及一些 add/remove 其他组件的操作。所以,我会开始写作:
public class MyComponent extends JComponent {
private UndoManager undo = new UndoManager();
public void addComponent(JComponent comp) {
this.add(comp);//Add the component to the view
undo.addEdit(new ComponentAddedEdit(comp));//make this action undoable
fireComponentAdded(comp);//warn the listeners that the action occured
}
}
接下来开始做题。在我的 ComponentAddedEdit
中,我会想到类似的东西:
public class ComponentAddedEdit extends AbstractUndoableEdit {
private final JComponent comp;
public ComponentAddedEdit(JComponent comp) {this.comp = comp;}
@Override
public void undo() throws CannotUndoException {
MyComponent.this.removeComponent(comp);
}
@Override
public void redo() throws CannotRedoException {
MyComponent.this.addComponent(comp);
}
}
当然,它不起作用,因为重做操作将创建一个新的 Edit 到 UndoManager。所以我需要创建一个这样的新方法:
public void addComponentNoUndo() {
this.add(comp);//Add the component to the view
fireComponentAdded(comp);//warn the listeners that the action occured
}
最后,仅针对 "add" 操作,我得到了 3 个名称相似的方法:add
、addComponent
和 addComponentNoUndo
。如果我有更多的动作,更复杂的动作,它会变得非常混乱。那你会怎么做呢?
我不是很喜欢摇摆,所以我可能不会给你一个具体的实现答案,但是看到这个tutorial on memento pattern。
您当然需要根据自己的需要进行调整,但我认为这是正确的方法。
尝试编写您自己的 "state"-class 而不是简单地使用字符串。
然后你想撤消一些东西,加载旧状态。如果您不希望用户能够撤消某些操作,只需不要加载以前的状态,告诉用户这是不可能的。考虑将布尔标志 "undoable" 添加到 "state"-class.
编辑
类似
class state extends JComponent {
private boolean undoable;
private JComponent toSave;
public state (boolean undoable, JComponent toSave, ...) {
this.undoable = undoable;
this.toSave = toSave;
...
}
...
}