控制台程序。

在Sketcher中创建形状时,并不知道应该以什么顺序创建不同类型的形状,这完全取决于使用Sketcher程序生成草图的人。因此需要绘制形状,对它们执行其他操作而不必知道图形是什么。当然,多态性在这里是有帮助的。

最简单的方法可能是为Sketcher形状类定义通用的基类,并在每个形状类中包含一个成员来存储某种java.awt.geom形状对象,接着把对形状类对象的引用存储为基类类型以获得多态行为。

1、通用基类:

  1 import java.awt.*;
  2 import java.io.Serializable;
  3 import static Constants.SketcherConstants.*;
  4 import java.awt.geom.*;
  5
  6 public abstract class Element implements Serializable{
  7
  8   public Element(Point position, Color color) {
  9     this.position = new Point(position);
 10     this.color = color;
 11   }
 12
 13   protected Element(Color color) {
 14     this.color = color;
 15   }
 16
 17   // Returns the color of the element
 18   public Color getColor() {
 19     return color;
 20   }
 21
 22   // Returns the position of the element
 23   public Point getPosition() {
 24     return position;
 25   }
 26
 27   // Returns the bounding rectangle enclosing an element boundary
 28   public java.awt.Rectangle getBounds() {
 29     return bounds;
 30   }
 31
 32   // Create a new element
 33   public static Element createElement(int type, Color color, Point start, Point end) {
 34     switch(type) {
 35       case LINE:
 36         return new Element.Line(start, end, color);
 37       case RECTANGLE:
 38          return new Rectangle(start, end, color);
 39       case CIRCLE:
 40         return new Circle(start, end, color);
 41       case CURVE:
 42         return new Curve(start, end, color);
 43       default:
 44        assert false;                                                   // We should never get to here
 45     }
 46     return null;
 47   }
 48
 49   // Nested class defining a line
 50   public static class Line extends Element {
 51     public Line(Point start, Point end, Color color) {
 52       super(start, color);
 53       line = new Line2D.Double(origin.x, origin.y, end.x - position.x, end.y - position.y);
 54       bounds = new java.awt.Rectangle(
 55                      Math.min(start.x ,end.x),    Math.min(start.y, end.y),
 56                      Math.abs(start.x - end.x)+1, Math.abs(start.y - end.y)+1);
 57     }
 58
 59     // Change the end point for the line
 60     public void modify(Point start, Point last) {
 61       line.x2 = last.x - position.x;
 62       line.y2 = last.y - position.y;
 63       bounds = new java.awt.Rectangle(
 64                    Math.min(start.x ,last.x),    Math.min(start.y, last.y),
 65                    Math.abs(start.x - last.x)+1, Math.abs(start.y - last.y)+1);
 66     }
 67
 68     // Display the line
 69     public  void draw(Graphics2D g2D) {
 70      g2D.setPaint(color);                                              // Set the line color
 71      g2D.translate(position.x, position.y);                            // Move context origin
 72      g2D.draw(line);                                                   // Draw the line
 73      g2D.translate(-position.x, -position.y);                          // Move context origin back
 74     }
 75     private Line2D.Double line;
 76     private final static long serialVersionUID = 1001L;
 77   }
 78
 79   // Nested class defining a rectangle
 80   public static class Rectangle extends Element {
 81     public Rectangle(Point start, Point end, Color color) {
 82       super(new Point(Math.min(start.x, end.x), Math.min(start.y, end.y)), color);
 83       rectangle = new Rectangle2D.Double(
 84         origin.x, origin.y,                                            // Top-left corner
 85         Math.abs(start.x - end.x), Math.abs(start.y - end.y));         // Width & height
 86       bounds = new java.awt.Rectangle(
 87                     Math.min(start.x ,end.x),    Math.min(start.y, end.y),
 88                     Math.abs(start.x - end.x)+1, Math.abs(start.y - end.y)+1);
 89     }
 90
 91     // Display the rectangle
 92     public  void draw(Graphics2D g2D) {
 93       g2D.setPaint(color);                                             // Set the rectangle color
 94       g2D.translate(position.x, position.y);                           // Move context origin
 95       g2D.draw(rectangle);                                             // Draw the rectangle
 96       g2D.translate(-position.x, -position.y);                         // Move context origin back
 97     }
 98
 99     // Method to redefine the rectangle
100     public void modify(Point start, Point last) {
101       bounds.x = position.x = Math.min(start.x, last.x);
102       bounds.y = position.y = Math.min(start.y, last.y);
103       rectangle.width = Math.abs(start.x - last.x);
104       rectangle.height = Math.abs(start.y - last.y);
105       bounds.width = (int)rectangle.width +1;
106       bounds.height = (int)rectangle.height + 1;
107     }
108
109     private Rectangle2D.Double rectangle;
110     private final static long serialVersionUID = 1001L;
111   }
112
113   // Nested class defining a circle
114   public static class Circle extends Element {
115     public Circle(Point center, Point circum, Color color) {
116       super(color);
117
118       // Radius is distance from center to circumference
119       double radius = center.distance(circum);
120       position = new Point(center.x - (int)radius, center.y - (int)radius);
121       circle = new Ellipse2D.Double(origin.x, origin.y, 2.*radius, 2.*radius);
122       bounds = new java.awt.Rectangle(position.x, position.y,
123                               1 + (int)circle.width, 1+(int)circle.height);
124     }
125
126     // Display the circle
127     public  void draw(Graphics2D g2D) {
128       g2D.setPaint(color);                                             // Set the circle color
129       g2D.translate(position.x, position.y);                           // Move context origin
130       g2D.draw(circle);                                                // Draw the circle
131       g2D.translate(-position.x, -position.y);                         // Move context origin back
132     }
133
134     // Recreate this circle
135     public void modify(Point center, Point circum) {
136       double radius = center.distance(circum);
137       circle.width = circle.height = 2*radius;
138       position.x = center.x - (int)radius;
139       position.y = center.y - (int)radius;
140       bounds = new java.awt.Rectangle(position.x, position.y,
141                               1 + (int)circle.width, 1+(int)circle.height);
142     }
143
144     private Ellipse2D.Double circle;
145     private final static long serialVersionUID = 1001L;
146   }
147
148   // Nested class defining a curve
149   public static class Curve extends Element {
150     public Curve(Point start, Point next, Color color) {
151       super(start, color);
152       curve = new GeneralPath();
153       curve.moveTo(origin.x, origin.y);                                // Set current position as origin
154       curve.lineTo(next.x - position.x, next.y - position.y);          // Add segment
155       bounds = new java.awt.Rectangle(
156                    Math.min(start.x ,next.x),    Math.min(start.y, next.y),
157                    Math.abs(next.x - start.x)+1, Math.abs(next.y - start.y)+1);
158     }
159
160     // Add another segment
161     public void modify(Point start, Point next) {
162       curve.lineTo(next.x - position.x, next.y - position.y);          // Add segment
163       bounds.add(new java.awt.Rectangle(next.x,next.y, 1, 1));         // Extend bounds
164     }
165
166
167     // Display the curve
168     public  void draw(Graphics2D g2D) {
169      g2D.setPaint(color);                                              // Set the curve color
170      g2D.translate(position.x, position.y);                            // Move context origin
171      g2D.draw(curve);                                                  // Draw the curve
172      g2D.translate(-position.x, -position.y);                          // Move context origin back
173     }
174
175     private GeneralPath curve;
176     private final static long serialVersionUID = 1001L;
177   }
178
179   // Abstract Element class methods
180   public abstract void draw(Graphics2D g2D);
181   public abstract void modify(Point start, Point last);
182
183   // Element class fields
184   protected Point position;                                            // Position of a shape
185   protected Color color;                                               // Color of a shape
186   protected java.awt.Rectangle bounds;                                 // Bounding rectangle
187   protected static final Point origin = new Point();                   // Origin for elements
188   private final static long serialVersionUID = 1001L;
189 }

