简体   繁体   English

当我在一个JFrame中有多个JPanel对象时,repaint()如何工作?

[英]How does repaint() work when I have multiple JPanel objects in a single JFrame?

I have read that when a JPanel object (or any instance of a class that extends JPanel ) is part of a JFrame , each time the JVM thinks that the JFrame needs to be refreshed, the JPanel instance's paintComponent() method is called. 我已经读到,当JPanel对象(或扩展JPanel的类的任何实例)是JFrame一部分时,每次JVM认为需要刷新JFrame ,都会调用JPanel实例的paintComponent()方法。

But what happens when I have two such objects, that are instances of two different classes? 但是,当我有两个这样的对象(即两个不同类的实例)时会发生什么? Running the code I've provided at the end, I found out that both paintComponent() methods are called, when I minimize, change the size or press the colourButton . 运行我最后提供的代码,我发现当我最小化,更改大小或按colourButton时,都调用了两个paintComponent()方法。

However, this is not the case when I press labelButton . 但是,当我按下labelButton时,情况并非如此。 It only invokes the MyDrawPanel paintComponent() . 它仅调用MyDrawPanel paintComponent() Why is that the case? 为什么会这样?

Thank you in advance! 先感谢您!

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

This tells the frame to repaint itself and all its children. 这告诉框架重新粉刷自身及其所有子代。 So all the components on the frame are repainted. 因此,框架上的所有组件均已重新粉刷。

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

The setText() method will invoke revalidate() and repaint() on the label. setText()方法将在标签上调用revalidate()repaint() The repaint() tells the label to repaint itself and all of its children. repaint()告诉标签重新绘制自身及其所有子级。

The revalidate() will invoke the layout manager in case the size of any components have changed. 如果任何组件的大小已更改,则revalidate()将调用布局管理器。 In this case it looks like the label will get larger. 在这种情况下,标签看起来会变大。 This means the panel added to the center (your DrawPanel) will get smaller, so it also needs to be repainted. 这意味着添加到中心(您的DrawPanel)的面板将变小,因此也需要重新粉刷。

The components in the NORTH/SOUTH are not affected by the change in the labels size so they are not repainted. NORTH / SOUTH中的组件不受标签大小更改的影响,因此不会重新粉刷。

So Swing will only repaint whatever is necessary to minimize the painting. 因此,Swing只会重新绘画以最小化绘画所需的一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM