我试图应用memento模式在我的tex编辑器应用程序中包含撤销/重做功能。假设它是简化的版本:)。到目前为止,我还没有弄清楚如何保存并恢复键盘上的准确文本输入。我的意思是,我必须将state属性与代码中的textarea链接起来,再加上一些其他修改。我试着把整个代码塞进三个类,Main,Editor,Memento,下面有什么提示吗?谢谢
public class Main {
public static void main(String[] args) {
Editor viewEditor = new Editor();
viewEditor.setVisible(true);
//Storing changes in ArrayList
List<Memento> mementoList = new ArrayList<Memento>();
viewEditor.setState(" first and only state :)");
mementoList.add(viewEditor.saveStatetoMemento());
viewEditor.getStatefromMemento(mementoList.get(0));
}
}
public class Editor extends JFrame {
String state;
public void setState(String state) {
this.state = state;
}
public String getState(String state) {
return state;
}
public Memento saveStatetoMemento() {
System.out.println("Saving state to Memento in Editor.java ");
return new Memento(state);
}
public void getStatefromMemento(Memento memento) {
state = memento.getState();
System.out.println("State restored from memento" + state);
}
//Using UndoManager for handling undo/redo/ operations
private UndoManager um = new UndoManager();
public Editor() {
initUI();
}
public final void initUI() {
//Panel
JPanel panel = new JPanel();
//Text Field
final JTextArea textArea = new JTextArea("");
textArea.getDocument().addUndoableEditListener(new UndoableEditListener() {
public void undoableEditHappened(UndoableEditEvent e) {
um.addEdit(e.getEdit());
state = textArea.getText();
}
});
textArea.setPreferredSize(new Dimension(550, 600));
textArea.setLineWrap(true);
textArea.setFont(new Font("Arial", Font.PLAIN, 20));
textArea.setEditable(true);
// Addind text field to panel
panel.add(textArea);
// Adding panel to JFrame
add(panel);
pack();
// Menubar
JMenuBar menubar = new JMenuBar();
// Menu Brudnopis
JMenu brudnopis = new JMenu("Brudnopis");
brudnopis.setMnemonic(KeyEvent.VK_B);
// Menu Items: Zakoncz
JMenuItem eMenuItemZakoncz = new JMenuItem("Zakoncz");
eMenuItemZakoncz.setMnemonic(KeyEvent.VK_K);
eMenuItemZakoncz.setToolTipText("Zakoncz program");
// Adding action for the item: "Zakoncz"
eMenuItemZakoncz.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
//Menu Edit Item
JMenu edit = new JMenu("Edycja");
edit.setMnemonic(KeyEvent.VK_H);
//Menu items: undo and redo
JMenuItem undo = new JMenuItem("Undo");
undo.setMnemonic(KeyEvent.VK_Z);
undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
//undo.setAction(a);
undo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (um.canUndo()) {
um.undo();
}
}
});
JMenuItem redo = new JMenuItem("Redo");
redo.setMnemonic(KeyEvent.VK_Y);
redo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK));
redo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (um.canRedo()) {
um.redo();
}
}
});
//Adding 'brudnopis' to menubar
menubar.add(brudnopis);
menubar.add(edit);
setJMenuBar(menubar);
//Dodanie opcji do paska menu
brudnopis.add(eMenuItemZakoncz);
edit.add(undo);
edit.add(redo);
setTitle("Brudnopis");
setSize(600, 700);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
public class Memento {
private final String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}发布于 2022-03-14 12:12:16
当TextArea的状态发生变化时,需要附加一个事件处理程序。当前,您只在程序启动时存储其状态。您这样做的确切方式是一个设计决策--如果您对现有的文本编辑器进行实验,您会发现它们通常在每次击键时都会执行与存储状态不同的操作。
您已经定义了一个ArrayList来存储状态。堆栈是一个更适合于Memento模式的结构。如果您支持重做,那么您也需要一个重做堆栈。
我不知道你是把这作为一个学术练习还是为了一个产品。如果是后者,那么仅仅找到一个已经具有成熟的撤销/重做功能的现有Java文本控件似乎更有效。
https://stackoverflow.com/questions/71082058
复制相似问题