• 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     }

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

  • 相关阅读:
    Docker 学习笔记
    Docker 镜像加速器(如何加速下载)
    Simple-DQN代码的理解笔记
    c语言NULL和0区别及NULL详解
    C 语言的 const 指针,指针的const有什么不同
    Edge和Level触发的中断
    尚硅谷设计模式笔记-适配器模式
    nginx服务器部署dist文件夹
    nginx服务器部署dist文件夹
    Jexl表达式引擎-根据字符串动态执行JAVA.md
  • 原文地址:https://www.cnblogs.com/mannixiang/p/3496590.html
Copyright © 2020-2023  润新知