簡體   English   中英

當我修改JPanel使其可見后,paintComponent在componentResize之前被調用

[英]When I modify a JPanel after it becomes visible, paintComponent gets called before componentResized

我有一個帶有顏色條的數據圖,該顏色條是一個JPanel ,其布局中包含兩個JPanel 一個JPanel是數據圖本身,另一個是顏色欄。 我想添加功能,以便可以打開和關閉顏色欄,而我通過簡單地刪除包含顏色欄的JPanel來解決此問題。 像這樣:

public class Data2DPlotWithColorBar extends JPanel {
    public Data2DPlotWithColorBar() { 
        this.data2DPlot = new Data2DPlot();
        this.colorBar  = new VerticalColorBar();
        this.setPlot();
    }

    public final void toggleColorBar() {
        enableColorBar = !enableColorBar;
        setPlot();
    }

    private void setPlot() {                
        this.removeAll();
        this.setLayout(new BorderLayout());
        if (enableColorBar) {
            this.add(colorBar, BorderLayout.EAST);
        }
        this.add(this.data2DPlot, BorderLayout.CENTER);
        this.revalidate();
        this.repaint();
    }

    private final Data2DPlot data2DPlot;    
    private final VerticalColorBar colorBar;
    private boolean enableColorBar;
}

問題是,當刪除顏色欄時,數據圖具有一個組件偵聽器,該組件偵聽器已覆蓋componentResized方法,該方法可以正確調整數據大小(保持固定的寬高比)以適合JPanel的大小。 像這樣:

public class Data2DPlot extends JPanel { 

    ...

    @Override
    public final void componentResized(ComponentEvent e) {
        double scaleFactorBuf = Math.min((double)getPixelMaxViewWidth()/getNativeWidth(), 
                                         (double)getPixelMaxViewHeight()/getNativeHeight());    
        // Make sure scaleFactorBuf isn't close to zero
        if (Math.abs(scaleFactorBuf) > MathUtilities.LAMBDA) {
            scaleFactor = scaleFactorBuf;
        }
    }


    ...   


    @Override
    protected final void paintComponent(Graphics g) {
        super.paintComponent(g);  
        ....
    }  

}

事實證明,數據圖未正確調整大小。 我進行了一些調試,發現當我打開和關閉顏色條時, componentResizedpaintComponent方法之后被調用。 這意味着先繪制圖像,然后再scaleFactor ,這是不正確的。 到目前為止,我能夠解決的唯一方法是在componentResized方法的最后調用repaint() 但是,調整組件大小時已經調用了repaint() ,所以我覺得這是不正確的方法。 一些谷歌搜索使我找到了在按需修改JPanel之后涉及使用revalidaterepaint解決方案。 但是,這樣做的任何組合仍然導致在repaint之后調用componentResized 有標准的解決方案嗎?

此主題中提出的答案提供了一個簡單的解決方案。 而不是重寫componentResized方法,而是執行setBounds(int,int,int,int)一個。

componentResized,setBounds和repaint的調用順序很奇怪。 在程序啟動時就是這樣;

  • 的setBounds
  • 的componentResized
  • 重繪

而如果您稍后手動調整大小(我沒有按代碼中的調整大小順序進行測試),

  • 的setBounds
  • 重繪
  • 的componentResized

通過在setBounds中設置標志,而不是在componentResized中設置標志,您可以知道重新調整面板大小時重新繪制尺寸敏感的變量,立即生效。

暫無
暫無

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

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