簡體   English   中英

在調整Jframe大小之前,JPanel不會更新

[英]JPanel doesn't update until resize Jframe

我子類化JPanel以覆蓋paintComponent(Graphics),我想在jframe中將圖像繪制到jpanel上。

但是直到我更改了jframe的大小,我的圖像才出現。 這是我的代碼:

public class ImagePanel extends JPanel{

    public void setImage(BufferedImage bi)
    {
        image = bi;
        revalidate();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if(image != null)
        {
            g.drawImage(image, 0, 0, this);
        }
    }
}

驗證是否添加組件並調用pack() setVisible() 之后調用setVisible() ,如本示例中所述 您可能還需要采用適當的布局 調用repaint()如建議在這里 ,可以解決症狀,但不是根本原因。

如果要“刷新” JPanel,則應調用repaint(),后者將調用paintComponent()。 這應該可以解決您的問題:

public void setImage(BufferedImage bi)
{
    image = bi;
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            repaint();
        }
    });
}

使用EDT更新和更改GUI的良好做法。 如果您有興趣,這里是EDT的更多信息:

事件分派線程如何工作?

不需要從EDT調用repaint 如果要更改GUI,例如將文本設置為JLabel,則它應位於EDT內。 以下是有關在EDT之外可以調用的內容的更多信息(由nIcE cOw提供):

在EDT之外可以安全地使用Component.repaint()嗎?

看一下JPanel.add() 的文檔 ,它是從java.awt.Container繼承的:

將指定的組件追加到此容器的末尾。 這是addImpl(java.awt.Component,java.lang.Object,int)的便捷方法。 此方法更改與布局有關的信息,因此使組件層次結構無效。 如果已經顯示了容器,則此后必須驗證層次結構才能顯示添加的組件。

重點已添加。

因此,如果在顯示容器對其進行修改,則必須調用validate()使其顯示。 僅調用repaint()是不夠的。 您可能已經注意到,調用setVisible(true)也可以; 這是因為它在內部調用validate()

我有同樣的問題,可以通過調用setVisible(true)來解決。 我正在使用的JFrame。

示例:如果您的JFrame在使用后沒有更新:

jframe.setContentPane(new MyContentPane());

修復:

jframe.setContentPane(new MyContentPane());
jframe.setVisible(true);

我知道即使您的JFrame已經可見,執行此操作聽起來也很愚蠢,但這是我到目前為止找到的解決此問題的唯一方法(上面提出的解決方案對我不起作用)。

這是一個完整的例子。 運行它,然后取消注釋“ f.setVisible(true);” 類Panel1和Panel2中的說明,您將看到區別。 不要忘記導入(對於自動導入,請按Ctrl + Shift + O)。

主類:

public class Main {
    private static JFrame f;
    public static void main(String[] args) {
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new Panel1(f));
        f.pack();    
        f.setVisible(true);
    }
}

Panel1類:

public class Panel1 extends JPanel{
    private JFrame f;
    public Panel1(JFrame frame) {
        f = frame;
        this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        JButton b = new JButton("Panel 1");
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                f.setContentPane(new Panel2(f));
                // Uncomment the instruction below to fix GUI "update-on-resize-only" problem
                //f.setVisible(true);
            }
        });
        add(b);
    }
}

Panel2類:

public class Panel2 extends JPanel{
    private JFrame f;
    public Panel2(JFrame frame) {
        f = frame;
        this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        JButton b = new JButton("Panel 2");
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                f.setContentPane(new Panel1(f));
                // Uncomment the instruction below to fix GUI "update-on-resize-only" problem
                //f.setVisible(true);
            }
        });
        add(b);
    }
}

希望能有所幫助。

問候。

我也有同樣的問題,但我找到了解決方案。 只需在頂部創建一個jframe對象,然后在底部調用jframe方法,例如jf.pack()jf.setVisible()jf.setSize()jf.setDefaultCloseOpetion()應該位於添加的所有UI的底部框架,您會發現它很棒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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