我想创建"撤消"和"重做"使用堆栈的按钮(不是摆动)。
当"撤消"单击,文本字段,列表和所有内容都需要撤消/重做。我知道我必须使用pop,push等。但是我在堆栈中放了什么? Textfield值?列出内容?
示例:
如何重置这些?
有没有办法在库中存储项目数据的当前状态?
答案 0 :(得分:2)
希望我能帮到你,因为我并不真正明白你的意思"使用堆栈(不是摆动)"。 Stack
是数据结构, Swing 是UI框架。所以那些基本上没有任何关系。
通常使用以下方法之一来实现撤消/重做。您应该使用哪一个取决于您所需的撤消/重做行为。
使用命令模式撤消/重做。
实现这种方法看起来像这样:
public interface ICommand {
void do();
void undo();
}
public class StudentSaveCommand implements ICommand {
public StudentSaveCommand(Student student) { ... }
[...]
}
在do()
课程的StudentSaveCommand
实施中,您实施了应该用来实际保存给定学生的操作,例如将数据插入数据库,保存到文件或只是将其添加到列表中。
在undo()
实施中,您实施了还原do()
实施的操作,例如从数据库中删除,删除文件或从列表中删除它。
要使用Stack
最终实现撤消/重做功能,您可以执行以下操作:
public void btnSaveStudentClickHandler() {
ICommand c = new IStudentSaveCommand(theStudentFromGUI);
c.do();
_redoStack.clear();
_undoStack.push(c);
}
public void btnUndoClickHandler() {
ICommand undoCommand = _undoStack.pop();
undoCommand.undo();
_redoStack.push(undoCommand);
}
public void btnRedoClickHandler() {
ICommand redoCommand = _redoStack.pop();
redoCommand.do();
_undoStack.push(redoCommand);
}
为了轻松地将模型上的更改反映到GUI,我将实现/使用某种数据绑定。正如您所看到的,这种方法不适合在非常细粒度的级别上实现撤消/重做,例如在文本框中更改学生的姓名。这是第二种方法。
使用 Memento Pattern 撤消/重做。
使用此模式可以保存和恢复对象的状态,例如一个Student
。使用此模式和Stack
代码的撤消/重做功能的实现可能看起来像这样:
public void txtStudentNameLostFocusHandler() {
Memento sm = student.getSavedState();
_redoStack.clear();
_undoStack.push(sm);
}
public void btnUndoClickHandler() {
Memento m = _undoStack.pop();
student.restoreSavedState(m);
_redoStack.push(m);
}
// [...] Redo implementation straight-forward
为了反映对Student
对象所做的更改,我更喜欢数据绑定或实现类似下面的方法,必须在撤消/重做操作后调用:
public void updateStudentGUI(Student student) {
txtName.setText(student.getName());
[...]
}
要在撤消/重做实现中获得这两种方法的优点,您也可以将这些方法结合起来。但是,最好的方法很大程度上取决于规范,分别取决于您真正想要实现的目标。