Ch.22 Command Pattern 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실 명령의 집합을 보존해서 똑 같은 명령을 재실행할 수 있도록 한다. 예에서는 명령이 mousedrag이며, 1) mousedrag할 때 canvas에 그림을 그리고 2) 이 명령을 저장 (MacroCommand의 commands 필드에 저장) 3) clear 버튼을 누르면 mousedrag한 것과 똑같은 명령을 한번 더 수행하고 저장된 명령을 지움 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실
Ch.22 Command Pattern ▌MacroCommand Class ▌DrawCommand Class package command; import java.util.Stack; import java.util.Iterator; public class MacroCommand implements Command { private Stack commands = new Stack(); public void execute() { Iterator it = commands.iterator(); while (it.hasNext()) { ((Command)it.next()).execute(); } } public void append(Command cmd) { if (cmd != this) { commands.push(cmd); } public void undo() { if (!commands.empty()) { commands.pop(); } public void clear() { commands.clear(); package drawer; import command.Command; import java.awt.Point; public class DrawCommand implements Command { protected Drawable drawable; private Point position; public DrawCommand(Drawable drawable, Point position) { this.drawable = drawable; this.position = position; } public void execute() { drawable.draw(position.x, position.y); MacroCommand의 append()는 stack에 push, clear()는 stack의 내용을 clear, execute()는 stack 안에 있는 모든 command에 대해 execute를 실행. DrawCommand의 drawable은 DrawCanvas의 instance. 그러므로 drawable.draw는 DrawCanvas.draw 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실
Ch.22 Command Pattern ▌DrawCanvas Class 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실 package drawer; import command.*; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class DrawCanvas extends Canvas implements Drawable { private Color color = Color.red; private int radius = 6; private MacroCommand history; public DrawCanvas(int width, int height, MacroCommand history) { setSize(width, height); setBackground(Color.white); this.history = history; } public void repaint(Graphics g) { history.execute(); public void draw(int x, int y) { Graphics g = getGraphics(); g.setColor(color); g.fillOval(x - radius, y - radius, radius * 2, radius * 2); DrawCanvas의 repaint()는 history.execute()를 call. history는 MacroCommand의 instance이므로 stack 안의 모든 command를 수행. 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실
Ch.22 Command Pattern ▌Main Class // import문 생략 pack(); setVisible(true); } public void actionPerformed(ActionEvent e) { if (e.getSource() == clearButton) { history.clear(); canvas.repaint(); } public void mouseDragged(MouseEvent e) { Command cmd = new DrawCommand(canvas, e.getPoint()); history.append(cmd); cmd.execute(); public void windowClosing(WindowEvent e) { System.exit(0); } public static void main(String[] args) { new Main("Command Pattern Sample"); // import문 생략 public class Main extends JFrame implements ActionListener, MouseMotionListener, WindowListener { private MacroCommand history = new MacroCommand(); private DrawCanvas canvas = new DrawCanvas(400, 400, history); private JButton clearButton = new JButton("clear"); public Main(String title) { super(title); this.addWindowListener(this); canvas.addMouseMotionListener(this); clearButton.addActionListener(this); Box buttonBox = new Box (BoxLayout.X_AXIS); buttonBox.add(clearButton); mainBox.add(buttonBox); mainBox.add(canvas); getContentPane().add(mainBox); Main의 생성자는 clearButton과 canvas를 만듬 1) mouseDragged가 수행되면 MacroCommand.append()를 수행 하여 stack에 cmd를 저장하고, DrawCommand.execute()를 수행 DrawCanvas.draw()를 수행 2) clearButton을 누르면 MacroCommand.clear()를 수행하여 stack 속의 모든 명령을 삭제하고, DrawCanvas.repaint()를 수행 MacroCommand.execute() DrawCommand.execute() DrawCanvas.draw()를 수행 장 덕 성 계명대학교 컴퓨터공학과 정보공학실험실