Java 为什么swing要画两次简单的组件?

Java 为什么swing要画两次简单的组件?,java,swing,graphics,awt,paintcomponent,Java,Swing,Graphics,Awt,Paintcomponent,下面是绘制椭圆形的简单示例 public class SwingPainter extends JFrame{ public SwingPainter() { super("Swing Painter"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); getContentPane().add(new MySwingComponent());

下面是绘制椭圆形的简单示例

public class SwingPainter extends JFrame{
    public SwingPainter() {
        super("Swing Painter");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        getContentPane().add(new MySwingComponent());

        setSize(200, 200);
        setVisible(true);
    }

    public static void main(String[] args) {
        new SwingPainter();
    }

    class MySwingComponent extends JComponent {

         public void paintComponent(Graphics g) {
            System.out.println("paintComponent");
            super.paintComponent(g);
            g.setColor(Color.red);
            g.fillOval(10, 10, 50, 50);
        }

        @Override
        protected void paintBorder(Graphics g) {
            System.out.println("Paint border");
            super.paintBorder(g);
        }

        @Override
        protected void paintChildren(Graphics g) {
            System.out.println("Paint children");
            super.paintChildren(g);
        }
    }
}
但在调试模式下,或者在绘制之前向控制台添加一些信息(如示例所示),您可以看到swing绘制组件两次

油漆组件

画框

画孩子

油漆组件

画框

画孩子


我无法理解为什么会发生这种情况,但我认为它会影响复杂GUI中的性能。

我同意Konstantin的观点,您需要记住的是,重绘管理器在应用程序启动时会响应任意数量的请求,这通常包括显示窗口并调整大小时的初始绘制请求(有两个)


试试这个。等待应用程序运行并调整窗口大小。我相信你会收到更多的重新绘制请求;)

这对我很管用。事实上,即使在调试模式下,输出也是:

paintComponent
Paint border
Paint children

请记住,在AWT和Swing组件中,只要GUI引擎认为合适,就有许多方法(paint、paintBorder、paintChildren、paintComponent、repaint和其他)通过回调调用。这可能因JVM而异,甚至因执行会话而异。它们也可以从与程序的交互中触发(例如,如果最小化/最大化)。或者它们可能根本不需要。

文章给出了原因:“不透明属性允许Swing的绘制系统检测特定组件上的重新绘制请求是否需要对底层祖先进行额外的重新绘制。”因为您扩展了
JComponent
不透明属性默认为false,优化是不可能的。设置属性
true
以查看差异,以及不尊重该属性的工件。相关的例子可以找到。

可能重复的可能重复的可能重复的是的,你是对的。这是因为不透明。当我将其设置为true时,控制台输出中只有3条记录。我需要更彻底地调查不透明的工作:)