當你的元件 paint() 被呼叫時, 在 Swing 的設計下,
預設的呼叫順序情況如下.
Step 1: paintComponent(Graphics g): 畫出目前元件的樣子
Step 2: paintBorder(Graphics g): 畫出目前的外框
Step 3: paintChildren(Graphics g): 呼叫所包含元件的 paint()
所以如果你的元件, 直接 override paint method,
然後不寫任何程式碼.
public void paint(Graphics g){
}
那麼你的元件+外框+所有的子元件都不會被畫出來.
為何畫元件時, 會產生閃爍的現象? -- 簡單的說, 就是因為你的 paintComponent 呼叫了清除畫面的程式碼.
JDK 中 paintComponent method 實作長相大致上如下:
protected void paintComponent(Graphics g) {
if (ui != null) {
// 如果有安裝 UI Delegate, 則呼叫 ui 的 update method
Graphics scratchGraphics = (g == null) ? null : g.create();
try {
ui.update(scratchGraphics, this);
}
finally {
scratchGraphics.dispose();
}
}
}
其中 ui 的 update method 實作, 如下:
public void update(Graphics g, JComponent c) {
if (c.isOpaque()) {
// 不透明
// 下面這段就是為什麼, 元件重畫時會閃爍的原因
g.setColor(c.getBackground());
g.fillRect(0, 0, c.getWidth(),c.getHeight());
}
paint(g, c); // <----- 這邊才是畫出預設元件的畫面
}
所以預設的情況下, 就是會閃爍. 為了防止這種情況, 你應該自己寫一個 paintComponent 繞過清背景的程式碼.
這樣你的元件就不會閃爍了.
References
1. http://java.sun.com/products/jfc/tsc/articles/painting/#paint_process
2. http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComponent.html
3. http://www.javafaq.nu/java-allbooks-8.html
沒有留言:
張貼留言