Java/Swing JFC/Undo Redo

Материал из Java эксперт
Перейти к: навигация, поиск

Adding Undo and Redo to a Text Component

   <source lang="java">
 

import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class Main{ public static void main(String[] argv) throws Exception{

   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   JFrame f = new JFrame();
   f.add(new JScrollPane(textcomp));
   f.setSize(330,300);
   f.setVisible(true);
   
   doc.addUndoableEditListener(new UndoableEditListener() {
       public void undoableEditHappened(UndoableEditEvent evt) {
           undo.addEdit(evt.getEdit());
       }
   });
   
   textcomp.getActionMap().put("Undo",
       new AbstractAction("Undo") {
           public void actionPerformed(ActionEvent evt) {
               try {
                   if (undo.canUndo()) {
                       undo.undo();
                   }
               } catch (CannotUndoException e) {
               }
           }
      });
   
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo");
   
   textcomp.getActionMap().put("Redo",
       new AbstractAction("Redo") {
           public void actionPerformed(ActionEvent evt) {
               try {
                   if (undo.canRedo()) {
                       undo.redo();
                   }
               } catch (CannotRedoException e) {
               }
           }
       });
   
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo");

}}


 </source>
   
  
 
  



Add Undo and Redo to a text component

   <source lang="java">
 

import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class Main {

 public static void main(String[] argv) throws Exception {
   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   doc.addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       undo.addEdit(evt.getEdit());
     }
   });
   textcomp.getActionMap().put("Undo", new AbstractAction("Undo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canUndo()) {
           undo.undo();
         }
       } catch (CannotUndoException e) {
       }
     }
   });
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo");
   textcomp.getActionMap().put("Redo", new AbstractAction("Redo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canRedo()) {
           undo.redo();
         }
       } catch (CannotRedoException e) {
       }
     }
   });
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo");
 }

}


 </source>
   
  
 
  



Add undo support to the StyleFrame example

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoStyleFrame.java //Add undo support to the StyleFrame example. This example only //retains the most recent edit, to keep things simple. import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.SwingConstants; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.undo.UndoableEdit; public class UndoStyleFrame extends StyleFrame {

 protected UndoAct undoAction = new UndoAct(); // an Action for undo
 protected RedoAct redoAction = new RedoAct(); // an Action for redo
 public UndoStyleFrame() {
   super();
   setTitle("UndoStyleFrame");
   // register the Actions as undo listeners (we inherited textPane)
   textPane.getDocument().addUndoableEditListener(undoAction);
   textPane.getDocument().addUndoableEditListener(redoAction);
   // create menu for undo/redo
   JMenu editMenu = new JMenu("Edit");
   editMenu.add(new JMenuItem(undoAction));
   editMenu.add(new JMenuItem(redoAction));
   menuBar.add(editMenu); // we inherited menuBar from superclass
   // create buttons for undo/redo
   JPanel buttonPanel = new JPanel();
   buttonPanel.add(new JButton(undoAction));
   buttonPanel.add(new JButton(redoAction));
   getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH);
 }
 // begin inner classes ------------
 public class UndoAct extends AbstractAction implements UndoableEditListener {
   private UndoableEdit edit;
   public UndoAct() {
     super("Undo");
     setEnabled(false);
   }
   public void updateEnabled() {
     setEnabled(edit.canUndo());
   }
   public void undoableEditHappened(UndoableEditEvent event) {
     edit = event.getEdit();
     putValue(NAME, edit.getUndoPresentationName());
     updateEnabled();
   }
   public void actionPerformed(ActionEvent ae) {
     edit.undo();
     updateEnabled(); // disable undo
     redoAction.updateEnabled(); // enable redo
   }
 }
 public class RedoAct extends AbstractAction implements UndoableEditListener {
   private UndoableEdit edit;
   public RedoAct() {
     super("Redo");
     setEnabled(false);
   }
   public void updateEnabled() {
     setEnabled(edit.canRedo());
   }
   public void undoableEditHappened(UndoableEditEvent event) {
     edit = event.getEdit();
     putValue(NAME, edit.getRedoPresentationName());
     updateEnabled();
   }
   public void actionPerformed(ActionEvent ae) {
     edit.redo();
     updateEnabled(); // disable redo
     undoAction.updateEnabled(); // enable undo
   }
 }
 // end inner classes ------------
 public static void main(String[] args) {
   JFrame frame = new UndoStyleFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(400, 300);
   frame.setVisible(true);
 }

} //StyleFrame.java //A JTextPane with a menu for Style manipulation. class StyleFrame extends JFrame implements ActionListener {

 protected StyleBox styleBox;
 protected JTextPane textPane;
 protected JMenuBar menuBar;
 protected JMenu applyStyleMenu, modifyStyleMenu;
 protected JMenuItem createItem;
 public StyleFrame() {
   super("StyleFrame");
   styleBox = new StyleBox();
   textPane = new JTextPane();
   getContentPane().add(new JScrollPane(textPane), BorderLayout.CENTER);
   // set up menu
   menuBar = new JMenuBar();
   JMenu styleMenu = new JMenu("Style");
   menuBar.add(styleMenu);
   setJMenuBar(menuBar);
   applyStyleMenu = new JMenu("Set Logical Style");
   applyStyleMenu
       .setToolTipText("set the Logical Style for the paragraph at caret location");
   styleMenu.add(applyStyleMenu);
   modifyStyleMenu = new JMenu("Modify Style");
   modifyStyleMenu
       .setToolTipText("redefine a named Style (will affect paragraphs using that style)");
   styleMenu.add(modifyStyleMenu);
   createItem = new JMenuItem("Create New Style");
   createItem
       .setToolTipText("define a new Style (which can then be applied to paragraphs)");
   createItem.addActionListener(this);
   styleMenu.add(createItem);
   // add the default style to applyStyleMenu and modifyStyleMenu
   createMenuItems(StyleContext.DEFAULT_STYLE);
 }
 protected void createMenuItems(String styleName) {
   // add "styleName" to applyStyleMenu and modifyStyleMenu
   JMenuItem applyItem = new JMenuItem(styleName);
   applyItem.addActionListener(this);
   applyStyleMenu.add(applyItem);
   JMenuItem modifyItem = new JMenuItem(styleName);
   modifyItem.addActionListener(this);
   modifyStyleMenu.add(modifyItem);
 }
 public void actionPerformed(ActionEvent e) {
   // determine which menuItem was invoked and process it
   JMenuItem source = (JMenuItem) e.getSource();
   if (applyStyleMenu.isMenuComponent(source)) {
     // apply an existing style to the paragraph at the caret position
     String styleName = source.getActionCommand();
     Style style = textPane.getStyle(styleName);
     textPane.setLogicalStyle(style);
   }
   if (source == createItem) {
     // define a new Style and add it to the menus
     styleBox.clear();
     int response = JOptionPane.showConfirmDialog(this, styleBox,
         "Style Editor", JOptionPane.OK_CANCEL_OPTION,
         JOptionPane.PLAIN_MESSAGE);
     if (response == JOptionPane.OK_OPTION
         && styleBox.getStyleName().length() > 0) {
       String styleName = styleBox.getStyleName();
       Style style = textPane.addStyle(styleName, null);
       styleBox.fillStyle(style);
       createMenuItems(styleName); // add new Style to the menus
     }
   }
   if (modifyStyleMenu.isMenuComponent(source)) {
     // redefine a Style (will automatically redraw paragraphs using
     // Style)
     String styleName = source.getActionCommand();
     Style style = textPane.getStyle(styleName);
     styleBox.loadFromStyle(style);
     int response = JOptionPane.showConfirmDialog(this, styleBox,
         "Style Editor", JOptionPane.OK_CANCEL_OPTION,
         JOptionPane.PLAIN_MESSAGE);
     if (response == JOptionPane.OK_OPTION)
       styleBox.fillStyle(style);
   }
 }
 public static void main(String[] args) {
   JFrame frame = new StyleFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(400, 300);
   frame.setVisible(true);
 }

} //StyleBox.java //A control panel that can be used to edit a style"s paragraph attributes. class StyleBox extends JPanel {

 private static final String[] fonts = { "Monospaced", "Serif", "SansSerif" };
 private static final String[] sizes = { "8", "10", "12", "18", "24", "36" };
 private JTextField nameField;
 private JComboBox fontCombo, sizeCombo;
 private JTextField leftField, rightField, aboveField, belowField;
 private JCheckBox boldCheck, italicCheck;
 public StyleBox() {
   // create the fields and lay them out
   super(new BorderLayout(4, 4));
   JPanel labelPanel = new JPanel(new GridLayout(8, 1, 0, 2));
   JPanel valuePanel = new JPanel(new GridLayout(8, 1, 0, 2));
   add(labelPanel, BorderLayout.WEST);
   add(valuePanel, BorderLayout.CENTER);
   JLabel lab;
   JPanel sidePanel;
   lab = new JLabel("Style Name", SwingConstants.RIGHT);
   labelPanel.add(lab);
   nameField = new JTextField();
   lab.setLabelFor(nameField);
   valuePanel.add(nameField);
   lab = new JLabel("Font", SwingConstants.RIGHT);
   labelPanel.add(lab);
   fontCombo = new JComboBox(fonts);
   fontCombo.setEditable(true); // user may enter custom value
   lab.setLabelFor(fontCombo);
   valuePanel.add(fontCombo);
   lab = new JLabel("Size", SwingConstants.RIGHT);
   labelPanel.add(lab);
   sizeCombo = new JComboBox(sizes);
   sizeCombo.setEditable(true); // user may enter custom value
   lab.setLabelFor(sizeCombo);
   sidePanel = new JPanel(new BorderLayout(4, 0));
   sidePanel.add(sizeCombo, BorderLayout.CENTER);
   sidePanel.add(new JLabel("points"), BorderLayout.EAST);
   valuePanel.add(sidePanel);
   lab = new JLabel("Left Indent", SwingConstants.RIGHT);
   labelPanel.add(lab);
   leftField = new JTextField();
   lab.setLabelFor(leftField);
   sidePanel = new JPanel(new BorderLayout(4, 0));
   sidePanel.add(leftField, BorderLayout.CENTER);
   sidePanel.add(new JLabel("points"), BorderLayout.EAST);
   valuePanel.add(sidePanel);
   lab = new JLabel("Right Indent", SwingConstants.RIGHT);
   labelPanel.add(lab);
   rightField = new JTextField();
   lab.setLabelFor(rightField);
   sidePanel = new JPanel(new BorderLayout(4, 0));
   sidePanel.add(rightField, BorderLayout.CENTER);
   sidePanel.add(new JLabel("points"), BorderLayout.EAST);
   valuePanel.add(sidePanel);
   lab = new JLabel("Space Above", SwingConstants.RIGHT);
   labelPanel.add(lab);
   aboveField = new JTextField();
   lab.setLabelFor(aboveField);
   sidePanel = new JPanel(new BorderLayout(4, 0));
   sidePanel.add(aboveField, BorderLayout.CENTER);
   sidePanel.add(new JLabel("points"), BorderLayout.EAST);
   valuePanel.add(sidePanel);
   lab = new JLabel("Space Below", SwingConstants.RIGHT);
   labelPanel.add(lab);
   belowField = new JTextField();
   lab.setLabelFor(belowField);
   sidePanel = new JPanel(new BorderLayout(4, 0));
   sidePanel.add(belowField, BorderLayout.CENTER);
   sidePanel.add(new JLabel("points"), BorderLayout.EAST);
   valuePanel.add(sidePanel);
   boldCheck = new JCheckBox("Bold");
   italicCheck = new JCheckBox("Italic");
   sidePanel = new JPanel(new GridLayout(1, 2));
   sidePanel.add(boldCheck);
   sidePanel.add(italicCheck);
   valuePanel.add(sidePanel);
   clear(); // sets initial values, etc.
 }
 public void clear() {
   // reset all fields (also sets nameField to be editable)
   nameField.setText("");
   nameField.setEditable(true);
   fontCombo.setSelectedIndex(0);
   sizeCombo.setSelectedIndex(2);
   leftField.setText("0.0");
   rightField.setText("0.0");
   aboveField.setText("0.0");
   belowField.setText("0.0");
   boldCheck.setSelected(false);
   italicCheck.setSelected(false);
 }
 public String getStyleName() {
   // return the name of the style
   String name = nameField.getText();
   if (name.length() > 0)
     return name;
   else
     return null;
 }
 public void fillStyle(Style style) {
   // mutate "style" with the values entered in the fields
   // (no value checking--could throw NumberFormatException)
   String font = (String) fontCombo.getSelectedItem();
   StyleConstants.setFontFamily(style, font);
   String size = (String) sizeCombo.getSelectedItem();
   StyleConstants.setFontSize(style, Integer.parseInt(size));
   String left = leftField.getText();
   StyleConstants.setLeftIndent(style, Float.valueOf(left).floatValue());
   String right = rightField.getText();
   StyleConstants.setRightIndent(style, Float.valueOf(right).floatValue());
   String above = aboveField.getText();
   StyleConstants.setSpaceAbove(style, Float.valueOf(above).floatValue());
   String below = belowField.getText();
   StyleConstants.setSpaceBelow(style, Float.valueOf(below).floatValue());
   boolean bold = boldCheck.isSelected();
   StyleConstants.setBold(style, bold);
   boolean italic = italicCheck.isSelected();
   StyleConstants.setItalic(style, italic);
 }
 // Load the form from an existing Style.
 public void loadFromStyle(Style style) {
   nameField.setText(style.getName());
   nameField.setEditable(false); // don"t allow name change
   String fam = StyleConstants.getFontFamily(style);
   fontCombo.setSelectedItem(fam);
   int size = StyleConstants.getFontSize(style);
   sizeCombo.setSelectedItem(Integer.toString(size));
   float left = StyleConstants.getLeftIndent(style);
   leftField.setText(Float.toString(left));
   float right = StyleConstants.getRightIndent(style);
   rightField.setText(Float.toString(right));
   float above = StyleConstants.getSpaceAbove(style);
   aboveField.setText(Float.toString(above));
   float below = StyleConstants.getSpaceBelow(style);
   belowField.setText(Float.toString(below));
   boolean bold = StyleConstants.isBold(style);
   boldCheck.setSelected(bold);
   boolean italic = StyleConstants.isItalic(style);
   italicCheck.setSelected(italic);
 }

}


 </source>
   
  
 
  



