这是绘制椭圆形的简单示例。
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 中的性能。
文章 在 AWT 和 Swing 中绘画:附加油漆属性:不透明度 指出了原因:"不透明属性允许 Swing 的绘制系统检测特定组件上的重新绘制请求是否需要对潜在祖先进行额外的重新绘制。因为扩展了JComponent
,所以默认情况下 opaque
属性为 false,并且无法进行优化。设置属性true
以查看差异,以及不兑现属性的项目。相关示例可在此处和此处找到。
我同意康斯坦丁的观点,您需要记住的是,重绘管理器在应用程序启动时会响应任意数量的请求,这通常包括显示窗口和调整大小时的初始绘制请求(有两个)。
试试这个。等到应用程序运行并调整窗口大小。 我相信你会得到更多,而不是几个重新粉刷请求;)
对我来说很好用。事实上,即使在调试模式下,输出也是:
paintComponent
Paint border
Paint children
请记住,在 AWT 和 Swing 组件中,有许多方法(paint、paintBorder、paintChildren、paintComponent、repaint 等)在 GUI 引擎找到合适的时间时通过回调调用。这可能因 JVM 而异,甚至因不同的执行会话而异。它们也可以从与程序的交互中触发(例如,如果您最小化/最大化)。或者他们可能根本不会。