从实现效果来看,repaint和updateUI差不多的。
那么rePaint和updateUI实质区别是什么,求解。实例问题:
开发工具:MyEclipse
Java环境:jre1.6.0我写了一个界面程序,通过一个button点击弹出图片,做好之后无法显示图片,我以为是图片路径问题,于是在监听里面修改了图片路径,加上了panel.updateUI()就OK了。
然后实现另一个button再添加另一张图片,也不行。在第二个button的监听当中加上了panel.repaint()也OK了。为了测试repaint和updateUI的区别,我注释掉第二个button监听中的panel.repaint(),这时候,奇迹发生了,居然注释了之后第二个button依然可以完成功能添加另一张图片。
于是,我再注释掉第一个button监听中的panel.updateUI(),奇迹再次发生,现在不使用repaint和updateUI方法也可以实现按钮点击后界面的更新。
为了搞清楚“奇迹”的来源,我写了一个测试。
public class TestDisplay extends JPanel{
JPanel panel=new JPanel();

public TestDisplay(){
JButton button=new JButton("Click");
button.addActionListener(new ButtonTest());
panel.add(button);
add(panel);
}

class ButtonTest implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
panel.add(new JButton("Test"));
panel.updateUI(); add(panel);
}
}
}public class Test {

public static void main(String[] args) {
TestDisplay td=new TestDisplay();
JFrame myFrame = new JFrame();
myFrame.setContentPane(td);
myFrame.setPreferredSize(new Dimension(700,550));
myFrame.setLocation(300, 150);
myFrame.pack();
myFrame.setVisible(true);
}}在此测试程序中,删除了updateUI()<红色部分>方法就无法实现显示中添加一个按钮的功能了,而这个测试程序将updateUI()改成repaint()也无法实现功能。
问题!!!!:那么实现这类事件监听中更改了界面的功能,是否必须调用界面容器的updateUI或repaint方法?如果是,那么请问,应该调用哪一个?两者有何区别?小弟初次编写GUI程序,急求解答,望各位大侠帮忙!!!

解决方案 »

  1.   

    引用资料,希望对你有帮助!
    Painting in Swing 
    Swing组件和AWT组件一样支持callback机制,拥有repaint方法,而且swing组件还内置了双缓冲机制和附加结构,如边界和UI delegate,还提供了 RepaintManager API 
    Swing组件默认是不透明的 
    不透明:会形成屏幕垃圾 
    透明:不会形成屏幕垃圾,降低效率 
    Swing组件的paint方法实际上是调用三个独立的方法,即: 
    1、   protected void paintComponent(Graphics g) 
    2、   protected void paintBorder(Graphics g) 
    3、   protected void paintChildren(Graphics g)  
    swing组件应该重载paintComponent方法而不是paint方法,而且尽量不要重载paintBorder和paintComponents方法(虽然这是允许的)。 
    UI delegates:标准swing组件实现的外观(look-and-feel) 
    与UI delegates相关联的标准组件的paint遵循下列步骤: 
    1、  paint方法调用paintComponent方法 
    2、  如果ui属性非空,paintComponent方法调用ui.update方法 
    3、  如果组件opaque属性为真,即不透明的话,ui.update方法会使用背景色填充背景,然后调用ui.paint方法 
    4、  ui.paint方法绘制组件内容 
    所以在重载的paintComponent方法中要调用super.paintComponent()方法,否则在不透明的前提下,组件必须负责填充背景。 
    Swing中paint调用的两种途径: 
    A.      由第一个重量级的祖先(ancestor)调用paint请求(通常是JFrame, JDialog, JWindow, JApplet) 
    1、  事件调度线程调用paint方法 
    2、  Container.paint方法默认操作是循环调用所有轻量级子类(descendents)的paint方法 
    3、  当绘制到第一个swing组件的时候,JComponent.paint方法的默认操作如下: 
    1.         如果组件实现了双缓冲的话,自动在内存中分配一个Graphics对象的副本; 
    2.         调用paintComponent方法(如果双缓冲的话就作用在后台(offscreen)graphics对象) 
    3.         调用paintBorder方法(如果双缓冲的话就作用在后台(offscreen)graphics对象) 
    4.         调用paintChildren方法(如果双缓冲的话就作用在后台(offscreen)graphics对象) 
    5.         如果组件实现了双缓冲的话,将后台graphics复制到前台来 
    B.      由javax.swing.JComponent的扩展的repaint方法产生的paint请求: 
    (详见原文) 主要是调用paintImmediately方法,对于swing组件来说,决定不会调用update方法。 
    Swing Painting Guidelines: 
    1、  swing组件中,paint方法通常是被系统或者应用程序触发,update方法决不会被swing组件触发; 
    2、  程序要调用repaint方法来实现paint功能,而不能直接调用paint方法; 
    3、  如果组件有复杂输出的话,应该使用带参数的repaint方法,即只重画需要重画的矩形区域,否则就要重新绘制全部组件; 
    4、  Swing组件的paint方法依次调用下列函数: 
           1.       paintComponent() 
           2.       paintBorder() 
           3.       paintChildren() 
    swing组件的子类如果想实现绘制代码的话,需要重载paintComponent方法,而不是paint方法; 
    5、  swing推荐两个属性用来提高绘制效率: 
           1.       opaque:组件是否绘制所有像素点,即透明与否,默认不透明 
          2.       optimizedDrawingEnabled:是否组件的子类有交迭,只重画交迭部分提高效率,默认true,有交迭; 
    6、  如果swing组件的opaque属性设为真,即不透明的话,那么就会绘制所有的像素点(包括使用paintComponent方法清除背景),否则会保留屏幕垃圾(透明); 
    7、  把opaque或optimizedDrawingEnabled的任何一个属性设成false,会增加绘制的处理过程; 
    8、  Swing组件的拥有UI delegates的子类(包括JPanel),应该在他们的paintComponent()方法里调用super.paintComponent()方法,因为UI delegates要负责重画背景的工作,还要注意第五点; 
    9、  Swing组件支持双缓冲机制,可以靠JComponent.doubleBuffered属性来设置,默认为true; 
    10、 强烈推荐将swing的所有组件设成双缓冲; 
    11、 有着复杂输出的组件应该合理使用要重绘的区域来减少有覆盖时候的绘制操作。