/*
Core SWING Advanced Programming
By Kim Topley
ISBN: 0 13 083292 8
Publisher: Prentice Hall
*/
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.UndoableEditListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import javax.swing.undo.UndoableEditSupport;
public class UndoExample3 extends JFrame {
public UndoExample3() {
super("Undo/Redo Example 3");
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
DefaultMutableTreeNode node = new DefaultMutableTreeNode("Apollo 8");
rootNode.add(node);
node.add(new DefaultMutableTreeNode("Borman"));
node.add(new DefaultMutableTreeNode("Lovell"));
node.add(new DefaultMutableTreeNode("Anders"));
node = new DefaultMutableTreeNode("Apollo 11");
rootNode.add(node);
node.add(new DefaultMutableTreeNode("Armstrong"));
node.add(new DefaultMutableTreeNode("Aldrin"));
node.add(new DefaultMutableTreeNode("Collins"));
node = new DefaultMutableTreeNode("Apollo 12");
rootNode.add(node);
node.add(new DefaultMutableTreeNode("Conrad"));
node.add(new DefaultMutableTreeNode("Gordon"));
node.add(new DefaultMutableTreeNode("Bean"));
UndoableTree tree = new UndoableTree(rootNode);
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
// Create the undo manager and actions
UndoManager manager = new UndoManager();
tree.addUndoableEditListener(manager);
Action undoAction = new UndoAction(manager);
Action redoAction = new RedoAction(manager);
// Add the actions to buttons
JPanel panel = new JPanel();
JButton undoButton = new JButton("Undo");
JButton redoButton = new JButton("Redo");
undoButton.addActionListener(undoAction);
redoButton.addActionListener(redoAction);
panel.add(undoButton);
panel.add(redoButton);
getContentPane().add(panel, BorderLayout.SOUTH);
// Assign the actions to keys
((JComponent) getContentPane()).registerKeyboardAction(undoAction,
KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK),
JComponent.WHEN_IN_FOCUSED_WINDOW);
((JComponent) getContentPane()).registerKeyboardAction(redoAction,
KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK),
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
// The Undo action
public class UndoAction extends AbstractAction {
public UndoAction(UndoManager manager) {
this.manager = manager;
}
public void actionPerformed(ActionEvent evt) {
try {
manager.undo();
} catch (CannotUndoException e) {
Toolkit.getDefaultToolkit().beep();
}
}
private UndoManager manager;
}
// The Redo action
public class RedoAction extends AbstractAction {
public RedoAction(UndoManager manager) {
this.manager = manager;
}
public void actionPerformed(ActionEvent evt) {
try {
manager.redo();
} catch (CannotRedoException e) {
Toolkit.getDefaultToolkit().beep();
}
}
private UndoManager manager;
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {}
JFrame f = new UndoExample3();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
f.pack();
f.setVisible(true);
}
}
class UndoableTree extends JTree {
// Only one constructor for brevity
public UndoableTree(TreeNode root) {
super(root);
}
public void addUndoableEditListener(UndoableEditListener l) {
support.addUndoableEditListener(l);
}
public void removeUndoableEditListener(UndoableEditListener l) {
support.removeUndoableEditListener(l);
}
public void collapsePath(TreePath path) {
boolean wasExpanded = isExpanded(path);
super.collapsePath(path);
boolean isExpanded = isExpanded(path);
if (isExpanded != wasExpanded) {
support.postEdit(new CollapseEdit(path));
}
}
public void expandPath(TreePath path) {
boolean wasExpanded = isExpanded(path);
super.expandPath(path);
boolean isExpanded = isExpanded(path);
if (isExpanded != wasExpanded) {
support.postEdit(new ExpandEdit(path));
}
}
private void undoExpansion(TreePath path) {
super.collapsePath(path);
}
private void undoCollapse(TreePath path) {
super.expandPath(path);
}
private class CollapseEdit extends AbstractUndoableEdit {
public CollapseEdit(TreePath path) {
this.path = path;
}
public void undo() throws CannotUndoException {
super.undo();
UndoableTree.this.undoCollapse(path);
}
public void redo() throws CannotRedoException {
super.redo();
UndoableTree.this.undoExpansion(path);
}
public String getPresentationName() {
return "node collapse";
}
private TreePath path;
}
private class ExpandEdit extends AbstractUndoableEdit {
public ExpandEdit(TreePath path) {
this.path = path;
}
public void undo() throws CannotUndoException {
super.undo();
UndoableTree.this.undoExpansion(path);
}
public void redo() throws CannotRedoException {
super.redo();
UndoableTree.this.undoCollapse(path);
}
public String getPresentationName() {
return "node expansion";
}
private TreePath path;
}
private UndoableEditSupport support = new UndoableEditSupport(this);
}
|