日期:2014-05-20  浏览次数:20776 次

java双缓冲中,为什么我调用repaint时,它直接调用paint()而不是update(),怎么改进?
Java code


import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class pic extends JFrame{

     Image image=null;
     Image offscreen;
     int hight=400;
     int width=400;
    
    public pic(){
        this.setSize(hight,width);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
           setVisible(false);
                System.exit(0);
            }
        });
        this.setResizable(false);
        this.setVisible(true);
       
        
    }
    public void paint(Graphics g){
            
        System.out.println("paint...");
        
    }
    public void update(Graphics g){
        image=new ImageIcon("C:\\Users\\Administrator\\Desktop\\z.jpg").getImage();//路径改变
        this.offscreen=this.createImage(hight,width);
        Graphics goff=this.offscreen.getGraphics();
        goff.drawImage(image,0,0,null);
        System.out.println("update.....");
        paint(goff);
        g.drawImage(offscreen,0,0,null);
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new pic().repaint();

    }

    }

为什么我调用repaint时,它直接调用paint()而不是update(),怎么改进?

------解决方案--------------------
不是JFrame 是Frame!另外,重绘最好放在另外一个线程
Java code


import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;

public class pic extends Frame implements Runnable{

     Image image=null;
     Image offscreen;
     int hight=400;
     int width=400;
    
    public pic(){
        this.setSize(hight,width);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
           setVisible(false);
                System.exit(0);
            }
        });
        this.setResizable(false);
        this.setVisible(true);
       
        
    }
    public void paint(Graphics g){
        System.out.println("paint...");
        
    }
    public void update(Graphics g){
        image=new ImageIcon("C:\\Users\\Administrator\\Desktop\\z.jpg").getImage();//路径改变
        this.offscreen=this.createImage(hight,width);
        Graphics goff=this.offscreen.getGraphics();
        goff.drawImage(image,0,0,null);
        System.out.println("update.....");
        paint(goff);
        g.drawImage(offscreen,0,0,null);
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
       new Thread( new pic()).start();

    }
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            repaint();
        }
    }

    }

------解决方案--------------------
JFrame的update方法只是调用 paint(g)。重写此方法,以防止不必要的调用清除背景。

JFrame的repaint方法是由类 java.awt.Component 继承的方法,如果此组件是轻量级组件,则repaint方法会尽快调用此组件的 paint 方法。否则此方法会尽快调用此组件的 update 方法。

双缓冲绘图一般都不直接在JFrame上绘制,一般是用JFrame绘制组件吧。

JDK API doc 上面有你的问题的答案。