View Code

2、实现了链表和Iterable<Element>接口的模型:

 1 import java.io.Serializable;
 2 import java.util.*;
 3
 4 public class SketcherModel extends Observable implements Serializable, Iterable<Element> {
 5
 6   //Remove an element from the sketch
 7   public boolean remove(Element element) {
 8     boolean removed = elements.remove(element);
 9     if(removed) {
10       setChanged();
11       notifyObservers(element.getBounds());
12     }
13     return removed;
14   }
15
16   //Add an element to the sketch
17   public void add(Element element) {
18     elements.add(element);
19     setChanged();
20     notifyObservers(element.getBounds());
21   }
22
23   // Get iterator for sketch elements
24   public Iterator<Element> iterator() {
25     return elements.iterator();
26   }
27
28
29   protected LinkedList<Element> elements = new LinkedList<>();
30   private final static long serialVersionUID = 1001L;
31 }

View Code

3、视图:

 1 import javax.swing.JComponent;
 2 import java.util.*;
 3 import java.awt.*;
 4 import java.awt.event.MouseEvent;
 5 import javax.swing.event.MouseInputAdapter;
 6
 7 @SuppressWarnings("serial")
 8 public class SketcherView extends JComponent implements Observer {
 9   public SketcherView(Sketcher theApp) {
10     this.theApp = theApp;
11     MouseHandler handler = new MouseHandler();                         // create the mouse listener
12     addMouseListener(handler);                                         // Listen for button events
13     addMouseMotionListener(handler);                                   // Listen for motion events
14   }
15
16   // Method called by Observable object when it changes
17   public void update(Observable o, Object rectangle) {
18     if(rectangle != null) {
19       repaint((java.awt.Rectangle)rectangle);
20     } else {
21       repaint();
22     }
23   }
24
25   // Method to draw on the view
26   @Override
27   public void paint(Graphics g) {
28     Graphics2D g2D = (Graphics2D)g;                                    // Get a 2D device context
29     for(Element element: theApp.getModel()) {                          // For each element in the model
30       element.draw(g2D);                                               // ...draw the element
31     }
32   }
33
34   class MouseHandler extends MouseInputAdapter {
35     @Override
36     public void mousePressed(MouseEvent e)  {
37       start = e.getPoint();                                            // Save the cursor position in start
38       buttonState = e.getButton();                                     // Record which button was pressed
39       if(buttonState == MouseEvent.BUTTON1) {
40         g2D = (Graphics2D)getGraphics();                               // Get graphics context
41         g2D.setXORMode(getBackground());                               // Set XOR mode
42       }
43     }
44
45     @Override
46     public void mouseDragged(MouseEvent e) {
47       last = e.getPoint();                                             // Save cursor position
48
49       if(buttonState == MouseEvent.BUTTON1) {
50         if(tempElement == null) {                                      // Is there an element?
51           tempElement = Element.createElement(                         // No, so create one
52                                  theApp.getWindow().getElementType(),
53                                  theApp.getWindow().getElementColor(),
54                                  start, last);
55         } else {
56           tempElement.draw(g2D);                                       // Yes draw to erase it
57           tempElement.modify(start, last);                             // Now modify it
58         }
59         tempElement.draw(g2D);                                         // and draw it
60      }
61     }
62
63     @Override
64     public void mouseReleased(MouseEvent e) {
65       if(e.getButton() == MouseEvent.BUTTON1) {
66         buttonState = MouseEvent.NOBUTTON;                             // Reset the button state
67
68         if(tempElement != null) {                                      // If there is an element...
69           theApp.getModel().add(tempElement);                          // ...add it to the model...
70           tempElement = null;                                          // ...and reset the field
71         }
72         if(g2D != null) {                                              // If there's a graphics context
73           g2D.dispose();                                               // ...release the resource...
74           g2D = null;                                                  // ...and reset field to null
75         }
76         start = last = null;                                           // Remove any points
77       }
78     }
79
80     @Override
81     public void mouseEntered(MouseEvent e) {
82       setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
83     }
84
85     @Override
86     public void mouseExited(MouseEvent e) {
87       setCursor(Cursor.getDefaultCursor());
88     }
89
90     private Point start;                                               // Stores cursor position on press
91     private Point last;                                                // Stores cursor position on drag
92     private Element tempElement = null;                                // Stores a temporary element
93     private int buttonState = MouseEvent.NOBUTTON;                     // Records button state
94     private Graphics2D g2D = null;                                     // Temporary graphics context
95    }
96
97   private Sketcher theApp;                                             // The application object
98 }

