ListerCi
2016-11-21 13:16
采纳率: 60%
浏览 1.5k
已采纳

Java制作画图程序的GUI问题

做了一个基于工厂模式的画图程序,有一些bug,画图会出现一些乱七八糟的情况。。。百思不得其解,来求助各位。。。
父类Shape:

 import java.awt.Graphics;

public abstract class Shape {

    abstract void draw(Graphics g);

}

Line类:

 import java.awt.Graphics;
import java.awt.Point;

public class Line extends Shape {

    private Point start;
    private Point end;

    Line(Point start, Point end) {
        this.start = start;
        this.end = end;
    }

    @Override
    void draw(Graphics g) {
        g.drawLine(start.x, start.y, end.x, end.y);
    }

}

Circle类:

import java.awt.Graphics;
import java.awt.Point;

public class Circle extends Shape {

    private Point start;
    private Point end;

    public Circle(Point start, Point end) {
        this.start = start;
        this.end = end;
    }

    @Override
    void draw(Graphics g) {
        g.drawOval(Math.min(start.x, end.x), Math.min(start.y, end.y),
                Math.max(Math.abs(start.x), Math.abs(start.y - end.y)),
                Math.max(Math.abs(start.x - end.x), Math.abs(start.y - end.y)));
    }

}

Rect类:

 import java.awt.Graphics;
import java.awt.Point;

public class Rect extends Shape {

    private Point start;
    private Point end;

    public Rect(Point start, Point end) {
        this.start = start;
        this.end = end;
    }

    @Override
    void draw(Graphics g) {
        g.drawRect(Math.min(start.x, end.x), Math.min(start.y, end.y),
                Math.abs(start.x - end.x), Math.abs(start.y - end.y));
    }

}

工厂类:

 import java.awt.Point;

public class ShapeFactory {

    public static Shape creator(int choices, Point start, Point end) {

        if (choices == 1)
            return new Line(start, end);
        else if (choices == 2)
            return new Circle(start, end);
        else if (choices == 3)
            return new Rect(start, end);

        else return null;
    }

}

主类,这边把代码全贴上来,想运行的朋友可以运行一下:
有些功能还没写完整,比如保存之类。
目前思路是这样:在菜单上选择要画的图形,这时会给choices赋一个值,代表要画的图形。
在鼠标点下的时候记录初始坐标。
鼠标抬起时记录终止坐标,并添加一个图形对象到保存的Vector中,再进行重绘。

 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.UIManager;

/**
 * @description 画图程序(以松耦合为目的,以工厂模式为实现方法)
 * @date 2016-11-19
 */


/**
 * @description 窗口类,定义大小以及窗口形态
 */
public class MyPaint extends JFrame {

    private static final long serialVersionUID = 1L;
    private DrawPanel drawingArea;
    private int width = 800, height = 600;
    public static int choices = 1;

    // Constructor
    public MyPaint() {

        super("Drawing Program");

        /**
         * 定义菜单条的文件选项,设置四个选项分别为:
         * 新建、打开、保存以及退出
         */
        JToolBar buttonPanel; //按钮面板
        JButton line, circle, rect;
        JMenuBar bar = new JMenuBar(); //菜单条
        JMenu fileMenu = new JMenu("File");

        // 新建
        JMenuItem newItem = new JMenuItem("New");
        newItem.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        //如果被触发,则调用新建文件函数段
                    }});
        fileMenu.add(newItem);

        // 保存
        JMenuItem saveItem = new JMenuItem("Save");
        saveItem.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        //如果被触发,则调用保存文件函数段
                    }});
        fileMenu.add(saveItem);

        // 打开
        JMenuItem loadItem = new JMenuItem("Load");
        loadItem.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        //如果被触发,则调用打开文件函数段
                    }});
        fileMenu.add(loadItem);

        // 设置分割线 & 退出
        fileMenu.addSeparator();
        JMenuItem exitItem = new JMenuItem("Exit");
        exitItem.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        System.exit(0); //如果被触发,则退出画图板程序
                    }});
        fileMenu.add(exitItem);
        bar.add(fileMenu);

        /**
         * 定义菜单栏的帮助选项,对软件进行解释
         */
        JMenu helpMenu = new JMenu("Help");
        JMenuItem aboutItem = new JMenuItem("About");
        aboutItem.setMnemonic('A');
        aboutItem.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null,
                                "This is a mini drawing program",
                                " 画图板程序说明 ",
                                JOptionPane.INFORMATION_MESSAGE);
                    }});
        helpMenu.add(aboutItem);
        bar.add(helpMenu);

        /**
         * 按钮面板
         */
        buttonPanel = new JToolBar(JToolBar.HORIZONTAL);
        // 添加直线按钮以及点击事件
        line = new JButton("Line");
        line.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
                choices = 1;
            }});

        // 添加圆按钮以及点击事件
        circle = new JButton("Circle");
        circle.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
                choices = 2;
            }});

        // 添加矩形按钮以及点击事件
        rect = new JButton("Rect");
        rect.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
                choices = 3;
            }});
        buttonPanel.add(line);
        buttonPanel.add(circle);
        buttonPanel.add(rect);

        setJMenuBar(bar);

        // 定义画图区域
        drawingArea = new DrawPanel();
        Container c = getContentPane();

        // 添加控件
        c.add(drawingArea, BorderLayout.CENTER);
        c.add(buttonPanel, BorderLayout.NORTH);

        // 设置窗口
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(width, height);
        setVisible(true);
    }

    /**
     * Main
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        new MyPaint();

    }
}

/**
 * @description 画图面板类,提供鼠标监听器
 *
 */
class DrawPanel extends JPanel implements MouseListener {

    private static final long serialVersionUID = 1L;

    // 用于保存图形
    private Vector<Shape> shapes;

    // 用于记录鼠标画图时留下的两个点的坐标
    private Point start = new Point();
    private Point end = new Point();

    // Constructor
    public DrawPanel() {
        shapes = new Vector<>();
        setBackground(Color.white);
        this.addMouseListener(this);
    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < shapes.size(); i++) {
            draw(g, shapes.elementAt(i));
        }
    }
    void draw(Graphics g, Shape shape) {
        shape.draw(g);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // do nothing here
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // do nothing here
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // do nothing here
    }

    //按下鼠标时记录坐标点
    @Override
    public void mousePressed(MouseEvent e) {
        start.x = e.getX();
        start.y = e.getY();
    }

    // 松开鼠标时记录坐标点并将图形画出来
    @Override
    public void mouseReleased(MouseEvent e) {
        end.x = e.getX();
        end.y = e.getY();
        shapes.add(ShapeFactory.creator(MyPaint.choices, start, end));

        repaint();
    }

}
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • _1_1_7_ 2016-11-21 14:11
    已采纳

    问题出在:

         private Point start = new Point();
        private Point end = new Point();
    

    不能用,应该:
    int x;
    int y;

         public void mousePressed(MouseEvent e) {
           x = e.getX();
           y = e.getY();
        }
    
         public void mouseReleased(MouseEvent e) {
            int x1 = e.getX();
           int y1 = e.getY();
            shapes.add(ShapeFactory.creator(MyPaint.choices, new Point(x,y), new Point(x1,y1)));
    
            repaint();
        }
    
    打赏 评论

相关推荐 更多相似问题