簡體   English   中英

當我在一個JFrame中有多個JPanel對象時,repaint()如何工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM