如何使用模型视图控制器模式操作绘制的对象?

时间:2015-01-27 16:44:35

标签: java user-interface model-view-controller

我听说过java中用于复杂GUI的MPV(模型视图控制器)模式来操作绘制的对象。但我是MPV的新手,无法找到任何可以帮助我操纵绘制的对象的东西:

1 - 启用绘制的对象移动 2 - 允许重新调整绘制的对象的大小。

有人可以帮我解决这个问题吗?告诉我是否也可以使用MPV模式将这些对象存储在某处以备将来重用;能够调用函数或其他东西来获取这些对象的细节吗?

请帮助,对所有这些都是新手。 这是我的代码:

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ERD_BUILDER_ extends JFrame {

    private static final long serialVersionUID = -140274271716086522L;

    JMenuBar menubar;
    JMenu File, Exit;
    JMenuItem New, Open;
    JComponent DrawingBoard;

    JButton brushBut, lineBut, ellipseBut, rectBut, strokeBut, fillBut;

    // Slider used to change the transparency

    JSlider transSlider;

    JLabel transLabel;

    // Makes sure the float for transparency only shows 2 digits

    DecimalFormat dec = new DecimalFormat("#.##");

    // Contains all of the rules for drawing

    Graphics2D graphSettings;

    // Homework use graphSettings.setStroke(new BasicStroke(5F));
    // To change the stroke dynamically with a component

    // Going to be used to monitor what shape to draw next

    int currentAction = 1;

    // Transparency of the shape

    float transparentVal = 1.0f;

    // Default stroke and fill colors

    Color strokeColor = Color.RED, fillColor = Color.WHITE;

    public static void main(String[] args) {
        new ERD_BUILDER_();
    }

    public ERD_BUILDER_() {
        // Define the defaults for the JFrame

        this.setSize(800, 600);
        this.setTitle("Java Paint");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setJMenuBar(menubar);

        JMenuBar menuBar = new JMenuBar();

        // Add the menubar to the frame
        setJMenuBar(menuBar);

        // Define and add two drop down menu to the menubar
        JMenu fileMenu = new JMenu("File");
        JMenu editMenu = new JMenu("Edit");
        JMenu dbMenu = new JMenu("Database");
        JMenu ToolsMenu = new JMenu("Tools");
        JMenu HelpMenu = new JMenu("Help");
        menuBar.add(fileMenu);
        menuBar.add(editMenu);
        menuBar.add(dbMenu);
        menuBar.add(ToolsMenu);
        menuBar.add(HelpMenu);
        // Create and add simple menu item to one of the drop down menu
        JMenuItem newAction = new JMenuItem("New Project");
        JMenuItem openAction = new JMenuItem("Open File");
        JMenuItem exitAction = new JMenuItem("Quit");
        JMenuItem cutAction = new JMenuItem("Cut");
        JMenuItem copyAction = new JMenuItem("Copy");
        JMenuItem pasteAction = new JMenuItem("Paste");
        JMenuItem UndoAction = new JMenuItem("Undo");
        JMenuItem RedoAction = new JMenuItem("Redo");
        JMenuItem clearAction = new JMenuItem("Clear");
        JMenuItem saveAction = new JMenuItem("Save");
        JMenuItem exportAction = new JMenuItem("Export");
        JMenuItem printAction = new JMenuItem("Print");
        JMenuItem ConvertAction = new JMenuItem("Convert To Tables");
        JMenuItem ColorAction = new JMenuItem("Color Picker");
        JMenuItem ZoomAction = new JMenuItem("Zoom");
        JMenuItem EntityAction = new JMenuItem("Entity & Attributes");
        JMenuItem RelationshipAction = new JMenuItem("Relationship Attributes");
        JMenuItem HelpAction = new JMenuItem("Help");
        JMenuItem AboutAction = new JMenuItem("About");

        fileMenu.add(newAction);
        fileMenu.addSeparator();
        fileMenu.add(openAction);
        fileMenu.addSeparator();
        fileMenu.add(saveAction);
        fileMenu.addSeparator();
        fileMenu.add(exportAction);
        fileMenu.addSeparator();
        fileMenu.add(printAction);
        fileMenu.addSeparator();
        fileMenu.add(exitAction);

        editMenu.add(UndoAction);
        editMenu.addSeparator();
        editMenu.add(RedoAction);
        editMenu.addSeparator();
        editMenu.add(cutAction);
        editMenu.addSeparator();
        editMenu.add(copyAction);
        editMenu.addSeparator();
        editMenu.add(pasteAction);
        editMenu.addSeparator();
        editMenu.add(clearAction);

        dbMenu.add(ConvertAction);

        ToolsMenu.add(ColorAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(ZoomAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(EntityAction);
        ToolsMenu.addSeparator();
        ToolsMenu.add(RelationshipAction);

        HelpMenu.add(HelpAction);
        HelpMenu.addSeparator();
        HelpMenu.add(AboutAction);

        newAction.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                new Lesson49_1().setVisible(true);
            }
        });

        JPanel buttonPanel = new JPanel();

        JPanel FieldPanel = new JPanel();

        // Swing box that will hold all the buttons

        Box theBox = Box.createVerticalBox();
        Box theBoxs = Box.createVerticalBox();

        // Make all the buttons in makeMeButtons by passing the
        // button icon.

        brushBut = makeMeButtons("./src/brush.png", 1);
        lineBut = makeMeButtons("./src/line.png", 2);
        ellipseBut = makeMeButtons("./src/ellipse.png", 3);
        rectBut = makeMeButtons("./src/rectangle.png", 4);

        // Make all the buttons in makeMeColorButton by passing the
        // button icon and true for stroke color or false for fill

        strokeBut = makeMeColorButton("./src/stroke.png", 5, true);
        fillBut = makeMeColorButton("./src/fill.png", 6, false);

        // Add the fields to the boxs


        JLabel Properties = new JLabel("Properties");

        theBoxs.add(Properties);


        theBox.add(brushBut);
        theBox.add(lineBut);
        theBox.add(ellipseBut);
        theBox.add(rectBut);
        theBox.add(strokeBut);
        theBox.add(fillBut);

        // Add the transparent label and slider

        transLabel = new JLabel("Transparent: 1");

        // Min value, Max value and starting value for slider

        transSlider = new JSlider(1, 99, 99);

        // Create an instance of ListenForEvents to handle events

        ListenForSlider lForSlider = new ListenForSlider();

        // Tell Java that you want to be alerted when an event
        // occurs on the slider

        transSlider.addChangeListener(lForSlider);

        //theBox.add(transLabel);
        //theBox.add(transSlider);

        buttonPanel.add(theBox);
        FieldPanel.add(theBoxs);

        this.add(buttonPanel, BorderLayout.WEST);
        this.add(FieldPanel, BorderLayout.EAST);
        buttonPanel.setPreferredSize(new Dimension(200,480));
        FieldPanel.setPreferredSize(new Dimension(200,480));
        // Make the drawing area take up the rest of the frame

        // this.add(new DrawingBoard(), BorderLayout.CENTER);
        final DrawingBoard drawPanel = new DrawingBoard();
        this.add(drawPanel, BorderLayout.CENTER);
        this.getContentPane().setBackground(Color.WHITE);

        exportAction.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                BufferedImage image = new BufferedImage(drawPanel.getWidth(),
                        drawPanel.getHeight(), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = image.createGraphics();
                drawPanel.paint(g);
                g.dispose();

                JFileChooser fileChooser = new JFileChooser();
                File theDirectory = new File("C:/Users/Wenda/Desktop");
                fileChooser.setCurrentDirectory(theDirectory);
                FileNameExtensionFilter pngFilter = new FileNameExtensionFilter(
                        "PNG file (*.png)", "png");
                fileChooser.addChoosableFileFilter(pngFilter);
                fileChooser.setFileFilter(pngFilter);

                int status = fileChooser.showSaveDialog(ERD_BUILDER_.this);

                if (status == JFileChooser.APPROVE_OPTION) {
                    try {
                        ImageIO.write(image, "png",
                                fileChooser.getSelectedFile());
                        JOptionPane.showMessageDialog(null, "Image saved to "
                                + fileChooser.getSelectedFile().getName());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

            }
        });

        // Show the frame

        this.setVisible(true);

    }

    // Spits out buttons based on the image supplied
    // actionNum represents each shape to be drawn

    public JButton makeMeButtons(String iconFile, final int actionNum) {
        JButton theBut = new JButton();
        Icon butIcon = new ImageIcon(iconFile);
        theBut.setIcon(butIcon);

        // Make the proper actionPerformed method execute when the
        // specific button is pressed

        theBut.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                currentAction = actionNum;

            }
        });

        return theBut;
    }

    // Spits out buttons based on the image supplied and
    // whether a stroke or fill is to be defined

    public JButton makeMeColorButton(String iconFile, final int actionNum,
            final boolean stroke) {
        JButton theBut = new JButton();
        Icon butIcon = new ImageIcon(iconFile);
        theBut.setIcon(butIcon);

        theBut.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if (stroke) {

                    // JColorChooser is a popup that lets you pick a color

                    strokeColor = JColorChooser.showDialog(null,
                            "Pick a Stroke", Color.BLACK);
                } else {
                    fillColor = JColorChooser.showDialog(null, "Pick a Fill",
                            Color.WHITE);
                }

            }
        });

        return theBut;
    }

    public class DrawingBoard extends JComponent {

        private static final long serialVersionUID = -4431176095451940075L;

        // ArrayLists that contain each shape drawn along with
        // that shapes stroke and fill
        ArrayList<Shape> shapes = new ArrayList<Shape>();
        ArrayList<Color> shapeFill = new ArrayList<Color>();
        ArrayList<Color> shapeStroke = new ArrayList<Color>();
        ArrayList<Float> transPercent = new ArrayList<Float>();

        Point drawStart, drawEnd;

        // Monitors events on the drawing area of the frame

        public DrawingBoard() {

            this.addMouseListener(new MouseAdapter() {

                public void mousePressed(MouseEvent e) {

                    if (currentAction != 1) {

                        // When the mouse is pressed get x & y position

                        drawStart = new Point(e.getX(), e.getY());
                        drawEnd = drawStart;
                        repaint();

                    }

                }

                public void mouseReleased(MouseEvent e) {

                    if (currentAction != 1) {

                        // Create a shape using the starting x & y
                        // and finishing x & y positions

                        Shape aShape = null;

                        if (currentAction == 2) {
                            aShape = drawLine(drawStart.x, drawStart.y,
                                    e.getX(), e.getY());
                        } else

                        if (currentAction == 3) {
                            aShape = drawEllipse(drawStart.x, drawStart.y,
                                    e.getX(), e.getY());
                        } else

                        if (currentAction == 4) {

                            // Create a new rectangle using x & y coordinates

                            aShape = drawRectangle(drawStart.x, drawStart.y,
                                    e.getX(), e.getY());
                        }

                        // Add shapes, fills and colors to there ArrayLists

                        shapes.add(aShape);
                        shapeFill.add(fillColor);
                        shapeStroke.add(strokeColor);

                        // Add transparency value to ArrayList

                        transPercent.add(transparentVal);

                        drawStart = null;
                        drawEnd = null;

                        // repaint the drawing area

                        repaint();

                    }

                }
            });

            this.addMouseMotionListener(new MouseMotionAdapter() {

                public void mouseDragged(MouseEvent e) {

                    // If this is a brush have shapes go on the screen quickly

                    if (currentAction == 1) {

                        int x = e.getX();
                        int y = e.getY();

                        Shape aShape = null;

                        // Make stroke and fill equal to eliminate the fact that
                        // this is an ellipse

                        strokeColor = fillColor;

                        aShape = drawBrush(x, y, 5, 5);

                        shapes.add(aShape);
                        shapeFill.add(fillColor);
                        shapeStroke.add(strokeColor);

                        // Add the transparency value

                        transPercent.add(transparentVal);
                    }

                    // Get the final x & y position after the mouse is dragged

                    drawEnd = new Point(e.getX(), e.getY());
                    repaint();
                }
            });
        }

        public void paint(Graphics g) {
            // Class used to define the shapes to be drawn

            graphSettings = (Graphics2D) g;

            // Antialiasing cleans up the jagged lines and defines rendering
            // rules

            graphSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            // Defines the line width of the stroke

            graphSettings.setStroke(new BasicStroke(4));

            // Iterators created to cycle through strokes and fills
            Iterator<Color> strokeCounter = shapeStroke.iterator();
            Iterator<Color> fillCounter = shapeFill.iterator();

            // Iterator for transparency

            Iterator<Float> transCounter = transPercent.iterator();

            for (Shape s : shapes) {

                // Sets the shapes transparency value

                graphSettings.setComposite(AlphaComposite.getInstance(
                        AlphaComposite.SRC_OVER, transCounter.next()));

                // Grabs the next stroke from the color arraylist
                graphSettings.setPaint(strokeCounter.next());

                graphSettings.draw(s);

                // Grabs the next fill from the color arraylist
                graphSettings.setPaint(fillCounter.next());

                graphSettings.fill(s);
            }

            // Guide shape used for drawing
            if (drawStart != null && drawEnd != null) {
                // Makes the guide shape transparent

                graphSettings.setComposite(AlphaComposite.getInstance(
                        AlphaComposite.SRC_OVER, 0.40f));

                // Make guide shape gray for professional look

                graphSettings.setPaint(Color.LIGHT_GRAY);

                Shape aShape = null;

                if (currentAction == 2) {
                    aShape = drawLine(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                } else

                if (currentAction == 3) {
                    aShape = drawEllipse(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                } else

                if (currentAction == 4) {

                    // Create a new rectangle using x & y coordinates

                    aShape = drawRectangle(drawStart.x, drawStart.y, drawEnd.x,
                            drawEnd.y);
                }

                graphSettings.draw(aShape);
            }
        }

        private Rectangle2D.Float drawRectangle(int x1, int y1, int x2, int y2) {
            // Get the top left hand corner for the shape
            // Math.min returns the points closest to 0

            int x = Math.min(x1, x2);
            int y = Math.min(y1, y2);

            // Gets the difference between the coordinates and

            int width = Math.abs(x1 - x2);
            int height = Math.abs(y1 - y2);

            return new Rectangle2D.Float(x, y, width, height);
        }

        // The other shapes will work similarly
        // More on this in the next tutorial

        private Ellipse2D.Float drawEllipse(int x1, int y1, int x2, int y2) {
            int x = Math.min(x1, x2);
            int y = Math.min(y1, y2);
            int width = Math.abs(x1 - x2);
            int height = Math.abs(y1 - y2);

            return new Ellipse2D.Float(x, y, width, height);
        }

        private Line2D.Float drawLine(int x1, int y1, int x2, int y2) {

            return new Line2D.Float(x1, y1, x2, y2);
        }

        private Ellipse2D.Float drawBrush(int x1, int y1, int brushStrokeWidth,
                int brushStrokeHeight) {

            return new Ellipse2D.Float(x1, y1, brushStrokeWidth,
                    brushStrokeHeight);

        }

    }

    // Implements ActionListener so it can react to events on components

    private class ListenForSlider implements ChangeListener {

        // Called when the spinner is changed

        public void stateChanged(ChangeEvent e) {

            // Check if the source of the event was the button

            if (e.getSource() == transSlider) {

                // Change the value for the label next to the spinner
                // Use decimal format to make sure only 2 decimals are ever
                // displayed

                transLabel.setText("Transparent: "
                        + dec.format(transSlider.getValue() * .01));

                // Set the value for transparency for every shape drawn after

                transparentVal = (float) (transSlider.getValue() * .01);

            }

        }

    }
}

1 个答案:

答案 0 :(得分:0)

您目前有3个课程,Lesson49_1,.DrawingBoard和ListenForSlider。

DrawingBoard是一个视图类,而ListenForSlider是一个控制器类。

Lesson49_1课程做的事太多了。每个类应该是模型,视图或控制器类。这就是使用MVC模式的原因。它允许您一次专注于GUI的一小部分。

在DrawingBoard中,您有4个与绘图有关的ArrayLists。我不理解这4个ArrayLists之间的关系,但这里是一个使用4个ArrayLists内容的示例模型类。

package com.ggl.fse;

import java.awt.Color;
import java.awt.Shape;

public class ShapeModel {

    private float transPercent;

    private Color fillColor;
    private Color strokeColor;

    private Shape shape;

    public ShapeModel(Shape shape, Color fillColor, Color strokeColor,
            float transPercent) {
        this.shape = shape;
        this.fillColor = fillColor;
        this.strokeColor = strokeColor;
        this.transPercent = transPercent;
    }

    public float getTransPercent() {
        return transPercent;
    }

    public Color getFillColor() {
        return fillColor;
    }

    public Color getStrokeColor() {
        return strokeColor;
    }

    public Shape getShape() {
        return shape;
    }

}

使用此类,您可以拥有一个List&lt; ShapeModel&gt;。

为了移动ShapeModel,您必须存储形状原点的X和Y.通过更改X和Y,可以更改形状的位置。

我无法再解释,因为我不了解您的所有绘图代码。