问题描述
请看下面的代码:
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.
It basically just draws two panels on top of third one: panel A, which is red, and panel B, which is green. The red panel A has lower z-order and is therefore painted over the panel B.Now if we force the panel B to repaint itself (just click on the JFrame, outside of both panels A and B), suddenly the panel B paints OVER the panel A.
如果我切换到使用 JComponent 而不是 JPanel,它可以正常工作并且 B 不会在 A 上绘制.看起来 JPanel 只是忽略了 Z 顺序.因此,解决方案似乎是使用 JComponent 而不是 JPanel.只是出于好奇 - 这种无 Z 顺序的行为对于 JPanel 是正常的吗?
If I switch to using JComponent instead of JPanel, it works correctly and B will not paint over A. It would seem that JPanel simply ignores the Z-order. So, the solution seems to be to use JComponent instead of JPanel. Just out of curiosity - is this Z-order-ignoring behavior normal for JPanel?
推荐答案
您的代码告诉红色面板重新绘制它自己.现在尝试更改 JFrame 的大小,面板将重新绘制.这是因为 Z-Order 仅在父面板重新绘制其所有子面板时才适用.这就是垃圾神的解决方案在这种情况下有效的原因.
Your code is telling the red panel to repaint itself so it does. Now try changing the size of the JFrame and the panels will repaint. This is because the Z-Order only applies when the parent panel repaints all its children. That is why trashgod's solution works in this case.
JComponent 行为如此的原因是因为它是非不透明的,所以每当它需要重新绘制时,需要先绘制其父级的背景,因此您最终会以 Z 顺序调用绘制父面板.
The reason the JComponent behaves the way it does is because it is non-opaque, so whenever it needs to be repainted the background of its parent needs to be painted first so you end up invoking the painting in the Z-Order of the parent panel.
所以两者的区别在于组件的不透明性.
So the difference between the two is the opaqueness of the components.
这篇关于JPanel 组件绘制顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!