Java Tutorial/Swing/Redo Undo
Содержание
- 1 14. Adding Undo and Redo to a Text Component
- 2 14. Bind the undo action to ctl-Z
- 3 14. Create an undo action and add it to the text component
- 4 14. Create a redo action and add it to the text component (JTextComponent)
- 5 14. Listen for undo and redo events
- 6 14. Undoable Drawing
- 7 14. Undo Editor
- 8 14. Using the Undo Framework with Swing Text Components
14. Adding Undo and Redo to a Text Component
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");
}}
14. Bind the undo action to ctl-Z
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);
}
}
14. Create an undo action and add it to the text component
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);
}
}
14. Create a redo action and add it to the text component (JTextComponent)
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);
}
}
14. Listen for undo and redo events
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);
}}
14. Undoable Drawing
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());
}
}
}
}
14. Undo Editor
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());
}
}
}
14. Using the Undo Framework with Swing Text Components
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);
}
}