An example that shows lots of little UndoManager details

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoManagerDetails.java //An example that shows lots of little UndoManager details // import java.util.Enumeration; import java.util.Vector; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; public class UndoManagerDetails {

 public static void main(String[] args) {
   UndoManager mgr = new UndoManager();
   // Show how insignificant edits are skipped over.
   //
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(1, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(2, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(3, false, false, false));
   mgr.addEdit(new SampleUndoableEdit(4, false, false, false));
   System.out.println("--------------------------");
   System.out.println("Insignificant edit example");
   System.out.println("--------------------------");
   mgr.undo();
   mgr.redo();
   System.out.println(mgr.canRedo()); // No more sig. edits
   // Show how edits that call add/replace are used.
   //
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(5, true, true, false));
   mgr.addEdit(new SampleUndoableEdit(6, false, true, false));
   System.out.println("----------------------------------");
   System.out.println("Absorbed (by addEdit) edit example");
   System.out.println("----------------------------------");
   mgr.undo();
   mgr.discardAllEdits();
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(1, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(2, false, true, true));
   System.out.println("--------------------------------------");
   System.out.println("Absorbed (by replaceEdit) edit example");
   System.out.println("--------------------------------------");
   mgr.undo();
   System.out.println(mgr.canUndo());
   // Show how changing limit works.
   mgr.discardAllEdits();
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(1, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(2, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(3, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(4, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(5, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(6, false, true, false));
   System.out.println("----------------------");
   System.out.println("Changing limit example");
   System.out.println("----------------------");
   mgr.undo();
   mgr.undo();
   mgr.undo(); // Now 3 undoable, 3 redoable
   mgr.setLimit(4); // Now 2 undoable, 2 redoable!
   while (mgr.canUndo())
     mgr.undo();
   while (mgr.canRedo())
     mgr.redo();
   // undoOrRedo example
   mgr.discardAllEdits();
   mgr.setLimit(1);
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(1, false, true, false));
   System.out.println("------------------");
   System.out.println("undoOrRedo example");
   System.out.println("------------------");
   System.out.println(mgr.getUndoOrRedoPresentationName());
   mgr.undoOrRedo();
   System.out.println(mgr.getUndoOrRedoPresentationName());
   mgr.undoOrRedo();
   // Show how UndoManager becomes a CompositeEdit.
   mgr.discardAllEdits();
   mgr.setLimit(100);
   //                                 # adds? sig? replace?
   mgr.addEdit(new SampleUndoableEdit(1, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(2, false, true, false));
   mgr.addEdit(new SampleUndoableEdit(3, false, true, false));
   System.out.println("------------------------------");
   System.out.println("Transform to composite example");
   System.out.println("------------------------------");
   mgr.end();
   mgr.undo();
   mgr.redo();
   // Show that adds are no longer allowed. Note that addEdit() returns
   // true in
   // pre-JDK 1.2 Swing releases. This is fixed in JDK 1.2.
   System.out.println(mgr.addEdit(new SampleUndoableEdit(4, false, true,
       false)));
   mgr.undo(); // note that edit 4 is not there
 }

} //SampleUndoableEdit.java //A simple (?) example of an undoable edit. // class SampleUndoableEdit extends AbstractUndoableEdit {

 private boolean isSignificant;
 private boolean isReplacer;
 private int number;
 private boolean allowAdds;
 private Vector addedEdits;
 private UndoableEdit replaced;
 // Create a new edit with an identifying number. The boolean arguments
 // define
 // the edit"s behavior.
 public SampleUndoableEdit(int number, boolean allowAdds,
     boolean isSignificant, boolean isReplacer) {
   this.number = number;
   this.allowAdds = allowAdds;
   if (allowAdds)
     addedEdits = new Vector();
   this.isSignificant = isSignificant;
   this.isReplacer = isReplacer;
 }
 // "Undo" the edit by printing a message to the screen.
 public void undo() throws CannotUndoException {
   super.undo();
   System.out.print("Undo " + number);
   dumpState();
 }
 // "Redo" the edit by printing a message to the screen.
 public void redo() throws CannotRedoException {
   super.redo();
   System.out.print("Redo " + number);
   dumpState();
 }
 // If allowAdds is true, we store the input edit. If not, just return false.
 public boolean addEdit(UndoableEdit anEdit) {
   if (allowAdds) {
     addedEdits.addElement(anEdit);
     return true;
   } else
     return false;
 }
 // If isReplacer is true, we store the edit we are replacing.
 public boolean replaceEdit(UndoableEdit anEdit) {
   if (isReplacer) {
     replaced = anEdit;
     return true;
   } else
     return false;
 }
 // Significance is based on constructor parameter.
 public boolean isSignificant() {
   return isSignificant;
 }
 // Just return our identifier.
 public String toString() {
   return "<" + number + ">";
 }
 // Debug output.
 public void dumpState() {
   if (allowAdds && addedEdits.size() > 0) {
     Enumeration e = addedEdits.elements();
     System.out.print(" (absorbed: ");
     while (e.hasMoreElements()) {
       System.out.print(e.nextElement());
     }
     System.out.print(")");
   }
   if (isReplacer && replaced != null) {
     System.out.print(" (replaced: " + replaced + ")");
   }
   System.out.println();
 }

}


 </source>
   
  
 
  



A sample app showing the use of UndoableToggleEdit and CompoundEdit

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoableToggleApp2.java //A sample app showing the use of UndoableToggleEdit and CompoundEdit. // import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JToggleButton; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.rupoundEdit; import javax.swing.undo.UndoableEdit; public class UndoableToggleApp2 extends JFrame {

 private CompoundEdit edit;
 private JButton undoButton;
 private JButton redoButton;
 private JButton endButton;
 // Create the main frame and everything in it.
 public UndoableToggleApp2() {
   // Create some toggle buttons (and subclasses)
   JToggleButton tog = new JToggleButton("ToggleButton");
   JCheckBox cb = new JCheckBox("CompoundEdit ExampleCheckBox");
   JRadioButton radio = new JRadioButton("RadioButton");
   // Add our listener to each toggle button
   SimpleListener sl = new SimpleListener();
   tog.addActionListener(sl);
   cb.addActionListener(sl);
   radio.addActionListener(sl);
   // Lay out the buttons
   Box buttonBox = new Box(BoxLayout.Y_AXIS);
   buttonBox.add(tog);
   buttonBox.add(cb);
   buttonBox.add(radio);
   // Create undo and redo buttons (initially disabled)
   undoButton = new JButton("Undo");
   redoButton = new JButton("Redo");
   endButton = new JButton("End");
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   endButton.setEnabled(false);
   // Add a listener to the undo button. It attempts to call undo() on the
   // current edit, then enables/disables the undo/redo buttons as
   // appropriate.
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.undo();
       } catch (CannotUndoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Add a redo listener: just like the undo listener, but for redo this
   // time.
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.redo();
       } catch (CannotRedoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Add an end listener. This listener will call end() on the
   // CompoundEdit
   // and update the undo/redo buttons.
   endButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       edit.end();
       endButton.setEnabled(false);
       undoButton.setEnabled(edit.canUndo());
       redoButton.setEnabled(edit.canRedo());
     }
   });
   // Layout the undo/redo/end buttons
   Box undoRedoEndBox = new Box(BoxLayout.X_AXIS);
   undoRedoEndBox.add(Box.createGlue());
   undoRedoEndBox.add(undoButton);
   undoRedoEndBox.add(Box.createHorizontalStrut(2));
   undoRedoEndBox.add(redoButton);
   undoRedoEndBox.add(Box.createHorizontalStrut(2));
   undoRedoEndBox.add(endButton);
   undoRedoEndBox.add(Box.createGlue());
   // Layout the main frame
   Container content = getContentPane();
   content.setLayout(new BorderLayout());
   content.add(buttonBox, BorderLayout.CENTER);
   content.add(undoRedoEndBox, BorderLayout.SOUTH);
   setSize(400, 150);
 }
 public class SimpleListener implements ActionListener {
   public void actionPerformed(ActionEvent ev) {
     if (edit == null || edit.isInProgress() == false)
       edit = new CompoundEdit();
     JToggleButton tb = (JToggleButton) ev.getSource();
     UndoableEdit togEdit = new UndoableToggleEdit(tb);
     edit.addEdit(togEdit);
     endButton.setEnabled(true);
     undoButton.setEnabled(edit.canUndo());
     redoButton.setEnabled(edit.canRedo());
   }
 }
 // Main program just creates the frame and displays it.
 public static void main(String[] args) {
   JFrame f = new UndoableToggleApp2();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

} //UndoableToggleEdit.java //An UndoableEdit used to undo the pressing of a JToggleButton. // class UndoableToggleEdit extends AbstractUndoableEdit {

 private JToggleButton button;
 private boolean selected;
 // Create a new edit for a JToggleButton that has just been toggled.
 public UndoableToggleEdit(JToggleButton button) {
   this.button = button;
   selected = button.isSelected();
 }
 // Return a reasonable name for this edit.
 public String getPresentationName() {
   return "Toggle " + button.getText() + " " + (selected ? "on" : "off");
 }
 // Redo by setting the button state as it was initially.
 public void redo() throws CannotRedoException {
   super.redo();
   button.setSelected(selected);
 }
 // Undo by setting the button state to the opposite value.
 public void undo() throws CannotUndoException {
   super.undo();
   button.setSelected(!selected);
 }

}


 </source>
   
  
 
  



