repaint() paint() update()重量级 轻量级
本人查找了许多网页 都说系统会自动调用repaint() 然后 如果是重量级组件 则repaint()调用 update() 而update()再调用paint()
而且API文档貌似也是这么说 可是我试验的结果却不是这样
而如果是轻量级组件则系统会自动调用repaint() 然后repaint()直接调用paint()
于是我试了试, 代码如下:
Java code
import java.awt.*;
import javax.swing.*;
public class TestLib extends JFrame{
public static void main(String[] args) {
TestLib c = new TestLib();
c.setSize(200,200);
c.setVisible(true);
}
TestLib() {
Component2 c = new Component2();
getContentPane().add(c);
}
}
class Component2 extends Button {
public void update(Graphics g) {
super.update(g);
System.out.println("update!!");
}
public void paint(Graphics b) {
super.paint(b);
System.out.println("paint!!");
}
public void repaint() {
super.repaint();
System.out.println("repaint");
}
}
可是测试结果是一开始只有paint!! 然后我用别的窗口遮住程序的窗口 然后再移开 还是出现一个paint!! 每次都这样 从来没有调用过repaint
这是为什么?假如把Button改成JButton 结果是一出来就3个paint!!
这是为什么?------解决方案--------------------先看看这篇文章吧:
http://blog.csdn.net/yanghai0321/article/details/6916657
------解决方案--------------------没仔细研究过,先看看2楼说的这篇文章
------解决方案--------------------对于这个问题,我们分两步说
第一:repaint(),paint(), update()三者的调用关系
repaint() 方法:
根据 API 可以得知,
当前控件为轻量级控件时, repaint() 会调用该控件的 paint() 方法
(但是我从源码上没有看出来其有调用 paint,而是在递归的调用父控件的 repaint,从理论上说,这个过程必然会最终找到一个 Window 级的重要级控件)
当前控件为重量级控件时, repaint() 会调用该控的 update() 方法
(但是从源码上看,其是产生了一个 PaintEvent 事件,并派发至事件序列中,待线程去处理,这个处理的过程的代码貌似看不到,其具体是执行的 update() 方法,还是 paint() 方法也不得而知)
update()方法:
在 Component 类中,其单纯的调用了 paint(),至于 Component 的各个子孙类有无重写该方法,要一个个去看
但是根据观察,基本上没有几个类有重写这个方法,即便是重写的,也是一样单纯的调用了 paint() 方法
paint() 方法:
在 Component 类中,没有任何实现,应该是在 Component 的子孙类中各自实现的
这里就产生了一个问题:update()方法真的有被调用么?在哪里调用了?
从实验的结果看,这个方法无论什么时候似乎都没有被调用,
而且该方法的存在也很鸡肋
可有可无,单纯的调一下 paint(),还不如直接调用 paint() 呢
所以我在这里做一个大胆的假设,PaintEvent 派发至事件序列之后,处理时是直接调用了 paint() 方法,而没有调用 update 方法
这就和 API 的说明有冲突了,
可能是 Java 的开发人员觉得这是底层实现,实现他们已经改了,API 也懒得改了
也可能是和系统相关,我是在 windows 下测试的,不知道 linux 下有无变化
也可能是我实验没有做仔细,希望大家给点不同意见
第二:repaint() 是什么时候自动调用的?
重量级控件的话,我还真不知道是什么时候自动调用的,
从实验结果上看,似乎也没哪里自动调用这个方法了,
轻量级控件的话,
去看各个控件对应的 UI 类就知道了
UI 类中注册了大量的事件监听器
比如大小变化时、获得/失去焦点时、鼠标进入/移出时、等等
很多地方都显式调用了 repaint 方法
这就是自动调用 repaint 方法的来源了
所以 Button 我不能确定其会自动调用 repaint 方法
而 JButton 你想知道其什么时候会自动调用 repaint 方法,去看一下其对应的 UI 类(MetalButtonUI、BasicButtonUI)
------解决方案--------------------我觉得吧,repaint()这个方法应该是程序员自己调用的吧,将repaint写在事件处理中,然后当事件触发时,系统再调用它。若是没有对事件进行监听的话,系统应该只会调用paint方法