2015-05-23 17 views
0

我已閱讀,當JPanel對象(或延伸JPanel一個類的任何實例)是JFrame的一部分,每個所述JVM認爲,JFrame需要被刷新時,JPanel實例的paintComponent()方法被調用。當單個JFrame中有多個JPanel對象時,repaint()如何工作?

但是當我有兩個這樣的對象,即兩個不同的類的實例會發生什麼?運行我在最後提供的代碼,我發現在調用最小化時調用了兩個paintComponent()方法,或者按colourButton

但是,這是而不是的情況下,當我按labelButton。它只調用MyDrawPanel paintComponent()。爲什麼會這樣?

預先感謝您!

class GUI { 

    JFrame frame; 
    JLabel label; 

    void go() { 
     JButton labelButton = new JButton("Click me to change that (<-) text"); 
     labelButton.addActionListener(new LabelListener()); 
     JButton colourButton = new JButton("Click me to change the colour"); 
     colourButton.addActionListener(new ColourListener()); 

     label = new JLabel("Don't change me!"); 

     frame = new JFrame(); 
     frame.setSize(600, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 

     MyDrawPanel Q = new MyDrawPanel(); 
     DrawPanel P = new DrawPanel(); 

     frame.getContentPane().add(BorderLayout.CENTER, Q); 
     frame.getContentPane().add(BorderLayout.EAST, labelButton); 
     frame.getContentPane().add(BorderLayout.WEST, label); 
     frame.getContentPane().add(BorderLayout.SOUTH, colourButton); 
     frame.getContentPane().add(BorderLayout.NORTH, P); 

    } 

    class LabelListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent event){ 
      label.setText("You've changed me!"); 
     } 
    } 

    class ColourListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent event){ 
      MyDrawPanel.red = (int) (Math.random() * 255); 
      MyDrawPanel.green = (int) (Math.random() * 255); 
      MyDrawPanel.blue = (int) (Math.random() * 255); 
      frame.repaint(); 
     } 
    } 
} 

class MyDrawPanel extends JPanel { 

    static int red = (int) (Math.random() * 255); 
    static int green = (int) (Math.random() * 255); 
    static int blue = (int) (Math.random() * 255); 

    @Override 
    public void paintComponent(Graphics g){ 
     Color randomColour = new Color(red, green, blue); 

     g.setColor(randomColour); 

     g.fillOval(70, 70, 75, 75); 

     System.out.println("Q"); 
    } 
} 

class DrawPanel extends JPanel { 

    @Override 
    public void paintComponent(Graphics g){ 

     System.out.println("P"); 

    } 
} 
+0

它調用你的'paintComponent' – Zizouz212

回答

1
frame.repaint(); 

這告訴幀重繪自己和所有的孩子。所以框架上的所有組件都會重新繪製。

label.setText("You've changed me!"); 

setText()的方法將調用標籤上revalidate()repaint()repaint()告訴標籤重新繪製自己和所有的孩子。

如果任何組件的大小發生變化,revalidate()將調用佈局管理器。在這種情況下,它看起來像標籤會變大。這意味着添加到中心的面板(您的DrawPanel)會變得更小,因此它也需要重新繪製。

NORTH/SOUTH中的組件不受標籤大小更改的影響,因此不會重新繪製。

所以Swing只會重畫任何必要的東西來最小化繪畫。

+0

所以setText(「」)檢查佈局的哪些部分需要重新繪製,以便它不會做任何不必要的工作,因此只打印「Q」,這意味着中心部分它的尺寸有變化嗎?至於frame.repaint()它重繪整個框架,以及它的孩子,在我們的情況P和Q? –