zoukankan      html  css  js  c++  java
  • Java基础之在窗口中绘图——使用模型/视图体系结构在视图中绘图(Sketcher 1 drawing a 3D rectangle)

    控制台程序。

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

    模型对象包含构成草图的文本和图形。模型类可以称为SketcherModel,表示模型视图的类可以称为SketcherView.

    应用程序对象全面负责管理程序涉及的其他对象之间的链接。只要应用程序类能使每个对象可用,可以访问应用程序对象的任何对象就都要与其他对象进行通信。因此,应用程序对象是对象之间的通信通道。

    注意:SketcherFrame不是视图类,这个类仅仅定义应用程序窗口及其关联的GUI组件。创建SketcherView对象时,应把SketcherView对象插入到SketcherFrame对象的内容面板中,并使用内容面板的布局管理器进行管理。通过将视图类与应用程序类分开定义,就可以把草图的视图与用于和程序交互的菜单及其他组件分开。这么做的优点是显示草图的区域能拥有自己的坐标系统,这种坐标系统独立于应用程序窗口的坐标系统。

    1、SketcherModel类:

    1 import java.io.Serializable;
    2 import java.util.Observable;
    3 
    4 public class SketcherModel extends Observable implements Serializable {
    5   // Detail of the rest of class to be filled in later...
    6   private final static long serialVersionUID = 1001L;
    7 }

    这个类可以串行化,因为我们希望把草图保存到文件中。SketcherModel类扩展了Observable类,所以可以使用这个类把视图类注册为观察器,并将视图的任何变化自动通知给模型。当草图拥有多个视图时,这个功能就会很有用。

    2、SketcherView类:

     1 import javax.swing.JComponent;
     2 import java.util.*;
     3 import java.awt.*;
     4 
     5 @SuppressWarnings("serial")
     6 public class SketcherView extends JComponent implements Observer {
     7   public SketcherView(Sketcher theApp) {
     8     this.theApp = theApp;
     9   }
    10 
    11   // Method called by Observable object when it changes
    12   public void update(Observable o, Object rectangle) {
    13     // Code to respond to changes in the model...
    14   }
    15 
    16   // Method to draw on the view
    17   @Override
    18   public void paint(Graphics g) {
    19     // Temporary code...
    20     Graphics2D g2D = (Graphics2D)g;                                    // Get a Java 2D device context
    21 
    22     g2D.setPaint(Color.RED);                                           // Draw in red
    23     g2D.draw3DRect(50, 50, 150, 100, true);                            // Draw a raised 3D rectangle
    24     g2D.drawString("A nice 3D rectangle", 60, 100);                    // Draw some text
    25   }
    26 
    27   private Sketcher theApp;                                             // The application object
    28 }

    视图需要访问模型才能显示,但构造函数不是在视图中保存对模型的引用,而是让应用程序对象通过参数把引用传送给视图。视图对象可以使用应用程序对象来访问模型对象,如果需要,还可以访问应用程序窗口。
    视图注册为模型的观察器。如果存在完全不同的对象表示模型,例如要加载新的文件,视图对象就会自动获得模型已发生改变的通知,并且能重绘视图作为响应。

    3、Sketcher类:

     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 }

    Sketcher类中的新方法返回对应用程序窗口、模型和视图的引用,所以在Sketcher应用程序代码的任何地方,只要有对应用程序对象的引用,就可以访问它们。
    在Sketcher类的createGUI()方法中创建完模型和视图对象后,就把视图注册为模型的观察器,让模型在发生变化时通知视图。

    4、SketcherFrame类:

    // Frame for the Sketcher application
    import javax.swing.*;
    import javax.swing.border.*;
    import java.awt.event.*;
    import java.awt.*;
    
    import static java.awt.event.InputEvent.*;
    import static java.awt.AWTEvent.*;
    import static java.awt.Color.*;
    import static Constants.SketcherConstants.*;
    import static javax.swing.Action.*;
    
    @SuppressWarnings("serial")
    public class SketcherFrame extends JFrame {
      // Constructor
      public SketcherFrame(String title, Sketcher theApp) {
        setTitle(title);                                                   // Set the window title
        this.theApp = theApp;                                              // Save app. object reference
        setJMenuBar(menuBar);                                              // Add the menu bar to the window
        setDefaultCloseOperation(EXIT_ON_CLOSE);                           // Default is exit the application
    
        createFileMenu();                                                  // Create the File menu
        createElementMenu();                                               // Create the element menu
        createColorMenu();                                                 // Create the element menu
        createToolbar();
        toolBar.setRollover(true);
        getContentPane().add(toolBar, BorderLayout.NORTH);
      }
    
      // Create File menu item actions
      private void createFileMenuActions() {
        newAction = new FileAction("New", 'N', CTRL_DOWN_MASK);
        openAction = new FileAction("Open", 'O', CTRL_DOWN_MASK);
        closeAction = new FileAction("Close");
        saveAction = new FileAction("Save", 'S', CTRL_DOWN_MASK);
        saveAsAction = new FileAction("Save As...");
        printAction = new FileAction("Print", 'P', CTRL_DOWN_MASK);
        exitAction = new FileAction("Exit", 'X', CTRL_DOWN_MASK);
    
        // Initialize the array
        FileAction[] actions = {openAction, closeAction, saveAction, saveAsAction, printAction, exitAction};
        fileActions = actions;
    
        // Add toolbar icons
        newAction.putValue(LARGE_ICON_KEY, NEW24);
        openAction.putValue(LARGE_ICON_KEY, OPEN24);
        saveAction.putValue(LARGE_ICON_KEY, SAVE24);
        saveAsAction.putValue(LARGE_ICON_KEY, SAVEAS24);
        printAction.putValue(LARGE_ICON_KEY, PRINT24);
    
        // Add menu item icons
        newAction.putValue(SMALL_ICON, NEW16);
        openAction.putValue(SMALL_ICON, OPEN16);
        saveAction.putValue(SMALL_ICON, SAVE16);
        saveAsAction.putValue(SMALL_ICON,SAVEAS16);
        printAction.putValue(SMALL_ICON, PRINT16);
    
        // Add tooltip text
        newAction.putValue(SHORT_DESCRIPTION, "Create a new sketch");
        openAction.putValue(SHORT_DESCRIPTION, "Read a sketch from a file");
        closeAction.putValue(SHORT_DESCRIPTION, "Close the current sketch");
        saveAction.putValue(SHORT_DESCRIPTION, "Save the current sketch to file");
        saveAsAction.putValue(SHORT_DESCRIPTION, "Save the current sketch to a new file");
        printAction.putValue(SHORT_DESCRIPTION, "Print the current sketch");
        exitAction.putValue(SHORT_DESCRIPTION, "Exit Sketcher");
      }
    
      // Create the File menu
      private void createFileMenu() {
        JMenu fileMenu = new JMenu("File");                                // Create File menu
        fileMenu.setMnemonic('F');                                         // Create shortcut
        createFileMenuActions();                                           // Create Actions for File menu item
    
        // Construct the file drop-down menu
        fileMenu.add(newAction);                                           // New Sketch menu item
        fileMenu.add(openAction);                                          // Open sketch menu item
        fileMenu.add(closeAction);                                         // Close sketch menu item
        fileMenu.addSeparator();                                           // Add separator
        fileMenu.add(saveAction);                                          // Save sketch to file
        fileMenu.add(saveAsAction);                                        // Save As menu item
        fileMenu.addSeparator();                                           // Add separator
        fileMenu.add(printAction);                                         // Print sketch menu item
        fileMenu.addSeparator();                                           // Add separator
        fileMenu.add(exitAction);                                          // Print sketch menu item
        menuBar.add(fileMenu);                                             // Add the file menu
      }
    
      // Create Element  menu actions
      private void createElementTypeActions() {
        lineAction = new TypeAction("Line", LINE, 'L', CTRL_DOWN_MASK);
        rectangleAction = new TypeAction("Rectangle", RECTANGLE, 'R', CTRL_DOWN_MASK);
        circleAction =  new TypeAction("Circle", CIRCLE,'C', CTRL_DOWN_MASK);
        curveAction = new TypeAction("Curve", CURVE,'U', CTRL_DOWN_MASK);
    
        // Initialize the array
        TypeAction[] actions = {lineAction, rectangleAction, circleAction, curveAction};
        typeActions = actions;
    
        // Add toolbar icons
        lineAction.putValue(LARGE_ICON_KEY, LINE24);
        rectangleAction.putValue(LARGE_ICON_KEY, RECTANGLE24);
        circleAction.putValue(LARGE_ICON_KEY, CIRCLE24);
        curveAction.putValue(LARGE_ICON_KEY, CURVE24);
    
        // Add menu item icons
        lineAction.putValue(SMALL_ICON, LINE16);
        rectangleAction.putValue(SMALL_ICON, RECTANGLE16);
        circleAction.putValue(SMALL_ICON, CIRCLE16);
        curveAction.putValue(SMALL_ICON, CURVE16);
    
        // Add tooltip text
        lineAction.putValue(SHORT_DESCRIPTION, "Draw lines");
        rectangleAction.putValue(SHORT_DESCRIPTION, "Draw rectangles");
        circleAction.putValue(SHORT_DESCRIPTION, "Draw circles");
        curveAction.putValue(SHORT_DESCRIPTION, "Draw curves");
      }
    
      // Create the Elements menu
      private void createElementMenu() {
        createElementTypeActions();
        elementMenu = new JMenu("Elements");                               // Create Elements menu
        elementMenu.setMnemonic('E');                                      // Create shortcut
        createRadioButtonDropDown(elementMenu, typeActions, lineAction);
        menuBar.add(elementMenu);                                          // Add the element menu
      }
    
      // Create Color menu actions
      private void createElementColorActions() {
        redAction = new ColorAction("Red", RED, 'R', CTRL_DOWN_MASK|ALT_DOWN_MASK);
        yellowAction = new ColorAction("Yellow", YELLOW, 'Y', CTRL_DOWN_MASK|ALT_DOWN_MASK);
        greenAction = new ColorAction("Green", GREEN, 'G', CTRL_DOWN_MASK|ALT_DOWN_MASK);
        blueAction = new ColorAction("Blue", BLUE, 'B', CTRL_DOWN_MASK|ALT_DOWN_MASK);
    
        // Initialize the array
        ColorAction[] actions = {redAction, greenAction, blueAction, yellowAction};
        colorActions = actions;
    
        // Add toolbar icons
        redAction.putValue(LARGE_ICON_KEY, RED24);
        greenAction.putValue(LARGE_ICON_KEY, GREEN24);
        blueAction.putValue(LARGE_ICON_KEY, BLUE24);
        yellowAction.putValue(LARGE_ICON_KEY, YELLOW24);
    
        // Add menu item icons
        redAction.putValue(SMALL_ICON, RED16);
        blueAction.putValue(SMALL_ICON, BLUE16);
        greenAction.putValue(SMALL_ICON, GREEN16);
        yellowAction.putValue(SMALL_ICON, YELLOW16);
    
        // Add tooltip text
        redAction.putValue(SHORT_DESCRIPTION, "Draw in red");
        blueAction.putValue(SHORT_DESCRIPTION, "Draw in blue");
        greenAction.putValue(SHORT_DESCRIPTION, "Draw in green");
        yellowAction.putValue(SHORT_DESCRIPTION, "Draw in yellow");
      }
    
      // Create the Color menu
      private void createColorMenu() {
        createElementColorActions();
        colorMenu = new JMenu("Color");                                    // Create Elements menu
        colorMenu.setMnemonic('C');                                        // Create shortcut
        createRadioButtonDropDown(colorMenu, colorActions, blueAction);
        menuBar.add(colorMenu);                                            // Add the color menu
      }
    
      // Menu creation helper
      private void createRadioButtonDropDown(JMenu menu, Action[] actions, Action selected) {
        ButtonGroup group = new ButtonGroup();
        JRadioButtonMenuItem item = null;
        for(Action action : actions) {
          group.add(menu.add(item = new JRadioButtonMenuItem(action)));
          if(action == selected) {
            item.setSelected(true);                                        // This is default selected
          }
        }
      }
    
      // Create toolbar buttons on the toolbar
      private void createToolbar() {
        for(FileAction action: fileActions){
          if(action != exitAction && action != closeAction)
            addToolbarButton(action);                                      // Add the toolbar button
        }
        toolBar.addSeparator();
    
        // Create Color menu buttons
        for(ColorAction action:colorActions){
            addToolbarButton(action);                                      // Add the toolbar button
        }
    
        toolBar.addSeparator();
    
        // Create Elements menu buttons
        for(TypeAction action:typeActions){
            addToolbarButton(action);                                      // Add the toolbar button
        }
     }
    
      // Create and add a toolbar button
      private void addToolbarButton(Action action) {
        JButton button = new JButton(action);                              // Create from Action
        button.setBorder(BorderFactory.createCompoundBorder(               // Add button border
               new EmptyBorder(2,5,5,2),                                   // Outside border
               BorderFactory.createRaisedBevelBorder()));                  // Inside border
        button.setHideActionText(true);                                    // No label on the button
        toolBar.add(button);                                               // Add the toolbar button
      }
    
      // Set radio button menu checks
      private void setChecks(JMenu menu, Object eventSource) {
        if(eventSource instanceof JButton){
          JButton button = (JButton)eventSource;
          Action action = button.getAction();
          for(int i = 0 ; i < menu.getItemCount() ; ++i) {
            JMenuItem item = menu.getItem(i);
            item.setSelected(item.getAction() == action);
          }
        }
      }
    
      // Inner class defining Action objects for File menu items
      class FileAction extends AbstractAction {
        // Create action with a name
        FileAction(String name) {
          super(name);
        }
    
        // Create action with a name and accelerator
        FileAction(String name, char ch, int modifiers) {
          super(name);
          putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
    
          // Now find the character to underline
          int index = name.toUpperCase().indexOf(ch);
          if(index != -1) {
            putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
          }
        }
    
        // Event handler
        public void actionPerformed(ActionEvent e) {
          // You will add action code here eventually...
        }
      }
    
      // Inner class defining Action objects for Element type menu items
      class TypeAction extends AbstractAction {
        // Create action with just a name property
        TypeAction(String name, int typeID) {
          super(name);
          this.typeID = typeID;
        }
    
        // Create action with a name and an accelerator
        private TypeAction(String name,int typeID, char ch, int modifiers) {
          this(name, typeID);
          putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
    
          // Now find the character to underline
          int index = name.toUpperCase().indexOf(ch);
          if(index != -1) {
            putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
          }
        }
    
        public void actionPerformed(ActionEvent e) {
          elementType = typeID;
          setChecks(elementMenu, e.getSource());
        }
    
        private int typeID;
      }
    
      // Handles color menu items
      class ColorAction  extends AbstractAction {
        // Create an action with a name and a color
        public ColorAction(String name, Color color) {
          super(name);
          this.color = color;
        }
    
        // Create an action with a name, a color, and an accelerator
        public ColorAction(String name, Color color, char ch, int modifiers) {
          this(name, color);
          putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(ch, modifiers));
    
          // Now find the character to underline
          int index = name.toUpperCase().indexOf(ch);
          if(index != -1) {
            putValue(DISPLAYED_MNEMONIC_INDEX_KEY, index);
          }
        }
    
        public void actionPerformed(ActionEvent e) {
          elementColor = color;
          setChecks(colorMenu, e.getSource());
        }
    
        private Color color;
      }
    
      // File actions
      private FileAction newAction, openAction, closeAction, saveAction, saveAsAction, printAction, exitAction;
      private FileAction[] fileActions;                                    // File actions as an array
    
      // Element type actions
      private TypeAction lineAction, rectangleAction, circleAction, curveAction;
      private TypeAction[] typeActions;                                    // Type actions as an array
    
    // Element color actions
      private ColorAction redAction, yellowAction,greenAction, blueAction;
      private ColorAction[] colorActions;                                  // Color actions as an array
    
      private JMenuBar menuBar = new JMenuBar();                           // Window menu bar
      private JMenu elementMenu;                                           // Elements menu
      private JMenu colorMenu;                                             // Color menu
    
      private Color elementColor = DEFAULT_ELEMENT_COLOR;                  // Current element color
      private int elementType = DEFAULT_ELEMENT_TYPE;                      // Current element type
      private JToolBar toolBar = new JToolBar();                           // Window toolbar
      private Sketcher theApp;                                             // The application object
    }
    View Code

    5、自定义常量包SketcherConstants:

     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
  • 相关阅读:
    开源魔兽世界私服搭建
    centos7 普通用户无法使用ssh登录其他服务器
    Java时间格式大全
    C#中的线程之Abort陷阱
    C# 多线程学习系列四之ThreadPool取消、超时子线程操作以及ManualResetEvent和AutoResetEvent信号量的使用
    C# ThreadPool类(线程池)
    VS2019输出信息到调试控制台
    Stream/Bytes[]/Image对象相互转化
    Asp.NetCore 读取配置文件帮助类
    Java SpringBoot使用126邮箱发送html内容邮件,带附件
  • 原文地址:https://www.cnblogs.com/mannixiang/p/3488325.html
Copyright © 2011-2022 走看看