Bind the undo action to ctl-Z

   <source lang="java">
 

import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class Main {

 public static void main(String[] argv) {
   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   doc.addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       undo.addEdit(evt.getEdit());
     }
   });
   textcomp.getActionMap().put("Undo", new AbstractAction("Undo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canUndo()) {
           undo.undo();
         }
       } catch (CannotUndoException e) {
       }
     }
   });
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo");
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(textcomp));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Create an undo action and add it to the text component

   <source lang="java">
 

import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class Main {

 public static void main(String[] argv) {
   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   doc.addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       undo.addEdit(evt.getEdit());
     }
   });
   textcomp.getActionMap().put("Undo", new AbstractAction("Undo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canUndo()) {
           undo.undo();
         }
       } catch (CannotUndoException e) {
       }
     }
   });
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(textcomp));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Create a redo action and add it to the text component (JTextComponent)

   <source lang="java">
 

import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class Main {

 public static void main(String[] argv) {
   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   doc.addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       undo.addEdit(evt.getEdit());
     }
   });
   textcomp.getActionMap().put("Undo", new AbstractAction("Undo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canUndo()) {
           undo.undo();
         }
       } catch (CannotUndoException e) {
       }
     }
   });
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "Undo");
   textcomp.getActionMap().put("Redo", new AbstractAction("Redo") {
     public void actionPerformed(ActionEvent evt) {
       try {
         if (undo.canRedo()) {
           undo.redo();
         }
       } catch (CannotRedoException e) {
       }
     }
   });
   textcomp.getInputMap().put(KeyStroke.getKeyStroke("control Y"), "Redo");
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(textcomp));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}


 </source>
   
  
 
  



Creating TextArea with Undo, Redo Capabilities

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; class UndoableTextArea extends JTextArea implements UndoableEditListener, FocusListener,

   KeyListener {
 private UndoManager m_undoManager;
 public UndoableTextArea() {
   this(new String());
 }
 public UndoableTextArea(String text) {
   super(text);
   getDocument().addUndoableEditListener(this);
   this.addKeyListener(this);
   this.addFocusListener(this);
 }
 private void createUndoMananger() {
   m_undoManager = new UndoManager();
   m_undoManager.setLimit(10);
 }
 private void removeUndoMananger() {
   m_undoManager.end();
 }
 public void focusGained(FocusEvent fe) {
   createUndoMananger();
 }
 public void focusLost(FocusEvent fe) {
   removeUndoMananger();
 }
 public void undoableEditHappened(UndoableEditEvent e) {
   m_undoManager.addEdit(e.getEdit());
 }
 public void keyPressed(KeyEvent e) {
   if ((e.getKeyCode() == KeyEvent.VK_Z) && (e.isControlDown())) {
     try {
       m_undoManager.undo();
     } catch (CannotUndoException cue) {
       Toolkit.getDefaultToolkit().beep();
     }
   }
   if ((e.getKeyCode() == KeyEvent.VK_Y) && (e.isControlDown())) {
     try {
       m_undoManager.redo();
     } catch (CannotRedoException cue) {
       Toolkit.getDefaultToolkit().beep();
     }
   }
 }
 public void keyReleased(KeyEvent e) {
 }
 public void keyTyped(KeyEvent e) {
 }

} public class Main extends JFrame {

 UndoableTextArea m_undoableTextArea = new UndoableTextArea();
 public Main() {
   JScrollPane sc = new JScrollPane(m_undoableTextArea);
   getContentPane().setLayout(new BorderLayout(10, 10));
   getContentPane()
       .add(BorderLayout.NORTH, new JLabel("Press, CTRL+Z to Undo, CTRL+Y to Redo..."));
   getContentPane().add(BorderLayout.CENTER, sc);
 }
 public static void main(String[] arg) {
   Main m = new Main();
   m.setVisible(true);
   m.setSize(new Dimension(400, 300));
   m.validate();
 }

}


 </source>
   
  
 
  



Listen for undo and redo events

   <source lang="java">
 

public class Main{ public static void main(String[] argv){

   JTextComponent textcomp = new JTextArea();
   final UndoManager undo = new UndoManager();
   Document doc = textcomp.getDocument();
   
   doc.addUndoableEditListener(new UndoableEditListener() {
       public void undoableEditHappened(UndoableEditEvent evt) {
           undo.addEdit(evt.getEdit());
       }
   });    
   JFrame frame = new JFrame();
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new JScrollPane(textcomp));
   frame.setSize(380, 320);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);

}}


 </source>
   
  
 
  



Simple GUI demo of UndoManager and friends

   <source lang="java">

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.undo.UndoManager; /**

* Simple GUI demo of UndoManager and friends.
* 
* @author Ian Darwin http://www.darwinsys.ru/
*/

public class UndoDemo extends JFrame {

 JTextArea ta;
 UndoManager um;
 /** Simple main program that just constructs and shows the GUI */
 public static void main(String[] files) {
   new UndoDemo().setVisible(true);
 }
 /** Construct a GUI that demonstrates use of UndoManager */
 public UndoDemo() {
   Container cp = getContentPane();
   cp.add(ta = new JTextArea(20, 60), BorderLayout.CENTER);
   JPanel bp;
   cp.add(bp = new JPanel(), BorderLayout.SOUTH);
   // Create a javax.swing.undo.UndoManager; this is an amazing class that
   // keeps a Stack of UndoableEdits and lets you invoke them;
   // by registering it as a Listener on the TextComponent.Document,
   // the Document will create the UndoableEdit objects and send them
   // to the UndoManager. Between them they do ALL the work!
   um = new UndoManager();
   ta.getDocument().addUndoableEditListener(um);
   // Create the buttons
   JButton cutButton, copyButton, pasteButton, undoButton, redoButton;
   bp.add(cutButton = new JButton("Cut"));
   cutButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       ta.cut();
     }
   });
   bp.add(copyButton = new JButton("Copy"));
   copyButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       ta.copy();
     }
   });
   bp.add(pasteButton = new JButton("Paste"));
   pasteButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       ta.paste();
     }
   });
   bp.add(undoButton = new JButton("UnDo"));
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       if (um.canUndo()) {
         um.undo();
       } else {
         warn("Can"t undo");
       }
     }
   });
   bp.add(redoButton = new JButton("ReDo"));
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       if (um.canRedo()) {
         um.redo();
       } else {
         warn("Can"t redo");
       }
     }
   });
   pack();
   setDefaultCloseOperation(EXIT_ON_CLOSE);
 }
 void warn(String msg) {
   JOptionPane.showMessageDialog(this, "Warning: " + msg, "Warning",
       JOptionPane.WARNING_MESSAGE);
 }

}


 </source>
   
  
 
  



The use of StateEdit(able)

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoableToggleApp4.java //A sample app showing the use of StateEdit(able). // import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Hashtable; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JToggleButton; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.StateEdit; import javax.swing.undo.StateEditable; public class UndoableToggleApp4 extends JFrame implements StateEditable {

 private JToggleButton tog;
 private JCheckBox cb;
 private JRadioButton radio;
 private JButton undoButton;
 private JButton redoButton;
 private JButton startButton;
 private JButton endButton;
 private StateEdit edit;
 // Create the main frame and everything in it.
 public UndoableToggleApp4() {
   // Create some toggle buttons (and subclasses).
   tog = new JToggleButton("ToggleButton");
   cb = new JCheckBox("CheckBox");
   radio = new JRadioButton("RadioButton");
   // Add our listener to the buttons.
   SimpleListener sl = new SimpleListener();
   tog.addActionListener(sl);
   cb.addActionListener(sl);
   radio.addActionListener(sl);
   // Lay out the buttons.
   Box buttonBox = new Box(BoxLayout.Y_AXIS);
   buttonBox.add(tog);
   buttonBox.add(cb);
   buttonBox.add(radio);
   // Create undo, redo, start, and end buttons.
   startButton = new JButton("Start");
   endButton = new JButton("End");
   undoButton = new JButton("Undo");
   redoButton = new JButton("Redo");
   startButton.setEnabled(true);
   endButton.setEnabled(false);
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   // Add a listener to the start button. It creates a new StateEdit,
   // passing in this frame as the StateEditable.
   startButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       edit = new StateEdit(UndoableToggleApp4.this);
       startButton.setEnabled(false);
       endButton.setEnabled(true);
       //undoButton.setEnabled(edit.canUndo());
       //
       // NOTE: We really don"t want to be able to undo until end() is
       // pressed,
       // but StateEdit does not enforce this for us!
       undoButton.setEnabled(false);
       redoButton.setEnabled(edit.canRedo());
     }
   });
   // Add a listener to the end button. It will call end() on the
   // StateEdit.
   endButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       edit.end();
       startButton.setEnabled(true);
       endButton.setEnabled(false);
       undoButton.setEnabled(edit.canUndo());
       redoButton.setEnabled(edit.canRedo());
     }
   });
   // Add a listener to the undo button. It attempts to call undo() on the
   // current edit, then enables/disables the undo/redo buttons as
   // appropriate.
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.undo();
       } catch (CannotUndoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Add a redo listener: just like the undo listener.
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.redo();
       } catch (CannotRedoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Lay out the state/end and undo/redo buttons.
   Box undoRedoBox = new Box(BoxLayout.X_AXIS);
   undoRedoBox.add(Box.createGlue());
   undoRedoBox.add(startButton);
   undoRedoBox.add(Box.createHorizontalStrut(2));
   undoRedoBox.add(endButton);
   undoRedoBox.add(Box.createHorizontalStrut(2));
   undoRedoBox.add(undoButton);
   undoRedoBox.add(Box.createHorizontalStrut(2));
   undoRedoBox.add(redoButton);
   undoRedoBox.add(Box.createGlue());
   // Lay out the main frame.
   Container content = getContentPane();
   content.setLayout(new BorderLayout());
   content.add(buttonBox, BorderLayout.CENTER);
   content.add(undoRedoBox, BorderLayout.SOUTH);
   setSize(400, 150);
 }
 public class SimpleListener implements ActionListener {
   // When any toggle button is clicked, we turn off the undo and redo
   // buttons, reflecting the fact that we can only undo/redo the last
   // set of state changes as long as no additional changes have been made.
   public void actionPerformed(ActionEvent ev) {
     undoButton.setEnabled(false);
     redoButton.setEnabled(false);
   }
 }
 // Save the state of the app by storing the current state of the three
 // buttons. We"ll use the buttons themselves as keys and their selected
 // state as values.
 public void storeState(Hashtable ht) {
   ht.put(tog, new Boolean(tog.isSelected()));
   ht.put(cb, new Boolean(cb.isSelected()));
   ht.put(radio, new Boolean(radio.isSelected()));
 }
 // Restore state based on the values we saved when storeState() was called.
 // Note that StateEdit discards any state info that did not change from
 // between the start state and the end state, so we can"t assume that the
 // state for all 3 buttons is in the Hashtable.
 public void restoreState(Hashtable ht) {
   Boolean b1 = (Boolean) ht.get(tog);
   if (b1 != null)
     tog.setSelected(b1.booleanValue());
   Boolean b2 = (Boolean) ht.get(cb);
   if (b2 != null)
     cb.setSelected(b2.booleanValue());
   Boolean b3 = (Boolean) ht.get(radio);
   if (b3 != null)
     radio.setSelected(b3.booleanValue());
 }
 // Main program just creates the frame and displays it.
 public static void main(String[] args) {
   JFrame f = new UndoableToggleApp4();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

}


 </source>
   
  
 
  



