/* * A simple Java program that demonstrates how undo works with Command objects * * Ben Bederson, May 8, 2002 */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import java.util.*; public class UndoExample extends JFrame { JMenuBar menuBar; JTextArea textArea; JMenu fileMenu; JMenu editMenu; Stack undoStack; Stack redoStack; JMenuItem undoMenu; JMenuItem redoMenu; public UndoExample() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); undoStack = new Stack(); redoStack = new Stack(); // Create a menu menuBar = new JMenuBar(); fileMenu = new JMenu("File"); fileMenu.add(new AbstractAction("Exit") { public void actionPerformed(ActionEvent e) { System.exit(0); } }); editMenu = new JMenu("Edit"); undoMenu = new JMenuItem(new AbstractAction("undo") { public void actionPerformed(ActionEvent e) { undo(); } }); undoMenu.setEnabled(false); editMenu.add(undoMenu); redoMenu = new JMenuItem(new AbstractAction("redo") { public void actionPerformed(ActionEvent e) { redo(); } }); redoMenu.setEnabled(false); editMenu.add(redoMenu); editMenu.add(new JSeparator()); editMenu.add(new AbstractAction("insert some text") { public void actionPerformed(ActionEvent e) { insertSomeText(); } }); menuBar.add(fileMenu); menuBar.add(editMenu); // Create a text box textArea = new JTextArea(); textArea.setRows(20); textArea.setColumns(50); JScrollPane scrollPane = new JScrollPane(textArea); // Set up the GUI setJMenuBar(menuBar); getContentPane().add(scrollPane); pack(); // Calculate the size of the window setVisible(true); // Make the window visible } void insertSomeText() { String[] randomText = {"Hello world\n", "What's up\n", "FooBar\n", "Question Technology\n"}; int index = (int)(Math.random() * randomText.length); String text = randomText[index]; InsertCommand insertCommand = new InsertCommand(textArea, text); insertCommand.execute(); undoStack.push(insertCommand); redoStack.clear(); undoMenu.setEnabled(true); } void undo() { if (!undoStack.isEmpty()) { Command command = (Command)undoStack.pop(); command.undo(); redoStack.push(command); redoMenu.setEnabled(true); } if (undoStack.isEmpty()) { undoMenu.setEnabled(false); } } void redo() { if (!redoStack.isEmpty()) { Command command = (Command)redoStack.pop(); command.redo(); undoStack.push(command); undoMenu.setEnabled(true); } if (redoStack.isEmpty()) { redoMenu.setEnabled(false); } } public static void main(String[] args) { new UndoExample(); } } interface Command { public void execute(); public void undo(); public void redo(); } class InsertCommand implements Command { JTextArea textArea; String textToInsert; String origText; String newText; public InsertCommand(JTextArea textArea, String textToInsert) { this.textArea = textArea; this.textToInsert = textToInsert; } public void execute() { origText = textArea.getText(); textArea.insert(textToInsert, textArea.getCaretPosition()); newText = textArea.getText(); } public void undo() { textArea.setText(origText); } public void redo() { textArea.setText(newText); } }