繁体   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