7

这是绘制椭圆的简单示例。

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);
        }
    }
}

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

油漆组件

绘制边框

画孩子

油漆组件

绘制边框

画孩子

我不明白为什么会发生这种情况,但我认为它会影响困难 GUI 中的性能。

4

3 回答 3

9

文章在 AWT 和 Swing 中绘制:附加绘制属性:不透明度说明了原因:“不透明属性允许 Swing 的绘制系统检测对特定组件的重新绘制请求是否需要对底层祖先进行额外的重新绘制。” 因为你extend JComponent,所以opaque属性默认为false,无法优化。设置属性true以查看差异,以及不尊重属性的工件。相关示例可在此处此处找到。

于 2012-08-15T10:19:40.843 回答
2

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

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

于 2012-08-15T10:13:35.407 回答
2

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

paintComponent
Paint border
Paint children

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

于 2012-08-15T10:15:30.970 回答