Java基础之扩展GUI——使用对话框创建文本元素(Sketcher 4 creating text elements)

控制台程序。

为了与Sketcher中的其他元素类型保持一致,需要为Elements菜单添加Text菜单项和工具栏按钮。还需要定义用来表示文本元素的类Element.Text。

1、修改SketcherFrame类添加文本定义菜单项和工具栏按钮:

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

2、定义文本类:

  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);
 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     protected boolean highlighted = false;                              // Highlight flag
 77     private final static long serialVersionUID = 1001L;
 78   }
 79 
 80   // Nested class defining a rectangle
 81   public static class Rectangle extends Element {
 82     public Rectangle(Point start, Point end, Color color) {
 83       super(new Point(Math.min(start.x, end.x), Math.min(start.y, end.y)), color);
 84       rectangle = new Rectangle2D.Double(
 85         origin.x, origin.y,                                             // Top-left corner
 86         Math.abs(start.x - end.x), Math.abs(start.y - end.y));          // Width & height
 87       bounds = new java.awt.Rectangle(
 88                     Math.min(start.x ,end.x),    Math.min(start.y, end.y),
 89                     Math.abs(start.x - end.x)+1, Math.abs(start.y - end.y)+1);
 90     }
 91 
 92     // Display the rectangle
 93     public  void draw(Graphics2D g2D) {
 94       g2D.setPaint(color);
 95       g2D.translate(position.x, position.y);                            // Move context origin
 96       g2D.draw(rectangle);                                              // Draw the rectangle
 97       g2D.translate(-position.x, -position.y);                          // Move context origin back
 98     }
 99 
100     // Method to redefine the rectangle
101     public void modify(Point start, Point last) {
102       bounds.x = position.x = Math.min(start.x, last.x);
103       bounds.y = position.y = Math.min(start.y, last.y);
104       rectangle.width = Math.abs(start.x - last.x);
105       rectangle.height = Math.abs(start.y - last.y);
106       bounds.width = (int)rectangle.width +1;
107       bounds.height = (int)rectangle.height + 1;
108     }
109 
110     private Rectangle2D.Double rectangle;
111     private final static long serialVersionUID = 1001L;
112   }
113 
114   // Nested class defining a circle
115   public static class Circle extends Element {
116     public Circle(Point center, Point circum, Color color) {
117       super(color);
118 
119       // Radius is distance from center to circumference
120       double radius = center.distance(circum);
121       position = new Point(center.x - (int)radius, center.y - (int)radius);
122       circle = new Ellipse2D.Double(origin.x, origin.y, 2.*radius, 2.*radius);
123       bounds = new java.awt.Rectangle(position.x, position.y,
124                               1 + (int)circle.width, 1+(int)circle.height);
125     }
126 
127     // Display the circle
128     public  void draw(Graphics2D g2D) {
129       g2D.setPaint(color);
130       g2D.translate(position.x, position.y);                            // Move context origin
131       g2D.draw(circle);                                                 // Draw the circle
132       g2D.translate(-position.x, -position.y);                          // Move context origin back
133     }
134 
135     // Recreate this circle
136     public void modify(Point center, Point circum) {
137       double radius = center.distance(circum);
138       circle.width = circle.height = 2*radius;
139       position.x = center.x - (int)radius;
140       position.y = center.y - (int)radius;
141       bounds = new java.awt.Rectangle(position.x, position.y,
142                               1 + (int)circle.width, 1+(int)circle.height);
143     }
144 
145     private Ellipse2D.Double circle;
146     private final static long serialVersionUID = 1001L;
147   }
148 
149   // Nested class defining a curve
150   public static class Curve extends Element {
151     public Curve(Point start, Point next, Color color) {
152       super(start, color);
153       curve = new GeneralPath();
154       curve.moveTo(origin.x, origin.y);                                 // Set current position as origin
155       curve.lineTo(next.x - position.x, next.y - position.y);           // Add segment
156       bounds = new java.awt.Rectangle(
157                    Math.min(start.x, next.x),    Math.min(start.y, next.y),
158                    Math.abs(next.x - start.x)+1, Math.abs(next.y - start.y)+1);
159     }
160 
161     // Add another segment
162     public void modify(Point start, Point next) {
163       curve.lineTo(next.x - position.x, next.y - position.y);           // Add segment
164       bounds.add(new java.awt.Rectangle(next.x,next.y, 1, 1));          // Extend bounds
165     }
166 
167 
168     // Display the curve
169     public  void draw(Graphics2D g2D) {
170       g2D.setPaint(color);
171       g2D.translate(position.x, position.y);                            // Move context origin
172       g2D.draw(curve);                                                  // Draw the curve
173       g2D.translate(-position.x, -position.y);                          // Move context origin back
174     }
175 
176     private GeneralPath curve;
177     private final static long serialVersionUID = 1001L;
178   }
179 
180   // Nested class defining a Text element
181   public static class Text extends Element  {
182     public Text(String text, Point start, Color color, FontMetrics fm) {
183       super(start, color);
184       this.text = text;
185       this.font = fm.getFont();
186         maxAscent = fm.getMaxAscent();
187         bounds = new java.awt.Rectangle(position.x, position.y,
188                  fm.stringWidth(text) + 4, maxAscent+ fm.getMaxDescent() + 4);
189                 System.out.println(bounds);
190     }
191 
192     public void draw(Graphics2D g2D)  {
193       g2D.setPaint(color);
194       Font oldFont = g2D.getFont();                                     // Save the old font
195       g2D.setFont(font);                                                // Set the new font
196       // Reference point for drawString() is the baseline of the 1st character
197       g2D.drawString(text, position.x + 2, position.y + maxAscent + 2);
198       g2D.setFont(oldFont);                                             // Restore the old font
199     }
200 
201     public void modify(Point start, Point last) {
202       // No code is required here, but you must supply a definition
203     }
204 
205     private Font font;                                                  // The font to be used
206     private int maxAscent;                                              // Maximum ascent
207     private String text;                                                // Text to be displayed
208     private final static long serialVersionUID = 1001L;
209   }
210 
211   // Abstract Element class methods
212   public abstract void draw(Graphics2D g2D);
213   public abstract void modify(Point start, Point last);
214 
215   // Element class fields
216   protected Point position;                                             // Position of a shape
217   protected Color color;                                                // Color of a shape
218   protected java.awt.Rectangle bounds;                                  // Bounding rectangle
219   protected static final Point origin = new Point();                    // Origin for elements
220   private final static long serialVersionUID = 1001L;
221 }
View Code

3、修改视图类,通过mouseClicked()事件处理创建文本事件:

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


遗留问题:

在定义文本类中Text类的构造函数中最后有一句System.out.println(bounds)不懂:

1 public Text(String text, Point start, Color color, FontMetrics fm) {
2       super(start, color);
3       this.text = text;
4       this.font = fm.getFont();
5         maxAscent = fm.getMaxAscent();
6         bounds = new java.awt.Rectangle(position.x, position.y,
7                  fm.stringWidth(text) + 4, maxAscent+ fm.getMaxDescent() + 4);
8                 System.out.println(bounds);
9     }

注释掉这句后好像和没注释一样效果。

 

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值