View Code

4、窗口框架:

  1 // Frame for the Sketcher application
  2 import javax.swing.*;
  3 import javax.swing.border.*;
  4 import java.awt.event.*;
  5 import java.awt.*;
  6
  7 import static java.awt.event.InputEvent.*;
  8 import static java.awt.AWTEvent.*;
  9 import static java.awt.Color.*;
 10 import static Constants.SketcherConstants.*;
 11 import static javax.swing.Action.*;
 12
 13 @SuppressWarnings("serial")
 14 public class SketcherFrame extends JFrame {
 15   // Constructor
 16   public SketcherFrame(String title, Sketcher theApp) {
 17     setTitle(title);                                                   // Set the window title
 18     this.theApp = theApp;                                              // Save app. object reference
 19     setJMenuBar(menuBar);                                              // Add the menu bar to the window
 20     setDefaultCloseOperation(EXIT_ON_CLOSE);                           // Default is exit the application
 21
 22     createFileMenu();                                                  // Create the File menu
 23     createElementMenu();                                               // Create the element menu
 24     createColorMenu();                                                 // Create the element menu
 25     createToolbar();
 26     toolBar.setRollover(true);
 27     getContentPane().add(toolBar, BorderLayout.NORTH);
 28   }
 29
 30   // Create File menu item actions
 31   private void createFileMenuActions() {
 32     newAction = new FileAction("New", 'N', CTRL_DOWN_MASK);
 33     openAction = new FileAction("Open", 'O', CTRL_DOWN_MASK);
 34     closeAction = new FileAction("Close");
 35     saveAction = new FileAction("Save", 'S', CTRL_DOWN_MASK);
 36     saveAsAction = new FileAction("Save As...");
 37     printAction = new FileAction("Print", 'P', CTRL_DOWN_MASK);
 38     exitAction = new FileAction("Exit", 'X', CTRL_DOWN_MASK);
 39
 40     // Initialize the array
 41     FileAction[] actions = {openAction, closeAction, saveAction, saveAsAction, printAction, exitAction};
 42     fileActions = actions;
 43
 44     // Add toolbar icons
 45     newAction.putValue(LARGE_ICON_KEY, NEW24);
 46     openAction.putValue(LARGE_ICON_KEY, OPEN24);
 47     saveAction.putValue(LARGE_ICON_KEY, SAVE24);
 48     saveAsAction.putValue(LARGE_ICON_KEY, SAVEAS24);
 49     printAction.putValue(LARGE_ICON_KEY, PRINT24);
 50
 51     // Add menu item icons
 52     newAction.putValue(SMALL_ICON, NEW16);
 53     openAction.putValue(SMALL_ICON, OPEN16);
 54     saveAction.putValue(SMALL_ICON, SAVE16);
 55     saveAsAction.putValue(SMALL_ICON,SAVEAS16);
 56     printAction.putValue(SMALL_ICON, PRINT16);
 57
 58     // Add tooltip text
 59     newAction.putValue(SHORT_DESCRIPTION, "Create a new sketch");
 60     openAction.putValue(SHORT_DESCRIPTION, "Read a sketch from a file");
 61     closeAction.putValue(SHORT_DESCRIPTION, "Close the current sketch");
 62     saveAction.putValue(SHORT_DESCRIPTION, "Save the current sketch to file");
 63     saveAsAction.putValue(SHORT_DESCRIPTION, "Save the current sketch to a new file");
 64     printAction.putValue(SHORT_DESCRIPTION, "Print the current sketch");
 65     exitAction.putValue(SHORT_DESCRIPTION, "Exit Sketcher");
 66   }
 67
 68   // Create the File menu
 69   private void createFileMenu() {
 70     JMenu fileMenu = new JMenu("File");                                // Create File menu
 71     fileMenu.setMnemonic('F');                                         // Create shortcut
 72     createFileMenuActions();                                           // Create Actions for File menu item
 73
 74     // Construct the file drop-down menu
 75     fileMenu.add(newAction);                                           // New Sketch menu item
 76     fileMenu.add(openAction);                                          // Open sketch menu item
 77     fileMenu.add(closeAction);                                         // Close sketch menu item
 78     fileMenu.addSeparator();                                           // Add separator
 79     fileMenu.add(saveAction);                                          // Save sketch to file
 80     fileMenu.add(saveAsAction);                                        // Save As menu item
 81     fileMenu.addSeparator();                                           // Add separator
 82     fileMenu.add(printAction);                                         // Print sketch menu item
 83     fileMenu.addSeparator();                                           // Add separator
 84     fileMenu.add(exitAction);                                          // Print sketch menu item
 85     menuBar.add(fileMenu);                                             // Add the file menu
 86   }
 87
 88   // Create Element  menu actions
 89   private void createElementTypeActions() {
 90     lineAction = new TypeAction("Line", LINE, 'L', CTRL_DOWN_MASK);
 91     rectangleAction = new TypeAction("Rectangle", RECTANGLE, 'R', CTRL_DOWN_MASK);
 92     circleAction =  new TypeAction("Circle", CIRCLE,'C', CTRL_DOWN_MASK);
 93     curveAction = new TypeAction("Curve", CURVE,'U', CTRL_DOWN_MASK);
 94
 95     // Initialize the array
 96     TypeAction[] actions = {lineAction, rectangleAction, circleAction, curveAction};
 97     typeActions = actions;
 98
 99     // Add toolbar icons
100     lineAction.putValue(LARGE_ICON_KEY, LINE24);
101     rectangleAction.putValue(LARGE_ICON_KEY, RECTANGLE24);
102     circleAction.putValue(LARGE_ICON_KEY, CIRCLE24);
103     curveAction.putValue(LARGE_ICON_KEY, CURVE24);
104
105     // Add menu item icons
106     lineAction.putValue(SMALL_ICON, LINE16);
107     rectangleAction.putValue(SMALL_ICON, RECTANGLE16);
108     circleAction.putValue(SMALL_ICON, CIRCLE16);
109     curveAction.putValue(SMALL_ICON, CURVE16);
110
111     // Add tooltip text
112     lineAction.putValue(SHORT_DESCRIPTION, "Draw lines");
113     rectangleAction.putValue(SHORT_DESCRIPTION, "Draw rectangles");
114     circleAction.putValue(SHORT_DESCRIPTION, "Draw circles");
115     curveAction.putValue(SHORT_DESCRIPTION, "Draw curves");
116   }
117
118   // Create the Elements menu
119   private void createElementMenu() {
120     createElementTypeActions();
121     elementMenu = new JMenu("Elements");                               // Create Elements menu
122     elementMenu.setMnemonic('E');                                      // Create shortcut
123     createRadioButtonDropDown(elementMenu, typeActions, lineAction);
124     menuBar.add(elementMenu);                                          // Add the element menu
125   }
126
127   // Create Color menu actions
128   private void createElementColorActions() {
129     redAction = new ColorAction("Red", RED, 'R', CTRL_DOWN_MASK|ALT_DOWN_MASK);
130     yellowAction = new ColorAction("Yellow", YELLOW, 'Y', CTRL_DOWN_MASK|ALT_DOWN_MASK);
131     greenAction = new ColorAction("Green", GREEN, 'G', CTRL_DOWN_MASK|ALT_DOWN_MASK);
132     blueAction = new ColorAction("Blue", BLUE, 'B', CTRL_DOWN_MASK|ALT_DOWN_MASK);
133
134     // Initialize the array
135     ColorAction[] actions = {redAction, greenAction, blueAction, yellowAction};
136     colorActions = actions;
137
138     // Add toolbar icons
139     redAction.putValue(LARGE_ICON_KEY, RED24);
140     greenAction.putValue(LARGE_ICON_KEY, GREEN24);
141     blueAction.putValue(LARGE_ICON_KEY, BLUE24);
142     yellowAction.putValue(LARGE_ICON_KEY, YELLOW24);
143
144     // Add menu item icons
145     redAction.putValue(SMALL_ICON, RED16);
146     blueAction.putValue(SMALL_ICON, BLUE16);
147     greenAction.putValue(SMALL_ICON, GREEN16);
148     yellowAction.putValue(SMALL_ICON, YELLOW16);
149
150     // Add tooltip text
151     redAction.putValue(SHORT_DESCRIPTION, "Draw in red");
152     blueAction.putValue(SHORT_DESCRIPTION, "Draw in blue");
153     greenAction.putValue(SHORT_DESCRIPTION, "Draw in green");
154     yellowAction.putValue(SHORT_DESCRIPTION, "Draw in yellow");
155   }
156
157   // Create the Color menu
158   private void createColorMenu() {
159     createElementColorActions();
160     colorMenu = new JMenu("Color");                                    // Create Elements menu
161     colorMenu.setMnemonic('C');                                        // Create shortcut
162     createRadioButtonDropDown(colorMenu, colorActions, blueAction);
163     menuBar.add(colorMenu);                                            // Add the color menu
164   }
165
166   // Menu creation helper
167   private void createRadioButtonDropDown(JMenu menu, Action[] actions, Action selected) {
168     ButtonGroup group = new ButtonGroup();
169     JRadioButtonMenuItem item = null;
170     for(Action action : actions) {
171       group.add(menu.add(item = new JRadioButtonMenuItem(action)));
172       if(action == selected) {
173         item.setSelected(true);                                        // This is default selected
174       }
175     }
176   }
177
178   // Create toolbar buttons on the toolbar
179   private void createToolbar() {
180     for(FileAction action: fileActions){
181       if(action != exitAction && action != closeAction)
182         addToolbarButton(action);                                      // Add the toolbar button
183     }
184     toolBar.addSeparator();
185
186     // Create Color menu buttons
187     for(ColorAction action:colorActions){
188         addToolbarButton(action);                                      // Add the toolbar button
189     }
190
191     toolBar.addSeparator();
192
193     // Create Elements menu buttons
194     for(TypeAction action:typeActions){
195         addToolbarButton(action);                                      // Add the toolbar button
196     }
197  }
198
199   // Create and add a toolbar button
200   private void addToolbarButton(Action action) {
201     JButton button = new JButton(action);                              // Create from Action
202     button.setBorder(BorderFactory.createCompoundBorder(               // Add button border
203            new EmptyBorder(2,5,5,2),                                   // Outside border
204            BorderFactory.createRaisedBevelBorder()));                  // Inside border
205     button.setHideActionText(true);                                    // No label on the button
206     toolBar.add(button);                                               // Add the toolbar button
207   }
208
209   // Return the current drawing color
210   public Color getElementColor() {
211     return elementColor;
212   }
213
214   // Return the current element type
215   public int getElementType() {
216     return elementType;
217   }
218
219   // Set radio button menu checks
220   private void setChecks(JMenu menu, Object eventSource) {
221     if(eventSource instanceof JButton){
222       JButton button = (JButton)eventSource;
223       Action action = button.getAction();
224       for(int i = 0 ; i<menu.getItemCount() ; ++i) {
225         JMenuItem item = menu.getItem(i);
226         item.setSelected(item.getAction() == action);
227       }
228     }
229   }
230
231   // Inner class defining Action objects for File menu items
232   class FileAction extends AbstractAction {
233     // Create action with a name
234     FileAction(String name) {
235       super(name);
236     }
237
238     // Create action with a name and accelerator
239     FileAction(String name, char ch, int modifiers) {
240       super(name);
241       putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
242
243       // Now find the character to underline
244       int index = name.toUpperCase().indexOf(ch);
245       if(index != -1) {
246         putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
247       }
248     }
249
250     // Event handler
251     public void actionPerformed(ActionEvent e) {
252       // You will add action code here eventually...
253     }
254   }
255
256   // Inner class defining Action objects for Element type menu items
257   class TypeAction extends AbstractAction {
258     // Create action with just a name property
259     TypeAction(String name, int typeID) {
260       super(name);
261       this.typeID = typeID;
262     }
263
264     // Create action with a name and an accelerator
265     private TypeAction(String name,int typeID, char ch, int modifiers) {
266       this(name, typeID);
267       putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
268
269       // Now find the character to underline
270       int index = name.toUpperCase().indexOf(ch);
271       if(index != -1) {
272         putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
273       }
274     }
275
276     public void actionPerformed(ActionEvent e) {
277       elementType = typeID;
278       setChecks(elementMenu, e.getSource());
279     }
280
281     private int typeID;
282   }
283
284   // Handles color menu items
285   class ColorAction  extends AbstractAction {
286     // Create an action with a name and a color
287     public ColorAction(String name, Color color) {
288       super(name);
289       this.color = color;
290     }
291
292     // Create an action with a name, a color, and an accelerator
293     public ColorAction(String name, Color color, char ch, int modifiers) {
294       this(name, color);
295       putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
296
297       // Now find the character to underline
298       int index = name.toUpperCase().indexOf(ch);
299       if(index != -1) {
300         putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
301       }
302     }
303
304     public void actionPerformed(ActionEvent e) {
305       elementColor = color;
306       setChecks(colorMenu, e.getSource());
307     }
308
309     private Color color;
310   }
311
312   // File actions
313   private FileAction newAction, openAction, closeAction, saveAction, saveAsAction, printAction, exitAction;
314   private FileAction[] fileActions;                                    // File actions as an array
315
316   // Element type actions
317   private TypeAction lineAction, rectangleAction, circleAction, curveAction;
318   private TypeAction[] typeActions;                                    // Type actions as an array
319
320 // Element color actions
321   private ColorAction redAction, yellowAction,greenAction, blueAction;
322   private ColorAction[] colorActions;                                  // Color actions as an array
323
324   private JMenuBar menuBar = new JMenuBar();                           // Window menu bar
325   private JMenu elementMenu;                                           // Elements menu
326   private JMenu colorMenu;                                             // Color menu
327
328   private Color elementColor = DEFAULT_ELEMENT_COLOR;                  // Current element color
329   private int elementType = DEFAULT_ELEMENT_TYPE;                      // Current element type
330   private JToolBar toolBar = new JToolBar();                           // Window toolbar
331   private Sketcher theApp;                                             // The application object
332 }

