读书人

JAVA 兑现Undo/Redo(撤销/恢复)二

发布时间: 2012-09-12 09:21:30 作者: rapoo

JAVA 实现Undo/Redo(撤销/恢复)二
三, DrawLineCommand,实现一次Undo/Redo功能

一个继承了UndoableCommand提供具体的撤销/恢复功能的子类,就可以实现一次Undo/Redo。这里实现一个在容器上画直线的子类DrawLineCommand,带有擦除和重画直线的功能。

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.util.Random;

public class DrawLineCommand extends UndoableCommand {

private int x1, y1, x2, y2;
private Container container;

public DrawLineCommand(Container container) {
this.container = container;
x1 = new Random().nextInt(100) + 100;
y1 = new Random().nextInt(100) + 100;
x2 = new Random().nextInt(100) + 300;
y2 = new Random().nextInt(100) + 250;
}

@Override
public void command() {
drawLine(Color.RED);
System.out.print("Draw a ");
System.out.println(toString());
}

@Override
public void restore() {
drawLine(container.getBackground());
System.out.print("Erase the ");
System.out.println(toString());
}

private void drawLine(Color c) {
Graphics g = container.getGraphics();
g.setColor(c);
g.drawLine(x1, y1, x2, y2);
g.dispose();
}

@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("line between point(");
stringBuilder.append(x1).append(",").append(y1).append(") and point(");
stringBuilder.append(x2).append(",").append(y2).append(")");
return stringBuilder.toString();
}
}


下面给出一个UndoTest类来测试DrawLineCommand

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class UndoTest extends JFrame {

UndoableCommand command;
Action drawLineAction, undoAction, redoAction;

public UndoTest() {
undoAction = new AbstractAction("Undo") {

@Override
public void actionPerformed(ActionEvent e) {
command.undo();
setEnabled(false);
redoAction.setEnabled(true);
}
};
undoAction.setEnabled(false);

redoAction = new AbstractAction("Redo") {

@Override
public void actionPerformed(ActionEvent e) {
command.redo();
setEnabled(false);
undoAction.setEnabled(true);
}
};
redoAction.setEnabled(false);

drawLineAction = new AbstractAction("Draw Line") {

@Override
public void actionPerformed(ActionEvent e) {
command = new DrawLineCommand(getContentPane());
command.execute();
undoAction.setEnabled(true);
}
};
}

public void createAndShowGUI() {
JToolBar toolBar = new JToolBar();
toolBar.add(drawLineAction);
toolBar.add(undoAction);
toolBar.add(redoAction);
add(toolBar, BorderLayout.NORTH);
setSize(600, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new UndoTest().createAndShowGUI();
}
});
}
}

结果:DrawLineCommand能完美完成最近一次的Undo/Redo

可见,用UndoableCommand来实现一次Undo/Redo功能是可行的,那么如何实现多次或者无限制的Undo/Redo呢?

读书人网 >编程

热点推荐