import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Images extends JFrame {
public static void main(String[] args) {
DisplayMode dm = new DisplayMode(800,600,32, DisplayMode.REFRESH_RATE_UNKNOWN);
Images I = new Images();
I.run(dm);
}
private Screen s;
private Image bg;
private Image pic;
private boolean nLoaded;
Animation a;
public void run(DisplayMode dm)
{
nLoaded = false;
s = new Screen();
try{
s.Setfullscreen(dm, this);
LoadPics();
MovieLoop();
try{
Thread.sleep(50000);
}catch(Exception ex){}
}finally{
s.restoreScreen();
}
}
public void MovieLoop(){
long startingtime = System.currentTimeMillis();
long cumTime = startingtime;
while(cumTime-startingtime < 5000)
{
long timepassed = System.currentTimeMillis() - cumTime;
cumTime += timepassed;
a.update(timepassed);
Graphics g = s.getFullScreenWindow().getGraphics();
draw(g);
g.dispose();
try{
Thread.sleep(20);
}catch(Exception ex){}
}
}
public void draw(Graphics g)
{
g.drawImage(bg, 0,0, null);
g.drawImage(a.getImage(),0,0,null); }
//Create Load Pictures
public void LoadPics()
{
bg = new ImageIcon("C:\\Gamepics\\BackgroundImage.jpg").getImage();
pic = new ImageIcon("C:\\Gamepics\\SmileyIcon3.png").getImage();
nLoaded = true;
repaint();
}
public void paint(Graphics g){
if(g instanceof Graphics2D){
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
if(nLoaded)
{
g.drawImage(bg, 0, 0, null);
g.drawImage(pic, 300,300, null);
}
}
}
我不明白我做错了什么我已经尽力忽略了一切。我只是练习一个简单的动画,我不断得到3个空指针异常。 我已经研究过最好的东西,显然java中的NullPointerExceptions与尝试获取空数组的大小有关吗?编译器没有将我的任何列表标记为问题,所以我有点困惑。任何帮助将不胜感激。所有错误都被注释掉了。它们有三个,它们在Images类
中错误:
Exception in thread "main" java.lang.NullPointerException
at Images.MovieLoop(Images.java:45)
at Images.run(Images.java:26)
at Images.main(Images.java:8)
动画类
import java.awt.Image;
import java.util.*;
public class Animation {
private ArrayList scenes;
private int sceneindex;
private long movietime;
private long totaltime;
//CONSTRUCTOR
public Animation(){
scenes = new ArrayList();
totaltime =0;
start();
}
//Add scene to array list and sets time for each scene
//For example. If you have 3 scenes you would add t to total time three times. So if you had
//3 Scenes, one for 1s, one for 2s, one for 3s. Total time would be 6s. and you would call addscene 3 times
public synchronized void addScene(Image i, long t)
{
totaltime+=t;
scenes.add(new OneScene(i, totaltime));
}
//start animation from beggininign inignngingingnig
public synchronized void start(){
movietime = 0;
sceneindex = 0;
}
//change scenes
//movie time is the sum of all the time passed from last update
//If you have more than one scene. timepassed gets added to movietime.
//if movietime is greater than or equal to total time(ie. animation is complete) restart the animation
public synchronized void update(long timepassed)
{
if(scenes.size() > 1){
movietime += timepassed;
if(movietime >= totaltime)
{
movietime = 0;
sceneindex = 0;
}
while(movietime > getScene(sceneindex).endTime)
{
sceneindex++;
}
}
}
public synchronized Image getImage(){
if(scenes.size() == 0){
return null;}
else{
return getScene(sceneindex).pic;
}
}
//Getscene
private OneScene getScene(int x){
return (OneScene)scenes.get(x);
}
//Scenes are gonna be
private class OneScene{
Image pic;
long endTime;
public OneScene(Image pic, long endTime)
{
this.pic = pic;
this.endTime = endTime;
}
}
}
我包含了动画类,因为编译器突出显示这三个方法调用作为问题的来源
a.update(timepassed);
MovieLoop();
I.run(dm);
答案 0 :(得分:1)
请注意:这是一个非常长的评论
让我们从Graphics g = s.getFullScreenWindow().getGraphics();
开始 - getGraphics
绝对不是一个好主意,这可以返回null
。
你不应该尝试从EDT以外的任何线程更新任何UI组件,你不应该以这种方式直接绘制它,相反,你应该使用paintComponent
。
您不应该dispose
您自己没有创建的Graphics
个上下文,这样可以防止绘制其他组件。
你应该避免覆盖paint
,特别是顶层容器,如果没有其他原因,它不是双缓冲(顶级容器),你也将绘制任何其他子组件。< / p>
查看Performing Custom Painting了解详情。
您应该尝试使用ImageIO
代替ImageIcon
。 ImageIO
如果无法读取文件,则会抛出异常,ImageIcon
只是无声地失败,没有用处。