单击JPanel以绘制形状

时间:2012-10-18 12:22:24

标签: java swing graphics drawing jpanel

我有一个包含3个JPanel的JFrame;选项,菜单,画布。在选项中有许多代表形状的JButton。目的是点击形状的JButton,例如矩形,然后单击画布上的任意位置,将在那里绘制形状。 出于某种原因,形状并不总是被绘制,只有在我单击画布左上角区域的某个位置时才会绘制它。此外,根据我点击的位置,形状似乎随机改变大小。

以下是我的一些代码片段,它可能是一个小错误,但我似乎无法找到它。

形状:

public class Shape extends JPanel {

    protected int xLocation;
    protected int yLocation;
    protected int numberOfSides; 
    protected String areaInfo; 
    protected String perimeterInfo; 

    public int getXLocation() {
        return xLocation;
    }

    public void setXLocation(int xLocation) {
        this.xLocation = xLocation;
    }

    public int getYLocation() {
        return yLocation;
    }

    public void setYLocation(int yLocation) {
        this.yLocation = yLocation;
    }

    public int getNumberOfSides() {
        return numberOfSides;
    }

    public Shape(int xLocation, int yLocation, int numberOfSides) {
        this.xLocation = xLocation;
        this.yLocation = yLocation;
        this.numberOfSides = numberOfSides;
    }
}

矩形:

import java.awt.Color;
import java.awt.Graphics;


public class Rectangle extends Shape {

    private int width;
    private int height;

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public Rectangle(int xLocation, int yLocation, int width, int height ) {
        super(xLocation, yLocation, 4);
        this.width = width;
        this.height = height;
        this.areaInfo = "Multiply width * height";
        this.perimeterInfo = "Add the lengths of each side";
    }

    public void paint(Graphics g){
        g.setColor(Color.BLACK);        
        g.fillRect(xLocation, yLocation, width, height);
    }
}

画布:

public class DrawingCanvas extends JPanel implements Serializable{

    private ArrayList<Shape> shapeList;
    OptionsPanel options;

    public void addShape(Shape shape){
        shapeList.add(shape);
        this.add(shape);
        this.repaint();
    }

    public DrawingCanvas(){
        shapeList = new ArrayList<Shape>();
    }

}

框:

public class DrawingFrame extends JFrame implements MouseListener, MouseMotionListener {

    private OptionsPanel options;
    private DrawingCanvas canvas;
    private MenuBar menu;
    Shape s; //shape to be manipulated

    public DrawingFrame(){
        options = new OptionsPanel();
        canvas = new DrawingCanvas();
        menu = new MenuBar();

        //options.setBounds(0, 0, 100, 500);
        options.setBackground(Color.GREEN);
        canvas.setBackground(Color.yellow);
        menu.setSize(1000,200);
        menu.setBackground(Color.magenta);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(1000,500);
        this.setTitle("Drawing Application");

        this.setLayout(new BorderLayout());
        this.getContentPane().add(options, BorderLayout.WEST);
        this.getContentPane().add(canvas, BorderLayout.CENTER);
        this.getContentPane().add(menu, BorderLayout.PAGE_START);
        this.setVisible(true);

        options.createRectangleButton.addMouseListener(this);
        options.createSquareButton.addMouseListener(this);
        options.createCircleButton.addMouseListener(this);
        options.createTriangleButton.addMouseListener(this);
        options.clearButton.addMouseListener(this);
        canvas.addMouseListener(this);
        canvas.addMouseMotionListener(this);

    }




    @Override
    public void mouseClicked(MouseEvent e) {
        boolean createShape = true;

        if(e.getSource().equals(options.createRectangleButton)){
            createShape = true;
            s = new Rectangle(50,50,400,200);
            s.addMouseListener(this);
            s.addMouseMotionListener(this); 
        }

        if (e.getSource().equals(canvas) && createShape == true){
            s.setXLocation(e.getX());
            s.setYLocation(e.getY());
            createShape = false;
            canvas.addShape(s);
        }

3 个答案:

答案 0 :(得分:2)

缺少complete example,很难说。我希望您的DrawingCanvas覆盖paintComponent(),以便在Shape中呈现累积的shapeList个实例。您可以将您的方法与GaphPanel中显示的方法进行比较,引用here

image

答案 1 :(得分:2)

您提供的代码不完整,但无论如何问题出在mouseClicked方法中,如果您将第二个if更改为以下内容,例如:

    if (e.getSource().equals(canvas) && createShape == true){
        int x = e.getX();
        int y = e.getY();
        s = new Rectangle(x,y,x+50,y+50);
        canvas.addShape(s);
    }

然后是宽度和宽度的矩形每当您单击画布时,高度50将被绘制,具体取决于您的x,y位置(您可以通过使用基于用户输入的变量来更改固定的宽度/高度)。另外,我不确定你在第一个if部分尝试做什么,你将MouseListener添加到未添加到画布的新创建的形状中,我想这里有你想做的其他事情......

答案 2 :(得分:0)

我不得不覆盖canvas类的paint方法;在canvas类中调用super.paint并单独重绘每个形状

public void paint(Graphics g){
            super.paint(g);
            for(int i=0;i<shapeList.size();i++){
                ((Shape)shapeList.get(i)).paint(g);
            }
        }