View Code

5、自定义常量包:

 1 // Defines application wide constants
 2 package Constants;
 3 import java.awt.Color;
 4 import javax.swing.*;
 5
 6 public class SketcherConstants {
 7   // Path for images
 8   public final static String imagePath = "E:/JavaProject/BeginningJava/Images/";
 9
10   // Toolbar icons
11   public final static Icon NEW24 = new ImageIcon(imagePath + "New24.gif");
12   public final static Icon OPEN24 = new ImageIcon(imagePath + "Open24.gif");
13   public final static Icon SAVE24 = new ImageIcon(imagePath + "Save24.gif");
14   public final static Icon SAVEAS24 = new ImageIcon(imagePath + "SaveAs24.gif");
15   public final static Icon PRINT24 = new ImageIcon(imagePath + "Print24.gif");
16
17   public final static Icon LINE24 = new ImageIcon(imagePath + "Line24.gif");
18   public final static Icon RECTANGLE24 = new ImageIcon(imagePath + "Rectangle24.gif");
19   public final static Icon CIRCLE24 = new ImageIcon(imagePath + "Circle24.gif");
20   public final static Icon CURVE24 = new ImageIcon(imagePath + "Curve24.gif");
21
22   public final static Icon RED24 = new ImageIcon(imagePath + "Red24.gif");
23   public final static Icon GREEN24 = new ImageIcon(imagePath + "Green24.gif");
24   public final static Icon BLUE24 = new ImageIcon(imagePath + "Blue24.gif");
25   public final static Icon YELLOW24 = new ImageIcon(imagePath + "Yellow24.gif");
26
27   // Menu item icons
28   public final static Icon NEW16 = new ImageIcon(imagePath + "new16.gif");
29   public final static Icon OPEN16 = new ImageIcon(imagePath + "Open16.gif");
30   public final static Icon SAVE16 = new ImageIcon(imagePath + "Save16.gif");
31   public final static Icon SAVEAS16 = new ImageIcon(imagePath + "SaveAs16.gif");
32   public final static Icon PRINT16 = new ImageIcon(imagePath + "print16.gif");
33
34   public final static Icon LINE16 = new ImageIcon(imagePath + "Line16.gif");
35   public final static Icon RECTANGLE16 = new ImageIcon(imagePath + "Rectangle16.gif");
36   public final static Icon CIRCLE16 = new ImageIcon(imagePath + "Circle16.gif");
37   public final static Icon CURVE16 = new ImageIcon(imagePath + "Curve16.gif");
38
39   public final static Icon RED16 = new ImageIcon(imagePath + "Red16.gif");
40   public final static Icon GREEN16 = new ImageIcon(imagePath + "Green16.gif");
41   public final static Icon BLUE16 = new ImageIcon(imagePath + "Blue16.gif");
42   public final static Icon YELLOW16 = new ImageIcon(imagePath + "Yellow16.gif");
43
44   // Element type definitions
45   public final static int LINE      = 101;
46   public final static int RECTANGLE = 102;
47   public final static int CIRCLE    = 103;
48   public final static int CURVE     = 104;
49
50   // Initial conditions
51   public final static int DEFAULT_ELEMENT_TYPE = LINE;
52   public final static Color DEFAULT_ELEMENT_COLOR = Color.BLUE;
53 }

