Java Tutorial/Swing/Redo Undo

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

14. 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>





14. 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>





14. 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>





14. 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>





14. 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>





14. Undoable Drawing

   <source lang="java">

import java.awt.BorderLayout; import java.awt.ruponent; 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.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JToolBar; import javax.swing.UIManager; 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 UndoableDrawingPanel extends JPanel implements StateEditable {

 private static String POLYGON_KEY = "Polygon";
 UndoableEditSupport undoableEditSupport = new UndoableEditSupport(this);
 Polygon polygon = new Polygon();
 public UndoableDrawingPanel() {
   MouseListener mouseListener = new MouseAdapter() {
     public void mouseReleased(MouseEvent mouseEvent) {
       StateEdit stateEdit = new StateEdit(UndoableDrawingPanel.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);
   UndoableDrawingPanel drawingPanel = new UndoableDrawingPanel();
   UndoManager manager = new UndoManager();
   drawingPanel.addUndoableEditListener(manager);
   JToolBar toolbar = new JToolBar();
   JButton undoButton = new JButton(UndoManagerHelper.getUndoAction(manager));
   toolbar.add(undoButton);
   JButton redoButton = new JButton(UndoManagerHelper.getRedoAction(manager));
   toolbar.add(redoButton);
   frame.add(toolbar, BorderLayout.NORTH);
   frame.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, (String) UIManager.get("AbstractUndoableEdit.undoText"));
 }
 public static Action getRedoAction(UndoManager manager, String label) {
   return new RedoAction(manager, label);
 }
 public static Action getRedoAction(UndoManager manager) {
   return new RedoAction(manager, (String) UIManager.get("AbstractUndoableEdit.redoText"));
 }
 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 {
   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>





14. Undo Editor

   <source lang="java">

import java.awt.BorderLayout; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.undo.UndoManager; public class UndoEditor extends JFrame {

 private UndoManager undoManager = new UndoManager();
 private JMenuBar menuBar = new JMenuBar();
 private JMenu editMenu = new JMenu("Edit");
 private UndoAction undoAction = new UndoAction();
 private RedoAction redoAction = new RedoAction();
 public UndoEditor() {
   setLayout(new BorderLayout());
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   JTextPane editor = new JTextPane();
   editor.getDocument().addUndoableEditListener(new UndoListener());
   JScrollPane scroller = new JScrollPane(editor);
   menuBar.add(editMenu);
   editMenu.add(undoAction);
   editMenu.add(redoAction);
   this.setJMenuBar(menuBar);
   add(scroller);
   setSize(400, 300);
   setVisible(true);
 }
 public static void main(String[] args) {
   new UndoEditor();
 }
 class UndoListener implements UndoableEditListener {
   public void undoableEditHappened(UndoableEditEvent e) {
     undoManager.addEdit(e.getEdit());
     undoAction.update();
     redoAction.update();
   }
 }
 class UndoAction extends AbstractAction {
   public UndoAction() {
     this.putValue(Action.NAME, undoManager.getUndoPresentationName());
     this.setEnabled(false);
   }
   public void actionPerformed(ActionEvent e) {
     if (this.isEnabled()) {
       undoManager.undo();
       undoAction.update();
       redoAction.update();
     }
   }
   public void update() {
     this.putValue(Action.NAME, undoManager.getUndoPresentationName());
     this.setEnabled(undoManager.canUndo());
   }
 }
 class RedoAction extends AbstractAction {
   public RedoAction() {
     this.putValue(Action.NAME, undoManager.getRedoPresentationName());
     this.setEnabled(false);
   }
   public void actionPerformed(ActionEvent e) {
     if (this.isEnabled()) {
       undoManager.redo();
       undoAction.update();
       redoAction.update();
     }
   }
   public void update() {
     this.putValue(Action.NAME, undoManager.getRedoPresentationName());
     this.setEnabled(undoManager.canRedo());
   }
 }

}</source>





14. Using the Undo Framework with Swing Text Components

   <source lang="java">

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax.swing.UIManager; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; 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, (String) UIManager.get("AbstractUndoableEdit.undoText"));
 }
 public static Action getRedoAction(UndoManager manager, String label) {
   return new RedoAction(manager, label);
 }
 public static Action getRedoAction(UndoManager manager) {
   return new RedoAction(manager, (String) UIManager.get("AbstractUndoableEdit.redoText"));
 }
 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 {
   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());
     }
   }
 }

} 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();
   JButton undoButton = new JButton(UndoManagerHelper.getUndoAction(manager));
   toolbar.add(undoButton);
   JButton redoButton = new JButton(UndoManagerHelper.getRedoAction(manager));
   toolbar.add(redoButton);
   frame.add(toolbar, BorderLayout.NORTH);
   frame.add(scrollPane, BorderLayout.CENTER);
   frame.setSize(300, 150);
   frame.setVisible(true);
 }

}</source>