2010-07-29 52 views
1

請參閱下面的代碼:JPanel組件繪製順序

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Main { 
    public static void main(String[] args) { 
    final JFrame f=new JFrame("foo"); 
    final JPanel c=new JPanel(null); 
    f.setContentPane(c); 
    c.setPreferredSize(new Dimension(500,500)); 
    final JPanel a=new JPanel(null){ 
     @Override 
     protected void paintComponent(Graphics g) { 
     g.setColor(Color.red); 
     g.fillRect(0, 0, getWidth(), getHeight()); 
     } 
    }; 
    a.setBounds(0,0,300,300); 
    c.add(a); 
    final JPanel b=new JPanel(null){ 
     @Override 
     protected void paintComponent(Graphics g) { 
     g.setColor(Color.green); 
     g.fillRect(0, 0, getWidth(), getHeight()); 
     } 
    }; 
    b.setBounds(200,200,500,500); 
    c.add(b); 
    c.setComponentZOrder(a, 0); 
    f.pack(); 
    f.setVisible(true); 
    f.addMouseListener(new MouseAdapter() { 

     @Override 
     public void mouseClicked(MouseEvent e) { 
     b.repaint(); 
     } 
    }); 
    } 
} 

它基本上只是借鑑了第三個的上面兩組:A組,這是紅色的,而面板B,這是綠色的。紅色面板A具有較低的z順序,因此被塗在面板B上。 現在,如果我們強制面板B重新繪製自己(只需單擊面板A和B之外的JFrame),則面板B突然顏色在面板A上。

如果我切換到使用JComponent而不是JPanel,它可以正常工作,並且B不會在A上繪製。看起來JPanel只是忽略了Z順序。所以,解決方案似乎是使用JComponent而不是JPanel。出於好奇 - 這個JPanel的Z順序忽略行爲是正常的嗎?

+0

謝謝您的意見!其實,要解決這個問題,請閱讀:[Swing Painting](http://java.sun.com/products/jfc/tsc/articles/painting/)(找到「Optimized」Drawing),也請閱讀:[ isOptimizedDrawingEnabled()](http://download.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#isOptimizedDrawingEnabled()) – 2011-07-10 17:50:45

回答

1

在您的鼠標處理程序中嘗試c.repaint()。此外,您無需重寫paintComponent()即可更改背景顏色。

public static void main(String[] args) { 
    final JFrame f = new JFrame("foo"); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    final JPanel c = new JPanel(null); 
    f.setContentPane(c); 
    c.setPreferredSize(new Dimension(500, 500)); 
    final JPanel a = new JPanel(); 
    a.setBounds(0, 0, 300, 300); 
    a.setBackground(Color.red); 
    c.add(a); 
    final JPanel b = new JPanel(); 
    b.setBounds(200, 200, 300, 300); 
    b.setBackground(Color.green); 
    c.add(b); 
    c.setComponentZOrder(a, 0); 
    f.pack(); 
    f.setVisible(true); 
    f.addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent e) { 
      c.repaint(); 
     } 
    }); 
} 
6

如果我切換到使用替代的JPanel的JComponent ,它工作正常 和B不會畫在A.

你的代碼是告訴紅色面板本身重繪所以確實。現在嘗試更改JFrame的大小,並重新繪製面板。這是因爲Z-Order僅在父面板重繪其所有子項時才適用。這就是爲什麼trashgod的解決方案適用於這種情況。

JComponent的行爲方式是因爲它是非透明的,所以無論何時需要重繪它的父級的背景都需要首先繪製,以便最終調用Z-Order中的繪畫的父面板。

所以兩者的區別在於組件的不透明性。

+0

優秀;更多討論可以在「其他塗料屬性」中找到:http://java.sun.com/products/jfc/tsc/articles/painting/#props – trashgod 2010-07-30 03:18:17