各位大大好,我是跟著視頻自學的java純新手,在寫的代碼中出現了一些問題想請教一下 代碼如下
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class myFrame extends JFrame implements KeyListener{
private ListallBG=new ArrayList();
private background nowBG=null;
public static void main(String args[]){
new myFrame();
}
public myFrame(){
this.setTitle("馬裡奧游戲程序");
this.setSize(900,600);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
//初始化場景之前要初始化全部圖片
StaticValue.init();
//創建全部場景
for(int i=1;i<=3;i++){
this.allBG.add(new background(i,i==3?true:false));
}
//將第一個場景設置為當前場景
this.nowBG=this.allBG.get(0);
//測試nowBG是否為空,非空
if(nowBG==null){
System.out.println("is null");
}
else
System.out.println("not null");
this.repaint();
this.addKeyListener(this);
}
public void paint (Graphics g){
//建立臨時緩沖圖片
BufferedImage image=new BufferedImage(900,600,BufferedImage.TYPE_3BYTE_BGR);
Graphics g2=image.getGraphics();
if (nowBG!=null){
g2.drawImage(this.nowBG.getBgImage(),0,0,this);
System.out.println("is not null");
}
else
System.out.println("is null");
//把圖片繪制到窗體
g.drawImage(image,0,0,this);
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
char a=e.getKeyChar();
int b=e.getKeyCode();
System.out.println(a+" "+b);
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
顯示出來的結果是
is null
not null
is not null
我想問一下paint()在什麼時候被調用的?為什麼被調用了兩次?為什麼paint()第一次被調用的時候nowBG沒有被初始化。然後就是運行的時候如果去掉paint()裡的if else判斷直接調用g2.drawImage(this.nowBG.getBgImage(),0,0,this)會出現java.lang.NullPointerException這該如何解決
首先一個概念,paint就是繪制的意思
.
你所看到的窗體(Window)
是個容器(Container)
,容器中有很多東西,比如你的JFrame
.
注意
看下面這段代碼:
this.setVisible(true);
this.setResizable(false);
//初始化場景之前要初始化全部圖片
StaticValue.init();
//創建全部場景
for(int i=1;i<=3;i++){
this.allBG.add(new background(i,i==3?true:false));
}
//將第一個場景設置為當前場景
this.nowBG=this.allBG.get(0);
//測試nowBG是否為空,非空
if(nowBG==null){
System.out.println("is null");
}
this.setVisible(true);
這行代碼先執行,而this.nowBG=this.allBG.get(0);
後執行。
setVisible(true)
的意思是在屏幕上顯示.
這句話會在引起它的父容器(包括爺爺容器、祖先容器)中的visible
字段的判斷.
而這個visible
聯合其它的字段來判斷是否需要重新繪制repaint
。
那麼,在你的this.allBG.add(new background(i,i==3?true:false));
執行前,
由於事先調用了setVisible
,所以你的paint
被調用,
這會導致你的問題直接調用g2.drawImage(this.nowBG.getBgImage(),0,0,this)會出現java.lang.NullPointerException這該如何解決
.
paint
方法調用的時機主要看容器中是否有髒的組件(dirtyComponents),這裡的髒
指的是否需要重新繪制組件。
所以當任何一個事件,比如最小化
、最大化(可能)
、重新調整窗體(或父容器)大小
,圖片的bits數(圖片是二進制數據)來了一批就paint一批等等,都會引起是否重繪(repaint
)的判定,那麼如果需要repaint
就可能調用'paint'.
你懂了嗎??請采納!!