[英]How do I create a Mock of a JFrame/JPanel that supports repaint functionality
[英]How does repaint() work when I have multiple JPanel objects in a single JFrame?
我已經讀到,當JPanel
對象(或擴展JPanel
的類的任何實例)是JFrame
一部分時,每次JVM認為需要刷新JFrame
,都會調用JPanel
實例的paintComponent()
方法。
但是,當我有兩個這樣的對象(即兩個不同類的實例)時會發生什么? 運行我最后提供的代碼,我發現當我最小化,更改大小或按colourButton
時,都調用了兩個paintComponent()
方法。
但是,當我按下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");
}
}
frame.repaint();
這告訴框架重新粉刷自身及其所有子代。 因此,框架上的所有組件均已重新粉刷。
label.setText("You've changed me!");
setText()
方法將在標簽上調用revalidate()
和repaint()
。 repaint()
告訴標簽重新繪制自身及其所有子級。
如果任何組件的大小已更改,則revalidate()
將調用布局管理器。 在這種情況下,標簽看起來會變大。 這意味着添加到中心(您的DrawPanel)的面板將變小,因此也需要重新粉刷。
NORTH / SOUTH中的組件不受標簽大小更改的影響,因此不會重新粉刷。
因此,Swing只會重新繪畫以最小化繪畫所需的一切。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.