为什么swing会简单地绘制两次?

Dra*_*gon 7 java graphics swing awt paintcomponent

这是绘制椭圆形的简单示例.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在调试模式或在绘制之前向控制台添加一些信息(如示例中),您可以看到swing绘制组件两次.

的paintComponent

油漆边框

画儿童

的paintComponent

油漆边框

画儿童

我无法理解它为什么会发生,但我认为它会影响困难的GUI中的性能.

tra*_*god 9

文章绘画在AWT和Swing:附加油漆属性:不透明度表明原因:"不透明属性允许Swing的油漆系统检测特定组件上的重绘请求是否需要额外重新绘制基础祖先." 因为您进行了扩展JComponent,所以opaque默认情况下该属性为false,并且无法进行优化.设置属性true以查看差异,以及不尊重属性的工件.可在此处此处找到相关示例.