尊敬的StackOverFlow社区,
我正在尝试重构我的简单绘画程序的实现。但是我确实有实现命令模式的问题。基本上,我希望每种“绘画模式”都有一个单独的命令类,该类正在实现一个接口。目前,我有3种绘制模式:矩形,椭圆形和涂鸦。 我真的很感谢收到的每一份帮助。 我将在下面提供代码。
我已经尝试使用三个Command类来实现它,在其中将gui赋予命令类。但不幸的是,我收到了很多异常:(。
class ShapeManager implements ItemListener {
DrawGUIs gui;
abstract class ShapeDrawer extends MouseAdapter implements MouseMotionListener {
public void mouseMoved(MouseEvent e) {
/* ignore */ }
}
// if this class is active, the mouse is interpreted as a pen
class ScribbleDrawer extends ShapeDrawer {
int lastx, lasty;
public void mousePressed(MouseEvent e) {
lastx = e.getX();
lasty = e.getY();
}
public void mouseDragged(MouseEvent e) {
Graphics g = gui.getGraphics();
int x = e.getX(), y = e.getY();
g.setColor(gui.color);
g.setPaintMode();
g.drawLine(lastx, lasty, x, y);
lastx = x;
lasty = y;
}
}
// if this class is active, rectangles are drawn
class RectangleDrawer extends ShapeDrawer implements Drawable{
int pressx, pressy;
int lastx = -1, lasty = -1;
// mouse pressed => fix first corner of rectangle
public void mousePressed(MouseEvent e) {
pressx = e.getX();
pressy = e.getY();
}
// mouse released => fix second corner of rectangle
// and draw the resulting shape
public void mouseReleased(MouseEvent e) {
Graphics g = gui.getGraphics();
if (lastx != -1) {
// first undraw a rubber rect
g.setXORMode(gui.color);
g.setColor(gui.getBackground());
doDraw(pressx, pressy, lastx, lasty, g);
lastx = -1;
lasty = -1;
}
// these commands finish the rubberband mode
g.setPaintMode();
g.setColor(gui.color);
// draw the finel rectangle
doDraw(pressx, pressy, e.getX(), e.getY(), g);
}
// mouse released => temporarily set second corner of rectangle
// draw the resulting shape in "rubber-band mode"
public void mouseDragged(MouseEvent e) {
Graphics g = gui.getGraphics();
// these commands set the rubberband mode
g.setXORMode(gui.color);
g.setColor(gui.getBackground());
if (lastx != -1) {
// first undraw previous rubber rect
doDraw(pressx, pressy, lastx, lasty, g);
}
lastx = e.getX();
lasty = e.getY();
// draw new rubber rect
doDraw(pressx, pressy, lastx, lasty, g);
}
public void doDraw(int x0, int y0, int x1, int y1, Graphics g) {
// calculate upperleft and width/height of rectangle
int x = Math.min(x0, x1);
int y = Math.min(y0, y1);
int w = Math.abs(x1 - x0);
int h = Math.abs(y1 - y0);
// draw rectangle
g.drawRect(x, y, w, h);
}
@Override
public void draw(Graphics g) {
// TODO Auto-generated method stub
}
}
// if this class is active, ovals are drawn
class OvalDrawer extends RectangleDrawer implements Drawable {
public void doDraw(int x0, int y0, int x1, int y1, Graphics g) {
int x = Math.min(x0, x1);
int y = Math.min(y0, y1);
int w = Math.abs(x1 - x0);
int h = Math.abs(y1 - y0);
// draw oval instead of rectangle
g.drawOval(x, y, w, h);
}
@Override
public void draw(Graphics g) {
// TODO Auto-generated method stub
}
}
ScribbleDrawer scribbleDrawer = new ScribbleDrawer();
RectangleDrawer rectDrawer = new RectangleDrawer();
OvalDrawer ovalDrawer = new OvalDrawer();
ShapeDrawer currentDrawer;
public ShapeManager(DrawGUIs itsGui) {
gui = itsGui;
// default: scribble mode
currentDrawer = scribbleDrawer;
// activate scribble drawer
gui.addMouseListener(currentDrawer);
gui.addMouseMotionListener(currentDrawer);
}
// reset the shape drawer
public void setCurrentDrawer(ShapeDrawer l) {
if (currentDrawer == l)
return;
// deactivate previous drawer
gui.removeMouseListener(currentDrawer);
gui.removeMouseMotionListener(currentDrawer);
// activate new drawer
currentDrawer = l;
gui.addMouseListener(currentDrawer);
gui.addMouseMotionListener(currentDrawer);
}
// user selected new shape => reset the shape mode
public void itemStateChanged(ItemEvent e) {
if (e.getItem().equals("Scribble")) {
setCurrentDrawer(scribbleDrawer);
} else if (e.getItem().equals("Rectangle")) {
setCurrentDrawer(rectDrawer);
} else if (e.getItem().equals("Oval")) {
setCurrentDrawer(ovalDrawer);
}
}
}
预期结果是带有附加CommandQueue的实际功能,以启用撤消和重做操作。