【问题标题】:JPanel component draw orderJPanel 组件绘制顺序
【发布时间】:2010-07-29 09:07:14
【问题描述】:

请看以下代码:

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 顺序的行为是否正常?

【问题讨论】:

标签: java swing


【解决方案1】:

如果我切换到使用 JComponent 而不是JPanel,它可以正常工作 B 不会在 A 上绘画。

您的代码告诉红色面板重新绘制它自己。现在尝试更改 JFrame 的大小,面板将重新绘制。这是因为 Z-Order 仅适用于父面板重新绘制其所有子面板时。这就是为什么垃圾神解决方案在这种情况下有效的原因。

JComponent 的行为方式是因为它是不透明的,所以每当需要重新绘制它时,需要先绘制其父级的背景,因此您最终会以 Z 顺序调用绘制父面板。

所以两者的区别在于组件的不透明性。

【讨论】:

【解决方案2】:

在您的鼠标处理程序中尝试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();
        }
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2023-03-07
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多