- 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 上面有你的问题的答案。