我有一个颜色栏的JPanel
数据情节与其中有两个JPanel
s的布局。其中一个JPanel
是数据图本身,另一个是彩条。我想添加功能,以便可以打开和关闭颜色条,并且通过简单地删除包含颜色条的JPanel
来解决这个问题。是这样的:当我修改一个JPanel后,它变得可见,paintComponent被调用之前componentResized
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
方法overrided其正确地调整大小的数据的组件监听器(保持固定纵横比)以适合的大小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);
....
}
}
事实证明,原样,数据没有正确调整大小。我做了一些调试,发现componentResized
在我关闭和打开颜色条后调用paintComponent
方法后。这意味着图像被绘制,然后scaleFactor
后来得到更新,这是不正确的。到目前为止,我已经能够修复它的唯一方法是在componentResized
方法的末尾呼叫repaint()
。但是,在调整组件大小时已调用repaint()
,所以我觉得这是不正确的方法。一些Google搜索引导我转向涉及使用revalidate
和repaint
的解决方案,然后根据需要修改JPanel
。但是,这样做的任何组合仍然导致在repaint
之后调用componentResized
。有没有这个标准的修复?
这似乎是一个复杂的设置,使得使用代码片段和简短的解释很难完全理解。我们不希望看到整个程序,但如果您很快就没有获得帮助,请考虑创建并发布[最小,完整和可验证示例程序](http://stackoverflow.com/help/mcve),其中您可以将代码压缩到仍然编译和运行的最小位,没有外部依赖性(例如需要链接到数据库或映像),没有额外的代码与您的问题无关,但仍然表明您的问题。 – 2014-09-23 02:18:10
请注意,'componentResized'可以快速连续多次调用,例如窗口大小调整时。我过去所做的是使用'javax.swing.Timer',设置为不重复,并使用一个小延迟(〜100ms),每次调用componentResized时重新启动它。这会阻止计时器触发更新,直到100ms过去。一旦触发,我执行我需要的更新并调用'repaint' ...另一种解决方案是重写'invalidate'并重置缓冲区(为'null'),并在调用缓冲区时使用'paintComponent'重建缓冲区缓冲区是'null') – MadProgrammer 2014-09-23 02:19:31
@MadProgrammer现在主要的问题是它被调用的顺序。我需要在'paintComponent'之前调用'componentResized'。出于某种原因,通过我上面的设置,'componentResized'在'paintComponent'之后的最后被调用。我会尽力得到一个完整的例子。 – Justin 2014-09-23 02:30:30