View Code

6、应用程序主程序:

 1 // Sketching application
 2 import javax.swing.*;
 3 import java.awt.*;
 4 import java.awt.event.*;
 5
 6 public class Sketcher {
 7   public static void main(String[] args) {
 8      theApp = new Sketcher();                                          // Create the application object
 9    SwingUtilities.invokeLater(new Runnable() {
10             public void run() {
11                           theApp.createGUI();                          // Call GUI creator
12             }
13         });
14   }
15
16   // Method to create the application GUI
17   private void createGUI() {
18     window = new SketcherFrame("Sketcher", this);                      // Create the app window
19     Toolkit theKit = window.getToolkit();                              // Get the window toolkit
20     Dimension wndSize = theKit.getScreenSize();                        // Get screen size
21
22     // Set the position to screen center & size to half screen size
23     window.setSize(wndSize.width/2, wndSize.height/2);                 // Set window size
24     window.setLocationRelativeTo(null);                                // Center window
25
26     window.addWindowListener(new WindowHandler());                     // Add window listener
27
28     sketch = new SketcherModel();                                      // Create the model
29     view = new SketcherView(this);                                     // Create the view
30     sketch.addObserver(view);                                          // Register view with the model
31     window.getContentPane().add(view, BorderLayout.CENTER);
32     window.setVisible(true);
33   }
34
35   // Return a reference to the application window
36   public SketcherFrame getWindow() {
37      return window;
38   }
39
40   // Return a reference to the model
41   public SketcherModel getModel() {
42      return sketch;
43   }
44
45   // Return a reference to the view
46   public SketcherView getView() {
47      return view;
48   }
49
50   // Handler class for window events
51   class WindowHandler extends WindowAdapter {
52     // Handler for window closing event
53     @Override
54     public void windowClosing(WindowEvent e) {
55       // Code to be added here...
56     }
57   }
58
59   private SketcherModel sketch;                                        // The data model for the sketch
60   private SketcherView view;                                           // The view of the sketch
61   private SketcherFrame window;                                        // The application window
62   private static Sketcher theApp;                                      // The application object
63 }

