程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> gui-Java制作畫圖程序的GUI問題

gui-Java制作畫圖程序的GUI問題

編輯:編程解疑
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();
    }

}

最佳回答:


問題出在:

     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();
    }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved