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

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

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绘制两次组件。

的paintComponent

油漆边框

画儿童

的paintComponent

油漆边框

画儿童

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

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

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

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

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

 paintComponent Paint border Paint children 

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