View Code

转载于:https://www.cnblogs.com/mannixiang/p/3489909.html

Java基础之在窗口中绘图——利用多态性使用鼠标自由绘图(Sketcher 7 with a crosshair cursor)...相关推荐

  1. Java基础之在窗口中绘图——使用模型/视图体系结构在视图中绘图(Sketcher 1 drawing a 3D rectangle)...

    控制台程序. 在模型中表示数据视图的类用来显示草图并处理用户的交互操作,所以这种类把显示方法和草图控制器合并在一起.不专用于某个视图的通用GUI创建和操作在SketcherFrame类中处理. 模型对 ...

  2. Java基础之在窗口中绘图——绘制圆弧和椭圆(Sketcher 3 drawing arcs and ellipses)

    控制台程序. 1 import javax.swing.JComponent; 2 import java.util.*; 3 import java.awt.*; 4 import java.awt ...

  3. Java基础之在窗口中绘图——绘制直线和矩形(Sketcher 2 drawing lines and rectangles)...

    控制台程序. 1 import javax.swing.JComponent; 2 import java.util.*; 3 import java.awt.*; 4 import java.awt ...

  4. java 绘制长方形_Java基础之在窗口中绘图——绘制直线和矩形(Sketcher 2 drawing lines and rectangles)...

    控制台程序. import javax.swing.JComponent; import java.util.*; import java.awt.*; import java.awt.geom.*; ...

  5. JAVA基础(持续更新中)

    JAVA基础 2020年11月27日 21:01 1 预科 a. 什么是计算机 能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备. 由硬件常见的形式有台式计算机.笔记本计算机.大型计算机等 ...

  6. Java基础核心总结(编辑中)

    Java概述 什么是Java? Java是Sun Microsystems于1995年首次发布的一种编程语言和计算平台.编程语言还比较好理 解,那么什么是计算平台呢? 计算平台是在电脑中运行应用程序( ...

  7. Java基础:IO 流中的 flush

    无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点 这里 可以跳转到教程. 内容概要 Java IO ...

  8. java基础—统计一个字符串中各个字符出现的次数

    统计一个字符串中各个字符出现的次数 import java.util.Iterator; import java.util.Set; import java.util.TreeMap;public c ...

  9. 【java基础 12】HashMap中是如何形成环形链表的?

    导读:经过前面的博客总结,可以知道的是,HashMap是有一个一维数组和一个链表组成,从而得知,在解决冲突问题时,hashmap选择的是链地址法.为什么HashMap会用一个数组这链表组成,当时给出的 ...

最新文章

  1. 微软发布多项Azure Kubernetes服务更新,增加GPU支持
  2. 机器人雅可比矩阵的求法_构造法
  3. 使用VMware进行基于Ubuntu16.04LTS的Spark集群搭建
  4. Win10系统的SurfacePro4如何重装系统-3 重装完成之后的系统优化
  5. 重磅!阿里云MongoDB 5.0发布,速来围观新特性
  6. 基于Netty的http服务器
  7. Appium+python自动化8-Appium Python API
  8. BZOJ4590: [Shoi2015]自动刷题机
  9. [05] Session概要
  10. python基础(14)之 类和对象
  11. 读写自旋锁详解,第 3 部分(来自IBM)
  12. map-reduce 、map、reduce
  13. openstack ha 部署
  14. JS的 setTimeout 和 bind 使用 、复选框限制选定数据jq
  15. 高并发高可用高性能的解决方案
  16. 怎么安装64位JAVA,大师来详解
  17. 小程序中如何引用阿里图标
  18. windows命令修改IP地址
  19. javascript自动分号补齐带来的坑
  20. DATAGUARD手记(DUPLICATE)(四)

热门文章

  1. 续集来了!我让 GPT-4 用 Laf 三分钟写了个完整的待办事项 App
  2. python逐步回归筛选变量_Python实现逐步回归(stepwise regression)
  3. 咖说 | 匿名的「N号房」:数字货币是否应当拥抱监管?
  4. 中国第一计算机编程高手横瓜的天才求职之路异常艰辛,天妒奇才呀
  5. SpringBoot重点详解--@JoinColumn注解
  6. 下载nyuv2数据集
  7. 福特 EPC数据采集成功
  8. TF+ OpenStack部署指南丨利用OpenStack TF配置虚拟网络
  9. Unity URP介绍
  10. “SCSA-T学习导图+”系列:IPSec VPN原理与应用