【问题标题】:Clicking on a JPanel to draw shapes单击 JPanel 以绘制形状
【发布时间】:2012-10-18 12:22:23
【问题描述】:

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

这是我的一些代码 sn-ps,这可能是一个小错误,但我似乎无法找到它。

形状:

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);
        }

【问题讨论】:

  • 你能发布 Shape 类吗?至少是处理形状位置的部分?另外,DrawingCanvas.repaint() 是否在某处被覆盖?
  • 已发布。不,没有任何 DrawingCanvas 绘制方法被覆盖
  • 你必须从Rectangle类中调用super.paint。更好的是,覆盖paintComponent,但请确保调用super.paintComponent。绘制方法做了很多后台工作,你不能简单地忽略它。

标签: java swing graphics drawing jpanel


【解决方案1】:

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

【讨论】:

    【解决方案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 添加到未添加到画布的新创建的形状中,我想您还想要其他东西做...

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多