2014-09-24 119 views
1

我想使用JPanel繪製一個矩形。問題是,當我點擊一個菜單項時,它應該繪製一個新的矩形。但是,當我這樣做時,只有一部分被繪製。這裏是我的意思是:使用JPanel在按鈕上點擊一個矩形使用JPanel

rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      squares.addSquare(10, 10, 100, 100); 
     } 
    }); 

做到這一點:

not

,但是當我把squares.addSquare(...) OUTSIDE中的ActionListener的,它提供了正確的形狀(只是沒有當我想它)

squares.addSquare(10, 10, 100, 100); 
    rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      //nothing on click... 
     } 
    }); 

,這裏是正確的矩形:

enter image description here

任何想法爲什麼它不能正確繪製時,我把它放在ActionListener?謝謝。

全碼

class UMLWindow extends JFrame { 
Squares squares = new Squares(); 

private static final long serialVersionUID = 1L; 

public UMLWindow() { 
    addMenus(); 
} 

public void addMenus() { 

    getContentPane().add(squares); 
    //squares.addSquare(10, 10, 100, 100); 

    JMenuBar menubar = new JMenuBar(); 

    JMenu file = new JMenu("File"); 
    file.setMnemonic(KeyEvent.VK_F); 

    JMenu shapes = new JMenu("Shapes"); 
    file.setMnemonic(KeyEvent.VK_F); 

    JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle"); 
    rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      squares.addSquare(10, 10, 100, 100); 
     } 
    }); 

    shapes.add(rectangleMenuItem); 

    menubar.add(shapes); 

    setJMenuBar(menubar); 

    setTitle("UML Editior"); 
    setSize(300, 200); 
    setLocationRelativeTo(null); 
} 


} 

class Squares extends JPanel { 
private static final long serialVersionUID = 1L; 

private List<Rectangle> squares = new ArrayList<Rectangle>(); 

public void addSquare(int x, int y, int width, int height) { 
    Rectangle rect = new Rectangle(x, y, width, height); 
    squares.add(rect); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    this.setOpaque(true); 
    this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    for (Rectangle rect : squares) { 
     g2.draw(rect); 
    } 
} 

} 
+0

@Bene:請做出答案。好處?你去哪兒了? – 2014-09-24 20:42:25

+0

是的,這工作。如果它成爲答案,我會接受 – Harry 2014-09-24 20:45:47

+0

@Harry如果Bene不回來,請隨時自己回答 – 2014-09-24 20:53:06

回答

3

搖擺採用被動的渲染引擎,所以它不知道什麼時候應該更新/除非你告訴它重繪的組件。

開始你addSquare方法中調用從repaint ...

public void addSquare(int x, int y, int width, int height) { 
    Rectangle rect = new Rectangle(x, y, width, height); 
    squares.add(rect); 
    repaint(); 
} 

這將使到重繪管理器的請求,通知它當前組件需要重新繪製。

您還應該爲您的組件提供尺寸提示,以便佈局經理將其尺寸設置爲0x0

考慮重寫Squares類的getPreferredSize方法並返回適當的默認大小...

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(300, 200); 
} 

這也意味着,你可以在主窗口中調用pack,它會「包裝」自己的周圍內容非常整齊。

此外,不要調用方法,這將改變組件或其他組件的狀態或安排額外的repaint請求,因爲這可能會設置一個無限循環的重繪,這將耗盡您的PC資源....

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    // This is bad... 
    //this.setOpaque(true); 
    // This is bad... 
    //this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    for (Rectangle rect : squares) { 
     g2.draw(rect); 
    } 
} 

不透明度和顏色的東西應該定義在塗料週期之外。此外,從JPanel延伸的組件默認是不透明的;)

+0

感謝您的幫助: ) – Harry 2014-09-25 00:49:18

+0

@Harry不用擔心,很高興它是有用的 – MadProgrammer 2014-09-25 00:49:50