The use of UndoableToggleEdit

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoableToggleApp.java //A sample app showing the use of UndoableToggleEdit. // import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JToggleButton; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoableEdit; public class UndoableToggleApp extends JFrame {

 private UndoableEdit edit;
 private JButton undoButton;
 private JButton redoButton;
 // Create the main frame and everything in it.
 public UndoableToggleApp() {
   // Create some toggle buttons (and subclasses)
   JToggleButton tog = new JToggleButton("ToggleButton");
   JCheckBox cb = new JCheckBox("CheckBox");
   JRadioButton radio = new JRadioButton("RadioButton");
   // Add our listener to each toggle button
   SimpleListener sl = new SimpleListener();
   tog.addActionListener(sl);
   cb.addActionListener(sl);
   radio.addActionListener(sl);
   // Layout the buttons
   Box buttonBox = new Box(BoxLayout.Y_AXIS);
   buttonBox.add(tog);
   buttonBox.add(cb);
   buttonBox.add(radio);
   // Create undo and redo buttons (initially disabled)
   undoButton = new JButton("Undo");
   redoButton = new JButton("Redo");
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   // Add a listener to the undo button. It attempts to call undo() on the
   // current edit, then enables/disables the undo/redo buttons as
   // appropriate.
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.undo();
       } catch (CannotUndoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Add a redo listener: just like the undo listener, but for redo this
   // time.
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         edit.redo();
       } catch (CannotRedoException ex) {
         ex.printStackTrace();
       } finally {
         undoButton.setEnabled(edit.canUndo());
         redoButton.setEnabled(edit.canRedo());
       }
     }
   });
   // Layout the undo/redo buttons
   Box undoRedoBox = new Box(BoxLayout.X_AXIS);
   undoRedoBox.add(Box.createGlue());
   undoRedoBox.add(undoButton);
   undoRedoBox.add(Box.createHorizontalStrut(2));
   undoRedoBox.add(redoButton);
   undoRedoBox.add(Box.createGlue());
   // Layout the main frame
   Container content = getContentPane();
   content.setLayout(new BorderLayout());
   content.add(buttonBox, BorderLayout.CENTER);
   content.add(undoRedoBox, BorderLayout.SOUTH);
   setSize(400, 150);
 }
 public class SimpleListener implements ActionListener {
   // When a toggle button is clicked, we create a new UndoableToggleEdit
   // (which replaces any previous edit). We then get the edit"s undo/redo
   // names and set the undo/redo button labels. Finally, we
   // enable/disable these buttons by asking the edit what we are
   // allowed to do.
   public void actionPerformed(ActionEvent ev) {
     JToggleButton tb = (JToggleButton) ev.getSource();
     edit = new UndoableToggleEdit(tb);
     undoButton.setText(edit.getUndoPresentationName());
     redoButton.setText(edit.getRedoPresentationName());
     undoButton.getParent().validate();
     undoButton.setEnabled(edit.canUndo());
     redoButton.setEnabled(edit.canRedo());
   }
 }
 // Main program just creates the frame and displays it.
 public static void main(String[] args) {
   JFrame f = new UndoableToggleApp();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

} //UndoableToggleEdit.java //An UndoableEdit used to undo the pressing of a JToggleButton. // class UndoableToggleEdit extends AbstractUndoableEdit {

 private JToggleButton button;
 private boolean selected;
 // Create a new edit for a JToggleButton that has just been toggled.
 public UndoableToggleEdit(JToggleButton button) {
   this.button = button;
   selected = button.isSelected();
 }
 // Return a reasonable name for this edit.
 public String getPresentationName() {
   return "Toggle " + button.getText() + " " + (selected ? "on" : "off");
 }
 // Redo by setting the button state as it was initially.
 public void redo() throws CannotRedoException {
   super.redo();
   button.setSelected(selected);
 }
 // Undo by setting the button state to the opposite value.
 public void undo() throws CannotUndoException {
   super.undo();
   button.setSelected(!selected);
 }

}


 </source>
   
  
 
  



The use of UndoManager

   <source lang="java">

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// UndoableToggleApp3.java //A sample app showing the use of UndoManager. // import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JToggleButton; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class UndoableToggleApp3 extends JFrame {

 private UndoManager manager = new UndoManager();
 private JButton undoButton;
 private JButton redoButton;
 // Create the main frame and everything in it.
 public UndoableToggleApp3() {
   // Create some toggle buttons.
   UndoableJToggleButton tog1 = new UndoableJToggleButton("One");
   UndoableJToggleButton tog2 = new UndoableJToggleButton("Two");
   UndoableJToggleButton tog3 = new UndoableJToggleButton("Three");
   // Add our listener to each toggle button.
   SimpleUEListener sl = new SimpleUEListener();
   tog1.addUndoableEditListener(sl);
   tog2.addUndoableEditListener(sl);
   tog3.addUndoableEditListener(sl);
   // Lay out the buttons.
   Box buttonBox = new Box(BoxLayout.Y_AXIS);
   buttonBox.add(tog1);
   buttonBox.add(tog2);
   buttonBox.add(tog3);
   // Create undo and redo buttons (initially disabled).
   undoButton = new JButton("Undo");
   redoButton = new JButton("Redo");
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   // Add a listener to the undo button. It attempts to call undo() on the
   // UndoManager, then enables/disables the undo/redo buttons as
   // appropriate.
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         manager.undo();
       } catch (CannotUndoException ex) {
         ex.printStackTrace();
       } finally {
         updateButtons();
       }
     }
   });
   // Add a redo listener: just like the undo listener.
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent ev) {
       try {
         manager.redo();
       } catch (CannotRedoException ex) {
         ex.printStackTrace();
       } finally {
         updateButtons();
       }
     }
   });
   // Lay out the undo/redo buttons.
   Box undoRedoBox = new Box(BoxLayout.X_AXIS);
   undoRedoBox.add(Box.createGlue());
   undoRedoBox.add(undoButton);
   undoRedoBox.add(Box.createHorizontalStrut(2));
   undoRedoBox.add(redoButton);
   undoRedoBox.add(Box.createGlue());
   // Lay out the main frame.
   getContentPane().setLayout(new BorderLayout());
   getContentPane().add(buttonBox, BorderLayout.CENTER);
   getContentPane().add(undoRedoBox, BorderLayout.SOUTH);
   setSize(400, 150);
 }
 public class SimpleUEListener implements UndoableEditListener {
   // When an UndoableEditEvent is generated (each time one of the buttons
   // is pressed), we add it to the UndoManager and then get the manager"s
   // undo/redo names and set the undo/redo button labels. Finally, we
   // enable/disable these buttons by asking the manager what we are
   // allowed to do.
   public void undoableEditHappened(UndoableEditEvent ev) {
     manager.addEdit(ev.getEdit());
     updateButtons();
   }
 }
 // Method to set the text and state of the undo/redo buttons.
 protected void updateButtons() {
   undoButton.setText(manager.getUndoPresentationName());
   redoButton.setText(manager.getRedoPresentationName());
   undoButton.getParent().validate();
   undoButton.setEnabled(manager.canUndo());
   redoButton.setEnabled(manager.canRedo());
 }
 // Main program just creates the frame and displays it.
 public static void main(String[] args) {
   JFrame f = new UndoableToggleApp3();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

} //UndoableJToggleButton.java //Sample undoable toggle button class. Supports only a single listener to //simplify the code. // class UndoableJToggleButton extends JToggleButton {

 private UndoableEditListener listener;
 // For this example, we"ll just provide one constructor . . .
 public UndoableJToggleButton(String txt) {
   super(txt);
 }
 // Set the UndoableEditListener.
 public void addUndoableEditListener(UndoableEditListener l) {
   listener = l; // Should ideally throw an exception if listener != null
 }
 // Remove the UndoableEditListener.
 public void removeUndoableEditListener(UndoableEditListener l) {
   listener = null;
 }
 // We override this method to call the super implementation first (to fire
 // the
 // action event) and then fire a new UndoableEditEvent to our listener.
 protected void fireActionPerformed(ActionEvent ev) {
   // Fire the ActionEvent as usual.
   super.fireActionPerformed(ev);
   if (listener != null) {
     listener.undoableEditHappened(new UndoableEditEvent(this,
         new UndoableToggleEdit(this)));
   }
 }

} //UndoableToggleEdit.java //An UndoableEdit used to undo the pressing of a JToggleButton. // class UndoableToggleEdit extends AbstractUndoableEdit {

 private JToggleButton button;
 private boolean selected;
 // Create a new edit for a JToggleButton that has just been toggled.
 public UndoableToggleEdit(JToggleButton button) {
   this.button = button;
   selected = button.isSelected();
 }
 // Return a reasonable name for this edit.
 public String getPresentationName() {
   return "Toggle " + button.getText() + " " + (selected ? "on" : "off");
 }
 // Redo by setting the button state as it was initially.
 public void redo() throws CannotRedoException {
   super.redo();
   button.setSelected(selected);
 }
 // Undo by setting the button state to the opposite value.
 public void undo() throws CannotUndoException {
   super.undo();
   button.setSelected(!selected);
 }

}


 </source>
   
  
 
  



