我有一個顏色欄的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