2012-10-18 243 views
2

我有一個包含3個JPanel的JFrame;選項,菜單,畫布。在選項中有一些代表形狀的JButton。目的是點擊一個形狀的JButton,例如矩形,然後單擊畫布上的任意位置,並在那裏繪製形狀。 出於某種原因,形狀並不總是繪製出來的,只是當我點擊畫布左上角區域時才繪製。此外,形狀似乎隨機更改大小取決於我點擊的位置。點擊JPanel繪製形狀

以下是我的一些代碼片段,它可能是一個小錯誤,但我似乎無法找到它。

形狀:

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

請問您可以發佈Shape類嗎?至少處理Shape的位置的部分?另外,'DrawingCanvas.repaint()'覆蓋了什麼地方? – Zistack

+0

已發佈。不,沒有任何DrawingCanvas繪畫方法被覆蓋 – Matt

+0

您必須從'Rectangle'類中調用'super.paint'。更好的是,重寫'paintComponent',而確保你調用'super.paintComponent'。繪畫方法做了很多後臺工作,你不能簡單地忽略它。 – MadProgrammer

回答

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

缺席complete example,這很難說。我期望您的DrawingCanvas覆蓋paintComponent()以便呈現shapeList中累計的Shape實例。您可以將您的方法與GaphPanel中所示的方法進行比較,引用here

image

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

然後矩形的寬度爲&根據您的x,y位置(您可以通過使用基於用戶輸入的變量來更改固定的寬度/高度),每當您單擊畫布時將繪製高度50。另外,我不確定你要在第一個if部分中嘗試做什麼,在此部分中,您將MouseListener添加到未添加到畫布上的新創建的形狀,我猜還有其他的事情要做。