Undoable Drawing Panel 2

   <source lang="java">

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.Graphics; import java.awt.Polygon; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.StateEdit; import javax.swing.undo.StateEditable; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEditSupport; public class UndoableDrawingPanel2 extends JPanel implements StateEditable {

 private static String POLYGON_KEY = "Polygon";
 UndoableEditSupport undoableEditSupport = new UndoableEditSupport(this);
 Polygon polygon = new Polygon();
 public UndoableDrawingPanel2() {
   MouseListener mouseListener = new MouseAdapter() {
     public void mouseReleased(MouseEvent mouseEvent) {
       StateEdit stateEdit = new StateEdit(UndoableDrawingPanel2.this);
       polygon.addPoint(mouseEvent.getX(), mouseEvent.getY());
       stateEdit.end();
       undoableEditSupport.postEdit(stateEdit);
       repaint();
     }
   };
   addMouseListener(mouseListener);
 }
 public void addUndoableEditListener(
     UndoableEditListener undoableEditListener) {
   undoableEditSupport.addUndoableEditListener(undoableEditListener);
 }
 public void removeUndoableEditListener(
     UndoableEditListener undoableEditListener) {
   undoableEditSupport.removeUndoableEditListener(undoableEditListener);
 }
 public void storeState(Hashtable state) {
   state.put(POLYGON_KEY, getPolygon());
 }
 public void restoreState(Hashtable state) {
   Polygon polygon = (Polygon) state.get(POLYGON_KEY);
   if (polygon != null) {
     setPolygon(polygon);
   }
 }
 public void setPolygon(Polygon newValue) {
   polygon = newValue;
   repaint();
 }
 public Polygon getPolygon() {
   Polygon returnValue;
   if (polygon.npoints == 0) {
     returnValue = new Polygon();
   } else {
     returnValue = new Polygon(polygon.xpoints, polygon.ypoints,
         polygon.npoints);
   }
   return returnValue;
 }
 protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   g.drawPolygon(polygon);
 }
 public static void main(String args[]) {
   JFrame frame = new JFrame("Drawing Sample2");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   UndoableDrawingPanel2 drawingPanel = new UndoableDrawingPanel2();
   UndoManager manager = new UndoManager();
   drawingPanel.addUndoableEditListener(manager);
   JToolBar toolbar = new JToolBar();
   toolbar.add(UndoManagerHelper.getUndoAction(manager));
   toolbar.add(UndoManagerHelper.getRedoAction(manager));
   Container content = frame.getContentPane();
   content.add(toolbar, BorderLayout.NORTH);
   content.add(drawingPanel, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

} class UndoManagerHelper {

 public static Action getUndoAction(UndoManager manager, String label) {
   return new UndoAction(manager, label);
 }
 public static Action getUndoAction(UndoManager manager) {
   return new UndoAction(manager, "Undo");
 }
 public static Action getRedoAction(UndoManager manager, String label) {
   return new RedoAction(manager, label);
 }
 public static Action getRedoAction(UndoManager manager) {
   return new RedoAction(manager, "Redo");
 }
 private abstract static class UndoRedoAction extends AbstractAction {
   UndoManager undoManager = new UndoManager();
   String errorMessage = "Cannot undo";
   String errorTitle = "Undo Problem";
   protected UndoRedoAction(UndoManager manager, String name) {
     super(name);
     undoManager = manager;
   }
   public void setErrorMessage(String newValue) {
     errorMessage = newValue;
   }
   public void setErrorTitle(String newValue) {
     errorTitle = newValue;
   }
   protected void showMessage(Object source) {
     if (source instanceof Component) {
       JOptionPane.showMessageDialog((Component) source, errorMessage,
           errorTitle, JOptionPane.WARNING_MESSAGE);
     } else {
       System.err.println(errorMessage);
     }
   }
 }
 public static class UndoAction extends UndoRedoAction {
   public UndoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot undo");
     setErrorTitle("Undo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.undo();
     } catch (CannotUndoException cannotUndoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }
 public static class RedoAction extends UndoRedoAction {
   String errorMessage = "Cannot redo";
   String errorTitle = "Redo Problem";
   public RedoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot redo");
     setErrorTitle("Redo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.redo();
     } catch (CannotRedoException cannotRedoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }

}


 </source>
   
  
 
  



Undo Drawing

   <source lang="java">

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.Graphics; import java.awt.Polygon; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.event.UndoableEditListener; 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 UndoDrawing {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Drawing Sample");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   UndoableDrawingPanel drawingPanel = new UndoableDrawingPanel();
   UndoManager manager = new UndoManager();
   drawingPanel.addUndoableEditListener(manager);
   JToolBar toolbar = new JToolBar();
   toolbar.add(UndoManagerHelper.getUndoAction(manager));
   toolbar.add(UndoManagerHelper.getRedoAction(manager));
   Container content = frame.getContentPane();
   content.add(toolbar, BorderLayout.NORTH);
   content.add(drawingPanel, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

} class UndoableDrawingPanel extends JPanel {

 UndoableEditSupport undoableEditSupport = new UndoableEditSupport(this);
 Polygon polygon = new Polygon();
 public UndoableDrawingPanel() {
   MouseListener mouseListener = new MouseAdapter() {
     public void mouseReleased(MouseEvent mouseEvent) {
       undoableEditSupport.postEdit(new UndoableDrawEdit(
           UndoableDrawingPanel.this));
       polygon.addPoint(mouseEvent.getX(), mouseEvent.getY());
       repaint();
     }
   };
   addMouseListener(mouseListener);
 }
 public void addUndoableEditListener(
     UndoableEditListener undoableEditListener) {
   undoableEditSupport.addUndoableEditListener(undoableEditListener);
 }
 public void removeUndoableEditListener(
     UndoableEditListener undoableEditListener) {
   undoableEditSupport.removeUndoableEditListener(undoableEditListener);
 }
 public void setPolygon(Polygon newValue) {
   polygon = newValue;
   repaint();
 }
 public Polygon getPolygon() {
   Polygon returnValue;
   if (polygon.npoints == 0) {
     returnValue = new Polygon();
   } else {
     returnValue = new Polygon(polygon.xpoints, polygon.ypoints,
         polygon.npoints);
   }
   return returnValue;
 }
 protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   g.drawPolygon(polygon);
 }

} class UndoManagerHelper {

 public static Action getUndoAction(UndoManager manager, String label) {
   return new UndoAction(manager, label);
 }
 public static Action getUndoAction(UndoManager manager) {
   return new UndoAction(manager, "Undo");
 }
 public static Action getRedoAction(UndoManager manager, String label) {
   return new RedoAction(manager, label);
 }
 public static Action getRedoAction(UndoManager manager) {
   return new RedoAction(manager, "Redo");
 }
 private abstract static class UndoRedoAction extends AbstractAction {
   UndoManager undoManager = new UndoManager();
   String errorMessage = "Cannot undo";
   String errorTitle = "Undo Problem";
   protected UndoRedoAction(UndoManager manager, String name) {
     super(name);
     undoManager = manager;
   }
   public void setErrorMessage(String newValue) {
     errorMessage = newValue;
   }
   public void setErrorTitle(String newValue) {
     errorTitle = newValue;
   }
   protected void showMessage(Object source) {
     if (source instanceof Component) {
       JOptionPane.showMessageDialog((Component) source, errorMessage,
           errorTitle, JOptionPane.WARNING_MESSAGE);
     } else {
       System.err.println(errorMessage);
     }
   }
 }
 public static class UndoAction extends UndoRedoAction {
   public UndoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot undo");
     setErrorTitle("Undo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.undo();
     } catch (CannotUndoException cannotUndoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }
 public static class RedoAction extends UndoRedoAction {
   String errorMessage = "Cannot redo";
   String errorTitle = "Redo Problem";
   public RedoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot redo");
     setErrorTitle("Redo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.redo();
     } catch (CannotRedoException cannotRedoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }

} class UndoableDrawEdit extends AbstractUndoableEdit {

 UndoableDrawingPanel panel;
 Polygon polygon, savedPolygon;
 public UndoableDrawEdit(UndoableDrawingPanel panel) {
   this.panel = panel;
   polygon = panel.getPolygon();
 }
 public String getPresentationName() {
   return "Polygon of size " + polygon.npoints;
 }
 public void redo() throws CannotRedoException {
   super.redo();
   if (savedPolygon == null) {
     // Should never get here, as super() doesn"t permit redoing
     throw new CannotRedoException();
   } else {
     panel.setPolygon(savedPolygon);
     savedPolygon = null;
   }
 }
 public void undo() throws CannotUndoException {
   super.undo();
   savedPolygon = panel.getPolygon();
   panel.setPolygon(polygon);
 }

}


 </source>
   
  
 
  



Undo Example 1

   <source lang="java">

/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall

  • /

import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.undo.*; public class UndoExample1 extends JFrame {

 public UndoExample1() {
   super("Undo/Redo Example 1");
 
   pane = new JTextPane();
   pane.setEditable(true);    // Editable
   getContentPane().add(new JScrollPane(pane), "Center");
   // Add a menu bar
   menuBar = new JMenuBar();
   setJMenuBar(menuBar);
   // Populate the menu bar
   createMenuBar();
 }
 public void createMenuBar() {
   // Remove the existing menu items
   int count = menuBar.getMenuCount();
   for (int i = 0; i < count; i++) {
     menuBar.remove(menuBar.getMenu(0));
   }
   // Build the new menu.
   Action[] actions = pane.getActions();
   Hashtable actionHash = new Hashtable();
   count = actions.length;
   for (int i = 0; i < count; i++) {
     actionHash.put(actions[i].getValue(Action.NAME), actions[i]);
   }
   // Add the font menu
   JMenu menu = MenuBuilder.buildMenu("Font", fontSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
   // Add the alignment menu
   menu = MenuBuilder.buildMenu("Align", alignSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
 }
 public static void main(String[] args) {
   try {
       UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   } catch (Exception evt) {}
 
   JFrame f = new UndoExample1();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent evt) {
       System.exit(0);
     }
   });
   f.setSize(250, 300);
   f.setVisible(true);
   // Create and show a frame monitoring undoable edits
   JFrame undoMonitor = new JFrame("Undo Monitor");
   final JTextArea textArea = new JTextArea();
   textArea.setEditable(false);
   undoMonitor.getContentPane().add(new JScrollPane(textArea));
   undoMonitor.setBounds(f.getLocation().x + f.getSize().width, 
             f.getLocation().y, 400, 200);
   undoMonitor.setVisible(true);
   pane.getDocument().addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       UndoableEdit edit = evt.getEdit();
       textArea.append(edit.getPresentationName() + "(" +
               edit.toString() + ")\n");
     }
   });
   
   // Create and show a frame monitoring document edits
   JFrame editMonitor = new JFrame("Edit Monitor");
   final JTextArea textArea2 = new JTextArea();
   textArea2.setEditable(false);
   editMonitor.getContentPane().add(new JScrollPane(textArea2));
   editMonitor.setBounds(undoMonitor.getLocation().x, 
         undoMonitor.getLocation().y + undoMonitor.getSize().height,
         400, 200);
   editMonitor.setVisible(true);
   pane.getDocument().addDocumentListener(new DocumentListener() {
     public void changedUpdate(DocumentEvent evt) {
       textArea2.append("Attribute change\n");
     }
     public void insertUpdate(DocumentEvent evt) {
       textArea2.append("Text insertion\n");
     }
     public void removeUpdate(DocumentEvent evt) {
       textArea2.append("Text removal\n");
     }
   });
 }
 private static JTextPane pane;
 private static JMenuBar menuBar;
 private static MenuSpec[] sizeSpec = new MenuSpec[] {
     new MenuSpec("Size 8",  "font-size-8"),
     new MenuSpec("Size 10", "font-size-10"),
     new MenuSpec("Size 12", "font-size-12"),
     new MenuSpec("Size 14", "font-size-14"),
     new MenuSpec("Size 16", "font-size-16"),
     new MenuSpec("Size 18", "font-size-18"),
     new MenuSpec("Size 24", "font-size-24"),
     new MenuSpec("Size 36", "font-size-36"),
     new MenuSpec("Size 48", "font-size-48")          
 };
 private static MenuSpec[] familySpec = new MenuSpec[] {
     new MenuSpec("Sans Serif", "font-family-SansSerif"),
     new MenuSpec("Monospaced", "font-family-Monospaced"),
     new MenuSpec("Serif", "font-family-Serif")
 };
 private static MenuSpec[] styleSpec = new MenuSpec[] {
     new MenuSpec("Bold", "font-bold"),
     new MenuSpec("Italics", "font-italic"),
     new MenuSpec("Underline", "font-underline")
 };
 // Menu definitions for fonts
 private static MenuSpec[] fontSpec = new MenuSpec[] {
     new MenuSpec("Size", sizeSpec),
     new MenuSpec("Family", familySpec),
     new MenuSpec("Style", styleSpec)
 };
 // Alignment
 private static MenuSpec[] alignSpec = new MenuSpec[] {
     new MenuSpec("Left", "left-justify"),
     new MenuSpec("Center", "center-justify"),
     new MenuSpec("Right", "right-justify")
 };

}

class MenuSpec {

 public MenuSpec(String name, MenuSpec[] subMenus) {
   this.name = name;
   this.subMenus = subMenus;
 }
 public MenuSpec(String name, String actionName) {
   this.name = name;
   this.actionName = actionName;
 }
 public MenuSpec(String name, Action action) {
   this.name = name;
   this.action = action;
 }
 public boolean isSubMenu() {
   return subMenus != null;
 }
 public boolean isAction() {
   return action != null;
 }
 public String getName() {
   return name;
 }
 public MenuSpec[] getSubMenus() {
   return subMenus;
 }
 public String getActionName() {
   return actionName;
 }
 public Action getAction() {
   return action;
 }
 private String name;
 private String actionName;
 private Action action;
 private MenuSpec[] subMenus;

}

class MenuBuilder {

 public static JMenu buildMenu(String name, MenuSpec[] menuSpecs,
     Hashtable actions) {
   int count = menuSpecs.length;
   JMenu menu = new JMenu(name);
   for (int i = 0; i < count; i++) {
     MenuSpec spec = menuSpecs[i];
     if (spec.isSubMenu()) {
       // Recurse to handle a sub menu
       JMenu subMenu = buildMenu(spec.getName(), spec.getSubMenus(),
           actions);
       if (subMenu != null) {
         menu.add(subMenu);
       }
     } else if (spec.isAction()) {
       // It"s an Action - add it directly to the menu
       menu.add(spec.getAction());
     } else {
       // It"s an action name - add it if possible
       String actionName = spec.getActionName();
       Action targetAction = (Action) actions.get(actionName);
       // Create the menu item
       JMenuItem menuItem = menu.add(spec.getName());
       if (targetAction != null) {
         // The editor kit knows the action
         menuItem.addActionListener(targetAction);
       } else {
         // Action not known - disable the menu item
         menuItem.setEnabled(false);
       }
     }
   }
   // Return null if nothing was added to the menu.
   if (menu.getMenuComponentCount() == 0) {
     menu = null;
   }
   return menu;
 }

}


 </source>
   
  
 
  



Undo Example 2

   <source lang="java">

/* 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 java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; public class UndoExample2 extends JFrame {

 public UndoExample2() {
   super("Undo/Redo Example 2");
   pane = new JTextPane();
   pane.setEditable(true); // Editable
   getContentPane().add(new JScrollPane(pane), BorderLayout.CENTER);
   // Add a menu bar
   menuBar = new JMenuBar();
   setJMenuBar(menuBar);
   // Populate the menu bar
   createMenuBar();
   // Create the undo manager and actions
   UndoManager manager = new UndoManager();
   pane.getDocument().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
   pane.registerKeyboardAction(undoAction, KeyStroke.getKeyStroke(
       KeyEvent.VK_Z, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
   pane.registerKeyboardAction(redoAction, KeyStroke.getKeyStroke(
       KeyEvent.VK_Y, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
 }
 public void createMenuBar() {
   // Remove the existing menu items
   int count = menuBar.getMenuCount();
   for (int i = 0; i < count; i++) {
     menuBar.remove(menuBar.getMenu(0));
   }
   // Build the new menu.
   Action[] actions = pane.getActions();
   Hashtable actionHash = new Hashtable();
   count = actions.length;
   for (int i = 0; i < count; i++) {
     actionHash.put(actions[i].getValue(Action.NAME), actions[i]);
   }
   // Add the font menu
   JMenu menu = MenuBuilder.buildMenu("Font", fontSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
   // Add the alignment menu
   menu = MenuBuilder.buildMenu("Align", alignSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
 }
 // 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 UndoExample2();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent evt) {
       System.exit(0);
     }
   });
   f.setSize(250, 300);
   f.setVisible(true);
   // Create and show a frame monitoring undoable edits
   JFrame undoMonitor = new JFrame("Undo Monitor");
   final JTextArea textArea = new JTextArea();
   textArea.setEditable(false);
   undoMonitor.getContentPane().add(new JScrollPane(textArea));
   undoMonitor.setBounds(f.getLocation().x + f.getSize().width, f
       .getLocation().y, 400, 200);
   undoMonitor.setVisible(true);
   pane.getDocument().addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       UndoableEdit edit = evt.getEdit();
       textArea.append(edit.getPresentationName() + "("
           + edit.toString() + ")\n");
     }
   });
   // Create and show a frame monitoring document edits
   JFrame editMonitor = new JFrame("Edit Monitor");
   final JTextArea textArea2 = new JTextArea();
   textArea2.setEditable(false);
   editMonitor.getContentPane().add(new JScrollPane(textArea2));
   editMonitor.setBounds(undoMonitor.getLocation().x, undoMonitor
       .getLocation().y
       + undoMonitor.getSize().height, 400, 200);
   editMonitor.setVisible(true);
   pane.getDocument().addDocumentListener(new DocumentListener() {
     public void changedUpdate(DocumentEvent evt) {
       textArea2.append("Attribute change\n");
     }
     public void insertUpdate(DocumentEvent evt) {
       textArea2.append("Text insertion\n");
     }
     public void removeUpdate(DocumentEvent evt) {
       textArea2.append("Text removal\n");
     }
   });
 }
 private static JTextPane pane;
 private static JMenuBar menuBar;
 private static MenuSpec[] sizeSpec = new MenuSpec[] {
     new MenuSpec("Size 8", "font-size-8"),
     new MenuSpec("Size 10", "font-size-10"),
     new MenuSpec("Size 12", "font-size-12"),
     new MenuSpec("Size 14", "font-size-14"),
     new MenuSpec("Size 16", "font-size-16"),
     new MenuSpec("Size 18", "font-size-18"),
     new MenuSpec("Size 24", "font-size-24"),
     new MenuSpec("Size 36", "font-size-36"),
     new MenuSpec("Size 48", "font-size-48") };
 private static MenuSpec[] familySpec = new MenuSpec[] {
     new MenuSpec("Sans Serif", "font-family-SansSerif"),
     new MenuSpec("Monospaced", "font-family-Monospaced"),
     new MenuSpec("Serif", "font-family-Serif") };
 private static MenuSpec[] styleSpec = new MenuSpec[] {
     new MenuSpec("Bold", "font-bold"),
     new MenuSpec("Italics", "font-italic"),
     new MenuSpec("Underline", "font-underline") };
 // Menu definitions for fonts
 private static MenuSpec[] fontSpec = new MenuSpec[] {
     new MenuSpec("Size", sizeSpec), new MenuSpec("Family", familySpec),
     new MenuSpec("Style", styleSpec) };
 // Alignment
 private static MenuSpec[] alignSpec = new MenuSpec[] {
     new MenuSpec("Left", "left-justify"),
     new MenuSpec("Center", "center-justify"),
     new MenuSpec("Right", "right-justify") };

} class MenuSpec {

 public MenuSpec(String name, MenuSpec[] subMenus) {
   this.name = name;
   this.subMenus = subMenus;
 }
 public MenuSpec(String name, String actionName) {
   this.name = name;
   this.actionName = actionName;
 }
 public MenuSpec(String name, Action action) {
   this.name = name;
   this.action = action;
 }
 public boolean isSubMenu() {
   return subMenus != null;
 }
 public boolean isAction() {
   return action != null;
 }
 public String getName() {
   return name;
 }
 public MenuSpec[] getSubMenus() {
   return subMenus;
 }
 public String getActionName() {
   return actionName;
 }
 public Action getAction() {
   return action;
 }
 private String name;
 private String actionName;
 private Action action;
 private MenuSpec[] subMenus;

} class MenuBuilder {

 public static JMenu buildMenu(String name, MenuSpec[] menuSpecs,
     Hashtable actions) {
   int count = menuSpecs.length;
   JMenu menu = new JMenu(name);
   for (int i = 0; i < count; i++) {
     MenuSpec spec = menuSpecs[i];
     if (spec.isSubMenu()) {
       // Recurse to handle a sub menu
       JMenu subMenu = buildMenu(spec.getName(), spec.getSubMenus(),
           actions);
       if (subMenu != null) {
         menu.add(subMenu);
       }
     } else if (spec.isAction()) {
       // It"s an Action - add it directly to the menu
       menu.add(spec.getAction());
     } else {
       // It"s an action name - add it if possible
       String actionName = spec.getActionName();
       Action targetAction = (Action) actions.get(actionName);
       // Create the menu item
       JMenuItem menuItem = menu.add(spec.getName());
       if (targetAction != null) {
         // The editor kit knows the action
         menuItem.addActionListener(targetAction);
       } else {
         // Action not known - disable the menu item
         menuItem.setEnabled(false);
       }
     }
   }
   // Return null if nothing was added to the menu.
   if (menu.getMenuComponentCount() == 0) {
     menu = null;
   }
   return menu;
 }

}


 </source>
   
  
 
  



Undo Example 3

   <source lang="java">

/* 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);

}


 </source>
   
  
 
  



Undo Example 4

   <source lang="java">

/* 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 UndoExample4 extends JFrame {

 public UndoExample4() {
   super("Undo/Redo Example 4");
   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"));
   UndoableTree2 tree = new UndoableTree2(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 UndoExample4();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent evt) {
       System.exit(0);
     }
   });
   f.pack();
   f.setVisible(true);
 }

} class UndoableTree2 extends JTree {

 public UndoableTree2(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);
   TreePath[] selections = getSelectionPaths();
   super.collapsePath(path);
   boolean isExpanded = isExpanded(path);
   if (isExpanded != wasExpanded) {
     TreePath[] newSelections = getSelectionPaths();
     support.beginUpdate();
     support.postEdit(new SelectionEdit(selections, newSelections));
     support.postEdit(new CollapseEdit(path));
     support.endUpdate();
   }
 }
 public void expandPath(TreePath path) {
   boolean wasExpanded = isExpanded(path);
   TreePath[] selections = getSelectionPaths();
   super.expandPath(path);
   boolean isExpanded = isExpanded(path);
   if (isExpanded != wasExpanded) {
     TreePath[] newSelections = getSelectionPaths();
     support.beginUpdate();
     support.postEdit(new SelectionEdit(selections, newSelections));
     support.postEdit(new ExpandEdit(path));
     support.endUpdate();
   }
 }
 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();
     UndoableTree2.this.undoCollapse(path);
   }
   public void redo() throws CannotRedoException {
     super.redo();
     UndoableTree2.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();
     UndoableTree2.this.undoExpansion(path);
   }
   public void redo() throws CannotRedoException {
     super.redo();
     UndoableTree2.this.undoCollapse(path);
   }
   public String getPresentationName() {
     return "node expansion";
   }
   private TreePath path;
 }
 private class SelectionEdit extends AbstractUndoableEdit {
   public SelectionEdit(TreePath[] oldSelections, TreePath[] newSelections) {
     this.oldSelections = oldSelections;
     this.newSelections = newSelections;
   }
   public void undo() throws CannotUndoException {
     super.undo();
     UndoableTree2.this.setSelectionPaths(oldSelections);
   }
   public void redo() throws CannotRedoException {
     super.redo();
     UndoableTree2.this.setSelectionPaths(newSelections);
   }
   public String getPresentationName() {
     return "selection change";
   }
   private TreePath[] oldSelections;
   private TreePath[] newSelections;
 }
 private UndoableEditSupport support = new UndoableEditSupport(this);

}


 </source>
   
  
 
  



Undo Example 5

   <source lang="java">

/* 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 java.util.Hashtable; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.EventListenerList; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; public class UndoExample5 extends JFrame {

 public UndoExample5() {
   super("Undo/Redo Example 5");
   pane = new JTextPane();
   pane.setEditable(true); // Editable
   getContentPane().add(new JScrollPane(pane), BorderLayout.CENTER);
   // Add a menu bar
   menuBar = new JMenuBar();
   setJMenuBar(menuBar);
   // Populate the menu bar
   createMenuBar();
   // Create the undo manager and actions
   MonitorableUndoManager manager = new MonitorableUndoManager();
   pane.getDocument().addUndoableEditListener(manager);
   Action undoAction = new UndoAction(manager);
   Action redoAction = new RedoAction(manager);
   // Add the actions to buttons
   JPanel panel = new JPanel();
   final JButton undoButton = new JButton("Undo");
   final JButton redoButton = new JButton("Redo");
   undoButton.addActionListener(undoAction);
   redoButton.addActionListener(redoAction);
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   panel.add(undoButton);
   panel.add(redoButton);
   getContentPane().add(panel, BorderLayout.SOUTH);
   // Assign the actions to keys
   pane.registerKeyboardAction(undoAction, KeyStroke.getKeyStroke(
       KeyEvent.VK_Z, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
   pane.registerKeyboardAction(redoAction, KeyStroke.getKeyStroke(
       KeyEvent.VK_Y, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
   // Handle events from the MonitorableUndoManager
   manager.addChangeListener(new ChangeListener() {
     public void stateChanged(ChangeEvent evt) {
       MonitorableUndoManager m = (MonitorableUndoManager) evt
           .getSource();
       boolean canUndo = m.canUndo();
       boolean canRedo = m.canRedo();
       undoButton.setEnabled(canUndo);
       redoButton.setEnabled(canRedo);
       undoButton.setToolTipText(canUndo ? m.getUndoPresentationName()
           : null);
       redoButton.setToolTipText(canRedo ? m.getRedoPresentationName()
           : null);
     }
   });
 }
 public void createMenuBar() {
   // Remove the existing menu items
   int count = menuBar.getMenuCount();
   for (int i = 0; i < count; i++) {
     menuBar.remove(menuBar.getMenu(0));
   }
   // Build the new menu.
   Action[] actions = pane.getActions();
   Hashtable actionHash = new Hashtable();
   count = actions.length;
   for (int i = 0; i < count; i++) {
     actionHash.put(actions[i].getValue(Action.NAME), actions[i]);
   }
   // Add the font menu
   JMenu menu = MenuBuilder.buildMenu("Font", fontSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
   // Add the alignment menu
   menu = MenuBuilder.buildMenu("Align", alignSpec, actionHash);
   if (menu != null) {
     menuBar.add(menu);
   }
 }
 // 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 UndoExample5();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent evt) {
       System.exit(0);
     }
   });
   f.setSize(250, 300);
   f.setVisible(true);
   // Create and show a frame monitoring undoable edits
   JFrame undoMonitor = new JFrame("Undo Monitor");
   final JTextArea textArea = new JTextArea();
   textArea.setEditable(false);
   undoMonitor.getContentPane().add(new JScrollPane(textArea));
   undoMonitor.setBounds(f.getLocation().x + f.getSize().width, f
       .getLocation().y, 400, 200);
   undoMonitor.setVisible(true);
   pane.getDocument().addUndoableEditListener(new UndoableEditListener() {
     public void undoableEditHappened(UndoableEditEvent evt) {
       UndoableEdit edit = evt.getEdit();
       textArea.append(edit.getPresentationName() + "("
           + edit.toString() + ")\n");
     }
   });
   // Create and show a frame monitoring document edits
   JFrame editMonitor = new JFrame("Edit Monitor");
   final JTextArea textArea2 = new JTextArea();
   textArea2.setEditable(false);
   editMonitor.getContentPane().add(new JScrollPane(textArea2));
   editMonitor.setBounds(undoMonitor.getLocation().x, undoMonitor
       .getLocation().y
       + undoMonitor.getSize().height, 400, 200);
   editMonitor.setVisible(true);
   pane.getDocument().addDocumentListener(new DocumentListener() {
     public void changedUpdate(DocumentEvent evt) {
       textArea2.append("Attribute change\n");
     }
     public void insertUpdate(DocumentEvent evt) {
       textArea2.append("Text insertion\n");
     }
     public void removeUpdate(DocumentEvent evt) {
       textArea2.append("Text removal\n");
     }
   });
 }
 private static JTextPane pane;
 private static JMenuBar menuBar;
 private static MenuSpec[] sizeSpec = new MenuSpec[] {
     new MenuSpec("Size 8", "font-size-8"),
     new MenuSpec("Size 10", "font-size-10"),
     new MenuSpec("Size 12", "font-size-12"),
     new MenuSpec("Size 14", "font-size-14"),
     new MenuSpec("Size 16", "font-size-16"),
     new MenuSpec("Size 18", "font-size-18"),
     new MenuSpec("Size 24", "font-size-24"),
     new MenuSpec("Size 36", "font-size-36"),
     new MenuSpec("Size 48", "font-size-48") };
 private static MenuSpec[] familySpec = new MenuSpec[] {
     new MenuSpec("Sans Serif", "font-family-SansSerif"),
     new MenuSpec("Monospaced", "font-family-Monospaced"),
     new MenuSpec("Serif", "font-family-Serif") };
 private static MenuSpec[] styleSpec = new MenuSpec[] {
     new MenuSpec("Bold", "font-bold"),
     new MenuSpec("Italics", "font-italic"),
     new MenuSpec("Underline", "font-underline") };
 // Menu definitions for fonts
 private static MenuSpec[] fontSpec = new MenuSpec[] {
     new MenuSpec("Size", sizeSpec), new MenuSpec("Family", familySpec),
     new MenuSpec("Style", styleSpec) };
 // Alignment
 private static MenuSpec[] alignSpec = new MenuSpec[] {
     new MenuSpec("Left", "left-justify"),
     new MenuSpec("Center", "center-justify"),
     new MenuSpec("Right", "right-justify") };

} class MonitorableUndoManager extends UndoManager {

 // List of listeners for events from this object
 protected EventListenerList listenerList = new EventListenerList();
 // A ChangeEvent dedicated to a single MonitorableUndoManager
 protected ChangeEvent changeEvent;
 // Super class overrides
 public synchronized void setLimit(int l) {
   super.setLimit(l);
   fireChangeEvent();
 }
 public synchronized void discardAllEdits() {
   super.discardAllEdits();
   fireChangeEvent();
 }
 public synchronized void undo() throws CannotUndoException {
   super.undo();
   fireChangeEvent();
 }
 public synchronized void redo() throws CannotRedoException {
   super.redo();
   fireChangeEvent();
 }
 public synchronized boolean addEdit(UndoableEdit anEdit) {
   boolean retval = super.addEdit(anEdit);
   fireChangeEvent();
   return retval;
 }
 // Support for ChangeListeners
 public void addChangeListener(ChangeListener l) {
   listenerList.add(ChangeListener.class, l);
 }
 public void removeChangeListener(ChangeListener l) {
   listenerList.remove(ChangeListener.class, l);
 }
 protected void fireChangeEvent() {
   Object[] listeners = listenerList.getListenerList();
   for (int i = listeners.length - 2; i >= 0; i -= 2) {
     if (listeners[i] == ChangeListener.class) {
       if (changeEvent == null) {
         changeEvent = new ChangeEvent(this);
       }
       ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
     }
   }
 }

} class MenuSpec {

 public MenuSpec(String name, MenuSpec[] subMenus) {
   this.name = name;
   this.subMenus = subMenus;
 }
 public MenuSpec(String name, String actionName) {
   this.name = name;
   this.actionName = actionName;
 }
 public MenuSpec(String name, Action action) {
   this.name = name;
   this.action = action;
 }
 public boolean isSubMenu() {
   return subMenus != null;
 }
 public boolean isAction() {
   return action != null;
 }
 public String getName() {
   return name;
 }
 public MenuSpec[] getSubMenus() {
   return subMenus;
 }
 public String getActionName() {
   return actionName;
 }
 public Action getAction() {
   return action;
 }
 private String name;
 private String actionName;
 private Action action;
 private MenuSpec[] subMenus;

} class MenuBuilder {

 public static JMenu buildMenu(String name, MenuSpec[] menuSpecs,
     Hashtable actions) {
   int count = menuSpecs.length;
   JMenu menu = new JMenu(name);
   for (int i = 0; i < count; i++) {
     MenuSpec spec = menuSpecs[i];
     if (spec.isSubMenu()) {
       // Recurse to handle a sub menu
       JMenu subMenu = buildMenu(spec.getName(), spec.getSubMenus(),
           actions);
       if (subMenu != null) {
         menu.add(subMenu);
       }
     } else if (spec.isAction()) {
       // It"s an Action - add it directly to the menu
       menu.add(spec.getAction());
     } else {
       // It"s an action name - add it if possible
       String actionName = spec.getActionName();
       Action targetAction = (Action) actions.get(actionName);
       // Create the menu item
       JMenuItem menuItem = menu.add(spec.getName());
       if (targetAction != null) {
         // The editor kit knows the action
         menuItem.addActionListener(targetAction);
       } else {
         // Action not known - disable the menu item
         menuItem.setEnabled(false);
       }
     }
   }
   // Return null if nothing was added to the menu.
   if (menu.getMenuComponentCount() == 0) {
     menu = null;
   }
   return menu;
 }

}


 </source>
   
  
 
  



Undo Example 6

   <source lang="java">

/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall

  • /

import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.dnd.Autoscroll; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.ruparator; import javax.swing.JFrame; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; public class FileTreeTest {

 public static void main(String[] args) {
   try {
       UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
   } catch (Exception evt) {}
 
   try {
     JFrame f = new JFrame("File Tree Test");
     final FileTree ft = new FileTree("D:\\");
     ft.addTreeSelectionListener(new TreeSelectionListener() {
       public void valueChanged(TreeSelectionEvent evt) {
         TreePath path = evt.getPath();
         String name = ft.getPathName(path);
         System.out.println("File " + name + " has been "
             + (evt.isAddedPath() ? "selected" : "deselected"));
       }
     });
     f.getContentPane().add(new JScrollPane(ft));
     f.setSize(300, 300);
     f.addWindowListener(new WindowAdapter() {
       public void windowClosing(WindowEvent evt) {
         System.exit(0);
       }
     });
     f.setVisible(true);
   } catch (FileNotFoundException e) {
     System.out.println("File " + args[0] + " not found");
   }
 }

} class FileTree extends JTree implements Autoscroll {

 public static final Insets defaultScrollInsets = new Insets(8, 8, 8, 8);
 protected Insets scrollInsets = defaultScrollInsets;
 public FileTree(String path) throws FileNotFoundException,
     SecurityException {
   super((TreeModel) null); // Create the JTree itself
   // Use horizontal and vertical lines
   putClientProperty("JTree.lineStyle", "Angled");
   // Create the first node
   FileTreeNode rootNode = new FileTreeNode(null, path);
   // Populate the root node with its subdirectories
   boolean addedNodes = rootNode.populateDirectories(true);
   setModel(new DefaultTreeModel(rootNode));
   // Listen for Tree Selection Events
   addTreeExpansionListener(new TreeExpansionHandler());
 }
 // Returns the full pathname for a path, or null if not a known path
 public String getPathName(TreePath path) {
   Object o = path.getLastPathComponent();
   if (o instanceof FileTreeNode) {
     return ((FileTreeNode) o).fullName;
   }
   return null;
 }
 // Adds a new node to the tree after construction.
 // Returns the inserted node, or null if the parent
 // directory has not been expanded.
 public FileTreeNode addNode(FileTreeNode parent, String name) {
   int index = parent.addNode(name);
   if (index != -1) {
     ((DefaultTreeModel) getModel()).nodesWereInserted(parent,
         new int[] { index });
     return (FileTreeNode) parent.getChildAt(index);
   }
   // No node was created
   return null;
 }
 // Autoscrolling support
 public void setScrollInsets(Insets insets) {
   this.scrollInsets = insets;
 }
 public Insets getScrollInsets() {
   return scrollInsets;
 }
 // Implementation of Autoscroll interface
 public Insets getAutoscrollInsets() {
   Rectangle r = getVisibleRect();
   Dimension size = getSize();
   Insets i = new Insets(r.y + scrollInsets.top, r.x + scrollInsets.left,
       size.height - r.y - r.height + scrollInsets.bottom, size.width
           - r.x - r.width + scrollInsets.right);
   return i;
 }
 public void autoscroll(Point location) {
   JScrollPane scroller = (JScrollPane) SwingUtilities.getAncestorOfClass(
       JScrollPane.class, this);
   if (scroller != null) {
     JScrollBar hBar = scroller.getHorizontalScrollBar();
     JScrollBar vBar = scroller.getVerticalScrollBar();
     Rectangle r = getVisibleRect();
     if (location.x <= r.x + scrollInsets.left) {
       // Need to scroll left
       hBar.setValue(hBar.getValue() - hBar.getUnitIncrement(-1));
     }
     if (location.y <= r.y + scrollInsets.top) {
       // Need to scroll up
       vBar.setValue(vBar.getValue() - vBar.getUnitIncrement(-1));
     }
     if (location.x >= r.x + r.width - scrollInsets.right) {
       // Need to scroll right
       hBar.setValue(hBar.getValue() + hBar.getUnitIncrement(1));
     }
     if (location.y >= r.y + r.height - scrollInsets.bottom) {
       // Need to scroll down
       vBar.setValue(vBar.getValue() + vBar.getUnitIncrement(1));
     }
   }
 }
 // Inner class that represents a node in this file system tree
 public static class FileTreeNode extends DefaultMutableTreeNode {
   public FileTreeNode(String parent, String name)
       throws SecurityException, FileNotFoundException {
     this.name = name;
     // See if this node exists and whether it is a directory
     fullName = parent == null ? name : parent + File.separator + name;
     File f = new File(fullName);
     if (f.exists() == false) {
       throw new FileNotFoundException("File " + fullName
           + " does not exist");
     }
     isDir = f.isDirectory();
     // Hack for Windows which doesn"t consider a drive to be a
     // directory!
     if (isDir == false && f.isFile() == false) {
       isDir = true;
     }
   }
   // Override isLeaf to check whether this is a directory
   public boolean isLeaf() {
     return !isDir;
   }
   // Override getAllowsChildren to check whether this is a directory
   public boolean getAllowsChildren() {
     return isDir;
   }
   // Return whether this is a directory
   public boolean isDir() {
     return isDir;
   }
   // Get full path
   public String getFullName() {
     return fullName;
   }
   // For display purposes, we return our own name
   public String toString() {
     return name;
   }
   // If we are a directory, scan our contents and populate
   // with children. In addition, populate those children
   // if the "descend" flag is true. We only descend once,
   // to avoid recursing the whole subtree.
   // Returns true if some nodes were added
   boolean populateDirectories(boolean descend) {
     boolean addedNodes = false;
     // Do this only once
     if (populated == false) {
       File f;
       try {
         f = new File(fullName);
       } catch (SecurityException e) {
         populated = true;
         return false;
       }
       if (interim == true) {
         // We have had a quick look here before:
         // remove the dummy node that we added last time
         removeAllChildren();
         interim = false;
       }
       String[] names = f.list(); // Get list of contents
       // Process the contents
       ArrayList list = new ArrayList();
       for (int i = 0; i < names.length; i++) {
         String name = names[i];
         File d = new File(fullName, name);
         try {
           FileTreeNode node = new FileTreeNode(fullName, name);
           list.add(node);
           if (descend && d.isDirectory()) {
             node.populateDirectories(false);
           }
           addedNodes = true;
           if (descend == false) {
             // Only add one node if not descending
             break;
           }
         } catch (Throwable t) {
           // Ignore phantoms or access problems
         }
       }
       if (addedNodes == true) {
         // Now sort the list of contained files and directories
         Object[] nodes = list.toArray();
         Arrays.sort(nodes, new Comparator() {
           public boolean equals(Object o) {
             return false;
           }
           public int compare(Object o1, Object o2) {
             FileTreeNode node1 = (FileTreeNode) o1;
             FileTreeNode node2 = (FileTreeNode) o2;
             // Directories come first
             if (node1.isDir != node2.isDir) {
               return node1.isDir ? -1 : +1;
             }
             // Both directories or both files -
             // compare based on pathname
             return node1.fullName.rupareTo(node2.fullName);
           }
         });
         // Add sorted items as children of this node
         for (int j = 0; j < nodes.length; j++) {
           this.add((FileTreeNode) nodes[j]);
         }
       }
       // If we were scanning to get all subdirectories,
       // or if we found no content, there is no
       // reason to look at this directory again, so
       // set populated to true. Otherwise, we set interim
       // so that we look again in the future if we need to
       if (descend == true || addedNodes == false) {
         populated = true;
       } else {
         // Just set interim state
         interim = true;
       }
     }
     return addedNodes;
   }
   // Adding a new file or directory after
   // constructing the FileTree. Returns
   // the index of the inserted node.
   public int addNode(String name) {
     // If not populated yet, do nothing
     if (populated == true) {
       // Do not add a new node if
       // the required node is already there
       int childCount = getChildCount();
       for (int i = 0; i < childCount; i++) {
         FileTreeNode node = (FileTreeNode) getChildAt(i);
         if (node.name.equals(name)) {
           // Already exists - ensure
           // we repopulate
           if (node.isDir()) {
             node.interim = true;
             node.populated = false;
           }
           return -1;
         }
       }
       // Add a new node
       try {
         FileTreeNode node = new FileTreeNode(fullName, name);
         add(node);
         return childCount;
       } catch (Exception e) {
       }
     }
     return -1;
   }
   protected String name; // Name of this component
   protected String fullName; // Full pathname
   protected boolean populated;// true if we have been populated
   protected boolean interim; // true if we are in interim state
   protected boolean isDir; // true if this is a directory
 }
 // Inner class that handles Tree Expansion Events
 protected class TreeExpansionHandler implements TreeExpansionListener {
   public void treeExpanded(TreeExpansionEvent evt) {
     TreePath path = evt.getPath(); // The expanded path
     JTree tree = (JTree) evt.getSource(); // The tree
     // Get the last component of the path and
     // arrange to have it fully populated.
     FileTreeNode node = (FileTreeNode) path.getLastPathComponent();
     if (node.populateDirectories(true)) {
       ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);
     }
   }
   public void treeCollapsed(TreeExpansionEvent evt) {
     // Nothing to do
   }
 }

}


 </source>
   
  
 
  



Undo Example 7

   <source lang="java">

/* Definitive Guide to Swing for Java 2, Second Edition By John Zukowski ISBN: 1-893115-78-X Publisher: APress

  • /

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; public class UndoSample {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Undo Sample");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JTextArea textArea = new JTextArea();
   JScrollPane scrollPane = new JScrollPane(textArea);
   UndoManager manager = new UndoManager();
   textArea.getDocument().addUndoableEditListener(manager);
   JToolBar toolbar = new JToolBar();
   toolbar.add(UndoManagerHelper.getUndoAction(manager));
   toolbar.add(UndoManagerHelper.getRedoAction(manager));
   Container content = frame.getContentPane();
   content.add(toolbar, BorderLayout.NORTH);
   content.add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

} class UndoManagerHelper {

 public static Action getUndoAction(UndoManager manager, String label) {
   return new UndoAction(manager, label);
 }
 public static Action getUndoAction(UndoManager manager) {
   return new UndoAction(manager, "Undo");
 }
 public static Action getRedoAction(UndoManager manager, String label) {
   return new RedoAction(manager, label);
 }
 public static Action getRedoAction(UndoManager manager) {
   return new RedoAction(manager, "Redo");
 }
 private abstract static class UndoRedoAction extends AbstractAction {
   UndoManager undoManager = new UndoManager();
   String errorMessage = "Cannot undo";
   String errorTitle = "Undo Problem";
   protected UndoRedoAction(UndoManager manager, String name) {
     super(name);
     undoManager = manager;
   }
   public void setErrorMessage(String newValue) {
     errorMessage = newValue;
   }
   public void setErrorTitle(String newValue) {
     errorTitle = newValue;
   }
   protected void showMessage(Object source) {
     if (source instanceof Component) {
       JOptionPane.showMessageDialog((Component) source, errorMessage,
           errorTitle, JOptionPane.WARNING_MESSAGE);
     } else {
       System.err.println(errorMessage);
     }
   }
 }
 public static class UndoAction extends UndoRedoAction {
   public UndoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot undo");
     setErrorTitle("Undo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.undo();
     } catch (CannotUndoException cannotUndoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }
 public static class RedoAction extends UndoRedoAction {
   String errorMessage = "Cannot redo";
   String errorTitle = "Redo Problem";
   public RedoAction(UndoManager manager, String name) {
     super(manager, name);
     setErrorMessage("Cannot redo");
     setErrorTitle("Redo Problem");
   }
   public void actionPerformed(ActionEvent actionEvent) {
     try {
       undoManager.redo();
     } catch (CannotRedoException cannotRedoException) {
       showMessage(actionEvent.getSource());
     }
   }
 }

}


 </source>
   
  
 
  



Undo manager

   <source lang="java">

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.event.UndoableEditEvent; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.UndoManager; public class UndoManagerDemo extends JFrame {

 protected Vector pointVector = new Vector();
 protected PaintCanvas canvas = new PaintCanvas(pointVector);
 protected UndoManager undoManager = new UndoManager();
 protected JButton undoButton = new JButton("Undo");
 protected JButton redoButton = new JButton("Redo");
 public UndoManagerDemo() {
   super("Undo/Redo Demo");
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   JPanel buttonPanel = new JPanel(new GridLayout());
   buttonPanel.add(undoButton);
   buttonPanel.add(redoButton);
   getContentPane().add(buttonPanel, BorderLayout.NORTH);
   getContentPane().add(canvas, BorderLayout.CENTER);
   canvas.addMouseListener(new MouseAdapter() {
     public void mousePressed(MouseEvent e) {
       Point point = new Point(e.getX(), e.getY());
       pointVector.addElement(point);
       undoManager.undoableEditHappened(new UndoableEditEvent(
           canvas, new UndoablePaintSquare(point, pointVector)));
       undoButton.setText(undoManager.getUndoPresentationName());
       redoButton.setText(undoManager.getRedoPresentationName());
       undoButton.setEnabled(undoManager.canUndo());
       redoButton.setEnabled(undoManager.canRedo());
       canvas.repaint();
     }
   });
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       try {
         undoManager.undo();
       } catch (CannotRedoException cre) {
         cre.printStackTrace();
       }
       canvas.repaint();
       undoButton.setEnabled(undoManager.canUndo());
       redoButton.setEnabled(undoManager.canRedo());
     }
   });
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       try {
         undoManager.redo();
       } catch (CannotRedoException cre) {
         cre.printStackTrace();
       }
       canvas.repaint();
       undoButton.setEnabled(undoManager.canUndo());
       redoButton.setEnabled(undoManager.canRedo());
     }
   });
   setSize(400, 300);
   setVisible(true);
 }
 public static void main(String argv[]) {
   new UndoManagerDemo();
 }
 class PaintCanvas extends JPanel {
   private Vector points;
   protected int width = 50;
   protected int height = 50;
   public PaintCanvas(Vector v) {
     super();
     points = v;
     setOpaque(true);
     setBackground(Color.white);
   }
   public void paintComponent(Graphics g) {
     super.paintComponent(g);
     g.setColor(Color.black);
     
     for(int i=0;i<points.size();i++){
       Point point = (Point) points.get(i);
       g.drawRect(point.x, point.y, width, height);
     }
   }
 }
 class UndoablePaintSquare extends AbstractUndoableEdit {
   protected Vector points;
   protected Point point;
   public UndoablePaintSquare(Point p, Vector v) {
     points = v;
     point = p;
   }
   public String getPresentationName() {
     return "Square Addition";
   }
   public void undo() {
     super.undo();
     points.remove(point);
   }
   public void redo() {
     super.redo();
     points.add(point);
   }
 }

}


 </source>
   
  
 
  



Undo redo textarea

   <source lang="java">

import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.CannotRedoException; import javax.swing.undo.UndoManager; public class UndoRedoTextArea extends JFrame {

 protected JTextArea textArea = new JTextArea();
 protected UndoManager undoManager = new UndoManager();
 protected JButton undoButton = new JButton("Undo");
 protected JButton redoButton = new JButton("Redo");
 public UndoRedoTextArea() {
   super("Undo/Redo Demo");
   undoButton.setEnabled(false);
   redoButton.setEnabled(false);
   JPanel buttonPanel = new JPanel(new GridLayout());
   buttonPanel.add(undoButton);
   buttonPanel.add(redoButton);
   JScrollPane scroller = new JScrollPane(textArea);
   getContentPane().add(buttonPanel, BorderLayout.NORTH);
   getContentPane().add(scroller, BorderLayout.CENTER);
   textArea.getDocument().addUndoableEditListener(
       new UndoableEditListener() {
         public void undoableEditHappened(UndoableEditEvent e) {
           undoManager.addEdit(e.getEdit());
           updateButtons();
         }
       });
   undoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       try {
         undoManager.undo();
       } catch (CannotRedoException cre) {
         cre.printStackTrace();
       }
       updateButtons();
     }
   });
   redoButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       try {
         undoManager.redo();
       } catch (CannotRedoException cre) {
         cre.printStackTrace();
       }
       updateButtons();
     }
   });
   setSize(400, 300);
   setVisible(true);
 }
 public void updateButtons() {
   undoButton.setText(undoManager.getUndoPresentationName());
   redoButton.setText(undoManager.getRedoPresentationName());
   undoButton.setEnabled(undoManager.canUndo());
   redoButton.setEnabled(undoManager.canRedo());
 }
 public static void main(String argv[]) {
   new UndoRedoTextArea();
 }

}


 </source>