I have searched for the past few days for a solution to this problem and I am beating my head against the wall. I'm knew to programming in java so bear with me.
I am currently trying to implement a Java Applet into an HTML page of mine for a school project. The Applet runs fine in Eclipse using AppletViewer, as well as in the web browser in a program called Blue Jay. I have exported the program into a jar file in the same directory as my HTML page, and added the necessary code to my HTML file, but whenever I actually run the HTML file the Applet gives me an "Illegal Argument Exception: name" error. The details of the error include the phrase "java.net.MalformedURLException:unknown protocol:e."
This is the relevant code for my HTML file:
<applet code="MovingBoxes.class" archive="E:\WebSystems\WebPages\Animations.jar"
width="350" height="350" >Animation of moving boxes</applet>
When the error occurs the phrase inside of the applet tags is not displayed either if that is significant. I have tried exporting other applets to see if they work and have received the same error every time. I'm also fairly certain that the destination for the file is correct, because when I change the destination name to something incorrect a "Class Not Found" error occurs instead.
And in the off chance that the error is in my applet, here is my applet code.
package theBig;
import java.awt.*;
public class MovingBoxes extends java.applet.Applet implements Runnable
{
Thread runner;
int size = 15;
int x_value = 200;
int y_value = 175;
int rndm_x;
int rndm_y;
int move = 1;
int cntr = 0;
Image dbImage;
Graphics dbg;
int x_value2 = 240;
int y_value2 = 250;
int rndm_x2;
int rndm_y2;
public void start()
{
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
public void stop()
{
if (runner != null) {
runner.stop();
runner = null;
}
}
public void run()
{
setBackground(Color.white);
while (true) {
rndm_x = (int)(Math.random()*10+1);
rndm_y = (int)(Math.random()*10+1);
if (rndm_x > 5)
x_value += move;
else
x_value -= move;
if (rndm_y > 5)
y_value = 50;
else
y_value = 50;
rndm_x2 = (int)(Math.random()*10+1);
rndm_y2 = (int)(Math.random()*10+1);
if (rndm_x2 > 5)
x_value2 += move;
else
x_value2 -= move;
if (rndm_y2 > 5)
y_value2 = 50;
else
y_value2 = 50;
if (x_value + size > x_value2)
{
cntr = 50;
}
while(cntr > 0)
{
cntr --;
x_value --;
x_value2 ++;
repaint();
try { Thread.sleep(25); }
catch (InterruptedException e) { }
}
repaint();
try { Thread.sleep(25); }
catch (InterruptedException e) { }
}
}
public void update(Graphics g) {
dbImage = createImage(getWidth(),getHeight());
dbg = dbImage.getGraphics();
paint(dbg);
g.drawImage(dbImage,0,0,this);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawRect(x_value, y_value, size, size);
g.fillRect(x_value, y_value, size, size);
g.setColor(Color.blue);
g.drawRect(x_value2, y_value2, size, size);
g.fillRect(x_value2, y_value2, size, size);
}
} `
Like I said, I have searched everywhere for an answer and come up empty handed. Any help you can offer me is greatly appreciated.
Maybe its a typo but you are missing a " after .jar in your HTML code.
If that doesn't help, maybe your archive should be a URL, not just a file path. Can you try this:
<applet code="MovingBoxes.class" archive="file:/E:/WebSystems/WebPages/Animations.jar"
width="350" height="350" >Animation of moving boxes</applet>
Related
I am trying to make a simple game with Java swing/awt.
I am have issue with lagging while printing and moving images on the screen.
Here is my code below:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
public class StarDef extends JFrame implements Runnable, KeyListener{
private BufferedImage back;
private boolean start = false, end = false;
public int w = 1500, h = 800, commandx = 200, commandy = 100, ground = 500, mineral = 100;
private int mineralx = 0, mineraly = commandy + 104;
private int dronecnt = 0;
private ArrayList<Drone> DrList = null;
private ArrayList<Enemy> EnList = null;
private ArrayList<Building> BuildList = null;
private ArrayList<Allies> AlyList= null;
public Image imagearr[] = new Image[10];
private boolean makedrone = false, NeedMinerals = false;
public int picnum = 1;
private int OrderBuild = 0;
public static void main(String[] args){
Thread t = new Thread(new StarDef());
t.start();
}
public StarDef(){
back = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
DrList = new ArrayList<>();
BuildList = new ArrayList<>();
EnList = new ArrayList<>();
AlyList = new ArrayList<>();
this.addKeyListener(this);
this.setSize(w,h);
this.setTitle("Starcraft");
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
try {
imagearr[0] = ImageIO.read(new File("Char/Command.png"));
imagearr[1] = ImageIO.read(new File("Char/droneleft.png"));
imagearr[2] = ImageIO.read(new File("Char/droneright.png"));
imagearr[3] = ImageIO.read(new File("Char/Mineral.png"));
imagearr[4] = ImageIO.read(new File("Char/barracks.png"));
} catch (Exception e){
e.printStackTrace();
}
}
public void initGame(){
DrList.clear();
mineral = 100;
}
public void draw(){
Graphics gs = back.getGraphics();
gs.setColor(Color.white);
gs.fillRect(0,0,w,h);
gs.setColor(Color.DARK_GRAY);
gs.fillRect(0,ground,w,200);
if (!end) {
gs.drawImage(imagearr[0], commandx, commandy, null); // First Image-Command Center
gs.drawImage(imagearr[3], mineralx,mineraly,null); // Second Image-Mineral
for (int i = 0; i < DrList.size(); i++) { //Printing Drones
Drone m = DrList.get(i);
gs.drawImage(imagearr[m.state], m.x, m.y, null); //Drawing Drones
m.moveDr(); // Moving the Drone
}
for (int i = 0; i < BuildList.size(); i++){ //Printing Building
Building bd = BuildList.get(i);
if(bd.buildingtype == 'R'){
gs.drawImage(imagearr[4], bd.x, bd.y, null); // Drawing Building-Problem starts..?
}
}
gs.drawImage(imagearr[0], commandx, commandy, null);
}
gs.setColor(Color.black);
gs.drawString("mineral : " + mineral, 10,50);
gs.drawString("Drones : " + DrList.size(), 10, 70);
Graphics ge = this.getGraphics();
ge.drawImage(back, 0,0,w,h,this);
}
public void run(){
try{
int timer = 10;
while (true){
Thread.sleep(timer);
if(start){
if (makedrone) {
makedrone();
}
if (OrderBuild>0){
makeBuilding(OrderBuild);
}
}
draw();
}
} catch (Exception e){
e.printStackTrace();
}
}
public void makeBuilding(int buildingnumber){
int bdx, bdy;
char BuildingType;
if(buildingnumber == 1){
bdx = 500;
bdy = 100;
BuildingType = 'R';
Building barracks = new Building(this, bdx, bdy, BuildingType);
BuildList.add(barracks);
}
}
public void makedrone() {
if (mineral >= 50) {
int dronex = commandx;
int droney = commandy+129;
Drone dr = new Drone(this ,dronex, droney);
DrList.add(dr);
dronecnt++;
mineral -= 50;
makedrone = false;
} else if (mineral < 50) {
NeedMinerals = true;
makedrone = false;
}
}
public void keyPressed(KeyEvent ke){
switch (ke.getKeyCode()){
case KeyEvent.VK_ENTER:
start = true;
end = false;
break;
case KeyEvent.VK_D:
makedrone = true;
break;
case KeyEvent.VK_R:
OrderBuild = 1;
break;
}
}
public void keyReleased(KeyEvent ke){
switch ((ke.getKeyCode())){
}
}
public void keyTyped(KeyEvent ke) {
}
}
When you compile the code, the first few stationary images appear fine.
After moving images(Drones) appear nicely, but when you summon the next stationary image(Building), heavy lag starts to appear and the speed of the moving drones decrease visibly.
The building is about 300*150 pixels and the drones are 40*30 pixels.
What is the cause of this problem? Is this because of the code(the way of summoning the image), or the picture's size, or the computer(I am using a notebook(LG Gram 14in)).?
Start by not using Graphics ge = this.getGraphics();.
Because you're also using your own Thread, you're running the risk of thread race conditions which could result in dirty reads/ paints.
Start by understanding how Swing painting actually works and work within the API functionality.
Start by having a look at Performing Custom Painting, Painting in AWT and Swing and Concurrency in Swing
KeyListener is also a poor choice for monitor key input and you should be using the Key Bindings API - see How to use key bindings for more details.
Adding content to the ArrayList can cause the ArrayList to go through a growth cycle, which can consume time and force a longer GC cycle. Consider seeding the ArrayList with initial capacity, it will help reduce the interval between growth cycles.
Focus on separating the "update" logic from the "paint" logic, it can help you find performance issues
You could also have a look at
java what is heavier: Canvas or paintComponent()?
Swing animation running extremely slow
Rotating multiple images causing flickering. Java Graphics2D
Which demonstrate a verity of techniques for improving performance of rendering in Swing.
If these still are't getting your to the level you want, then you will want to explore using a BufferStrategy
Better draw in JPanel and use repaint() method to update your JPanel
This question already has answers here:
Class.getResource() returns null
(2 answers)
Closed 8 years ago.
This is my first question, I hope it's not too poorly made.
I'm definitely beginner level at java, probably lower. I'm taking most of my code from a tutorial in fact, hoping I'll learn what all the things do soon enough.
Anyway, so far, I have 3 .java files in my program, and it shows the exception to be at all 3 of them, plus one I never made.
Here's the full error:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:205)
at Emilia.<init>(Emilia.java:17)
at Board.<init>(Board.java:26)
at TestGame.<init>(TestGame.java:7)
at TestGame.main(TestGame.java:18)
Here's all the code:
TestGame.java
import javax.swing.JFrame;
public class TestGame extends JFrame {
public TestGame() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);
setTitle("Project Obcasus");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new TestGame();
}
}
Board.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
private Timer timer;
private Emilia emilia;
public Board() {
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
emilia = new Emilia();
timer = new Timer(5, this);
timer.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(emilia.getImage(), emilia.getX(), emilia.getY(), this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
emilia.move();
repaint();
}
private class TAdapter extends KeyAdapter {
public void keyReleased(KeyEvent e) {
emilia.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
emilia.keyPressed(e);
}
}
}
Emilia.java
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
public class Emilia {
private String emilia = "emiliasprite.png";
private int dx;
private int dy;
private int x;
private int y;
private Image image;
public Emilia() {
ImageIcon ii = new ImageIcon(this.getClass().getResource(emilia));
image = ii.getImage();
x = 40;
y = 60;
}
public void move() {
x += dx;
y += dy;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
dx = -1;
}
if (key == KeyEvent.VK_D) {
dx = 1;
}
if (key == KeyEvent.VK_W) {
dy = -1;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
dx = 0;
}
if (key == KeyEvent.VK_D) {
dx = 0;
}
if (key == KeyEvent.VK_W) {
dy = 0;
}
}
}
ImageIcon.java - Line 205
this(location, location.toExternalForm());
Again, I'm beginner level so if you guys could explain it as you would to a newcomer to java (or any programming language for that matter)
Thanks for any help. - Niblexis
path of .png file:
C:\Users\Damon\workspace\TestGame\Resources\Sprites\Player
The .png file is in the player folder. I tried to run the program via the run button in Eclipse. At least, I think it's the run button because it's what showed me the errors in the first place.
Looks like the problem is in this line:
ImageIcon ii = new ImageIcon(this.getClass().getResource(emilia));
which means most likely that you haven't placed your .png file in the right place for Java to find it.
Could you post the exact path of the .png file on disk?
More specifically: a null pointer in this line of ImageIcon.java:
this(location, location.toExternalForm());
would imply that the URL location is null (causing an exception in the method call .toExternalForm(). If you look at the docs for Class.getResource() you will see it says:
Returns: A URL object or null if no resource with this name is found
which implies that Java can't find the resource in question.
For us to help, you will need to describe your runtime environment (are you running your program from .class files or in a .jar? at the command-line or in a debugger in Eclipse / Netbeans?) so we can help you figure out why the resource isn't being found.
You're effectively calling Emilia.class.getResource("emiliasprite.png") with Emilia.java in the default (root) package, which means that you need to tell your IDE / build process to copy this file into the root of the classpath. (in the same directory that Emilia.class ends up) Otherwise, Java has no idea where to find it.
If you want to place the resource somewhere else, you need to change the path accordingly, as well as the mechanism that copies the resource from the source directory to the appropriate place on the classpath.
See this stackoverflow answer: Java in Eclipse: Where do I put files on the filesystem that I want to load using getResource? (e.g. images for an ImageIcon)
I've got a problem with the jar file that's supposed to run the game i'm trying to create.
It's basicaly a major issue with the loading of Images so that it works in the Jar aswell as Netbeans' environment.
i'm currently using
imgIcon = new ImageIcon(Core.classLoader.getResource("Images/Boss1.png"));
img = imgIcon.getImage();
this works just fine 4 all my enemies the level background and the shots my various object fire. But if I try to use it on my player class the JAR file becomes unexecutablem, even thought it still works perfectly in NetBeans. So did i screw up in the Player or somewhere else because the Images seem to load with this particular code and only if it's also in the player the jar is unusable.
Player class to be seen here(I think it's got to be a problem in here that i overlooked over and over):
package Entity;
import Shots.PlayerShot;
import bullethellreloaded.Core;
import bullethellreloaded.Screen;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player extends Entity{
public int x,y; // public used to make an easy mouse controll;
int xDirection, yDirection;
int health;
private Image img;
private ImageIcon imgIcon;
private Rectangle hitbox;
public static ArrayList shots;
public Player(){
x = 250;
y = 400;
shots = new ArrayList();
health = 5;
imgIcon = new ImageIcon(Core.classLoader.getResource("Images/spaceship (Redshrike,Stephen Challener).png"));
img = imgIcon.getImage();
}
#Override
public void move(){
x += xDirection;
y += yDirection;
// Wallcollision detection, needs to be ajusted for the size of the object.
if(x <= 0)
x = 0;
if(x >= Screen.getScreenWidth())
x = Screen.getScreenWidth();
if(y <= 0)
y = 0;
if(y >= Screen.getScreenHeight())
y = Screen.getScreenHeight();
}
public void setXDirection(int xdir){
xDirection = xdir;
}
public void setYDirection(int ydir){
yDirection = ydir;
}
#Override
public Image getImage(){
return img;
}
#Override
public ImageIcon getImageIcon(){
return imgIcon;
}
#Override
public int getX(){
return x;
}
#Override
public int getY(){
return y;
}
#Override
public Rectangle getHitbox(){
return hitbox;
}
public static ArrayList getShots(){
return shots;
}
public void fire(){
PlayerShot shot = new PlayerShot(getX(), getY()-getImageIcon().getIconHeight()/2, 0, 1, 1,Core.classLoader.getResource("Images/PlayerShot.png"));
shots.add(shot);
}
#Override
public void removeHitbox(){
hitbox = null;
}
#Override
public Rectangle setHitbox(){
int width = getImageIcon().getIconWidth();
int height = getImageIcon().getIconHeight();
hitbox = new Rectangle(getX()+width/2-5, getY()+height/2-5, 1, 1);
return hitbox;
}
public void takeDamage(int dmg){
health -= dmg;
}
public int getHealth(){
return health;
}
drawn in my screen class which is an extended JFrame in the paintComponent that's invoked by the paint(doublebuffering and stuff^^)
in the following code segment:
}else{
g.drawImage(testlevel.getImage(),0,0,this);
g.drawImage(player.getImage(),player.getX(),player.getY(),this);
// painting the Score
g.setColor(Color.white);
g.setFont(new Font("Arial",Font.BOLD,14));
g.drawString("Score: "+ Score.getScore(), getScreenWidth()-100, 50);
// painting out the content of the ArrayLists shots, enemies, enemyShots
try{
for (int i = 0; i < Player.shots.size(); i++){
PlayerShot s = (PlayerShot) Player.shots.get(i);
if (s.getDeleted() != true){
g.drawImage(s.getImage(), s.getX(), s.getY(), this);
}
}
for (int i = 0; i < Enemy.enemies.size(); i++){
Enemy e = (Enemy) Enemy.enemies.get(i);
if (e.getDestroied() != true){
g.drawImage(e.getImage(), e.getX(), e.getY(), this);
}
}
for (int i = 0; i < Enemy.enemyShots.size(); i++){
EnemyShot es = (EnemyShot) Enemy.enemyShots.get(i);
if (es.getDeleted() != true){
g.drawImage(es.getImage(), es.getX(), es.getY(), this);
}
}
}catch(Exception e){}
}
repaint();
}
I hope thats enough information, if that's not the case please let me know.
EDIT:
The question is more like is there another way that might work with my programm or what did i screw up to get this useless JAR thats not even starting.
changeing this (this path only works in netbeans the jar can't find it with this path)
imgIcon = new ImageIcon("src/Images/spaceship (Redshrike,Stephen Challener).png");
to this:
imgIcon = new ImageIcon(Core.classLoader.getResource("Images/spaceship (Redshrike,Stephen Challener).png"));
makes the JAR not runnable (not even a process in the background) whereas it worked just fine with the old path except the fact that the player didn't had an image.
You should pack the resources into the final Jar.
For Eclipse there's a plugin called FatJar that does that (in newer Eclipse versions it's embedded as the option Export>Runnable Jar File).
Usually compilers will not pack resources into the bundle.
I found it out myself, its quite the ridiculous thing.
The Image's name seems to be to long 4 the classLoader if it's used in a jar shorting down the name of the Image let's the program run ^^
AnyWays thx to the ones trying to help me and to the JAR file that reminded me of looking into the simple stuff 1.
Snake
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);
}
}
}
Im not understanding what I did wrong ive overlooked everything the best I can. Im just practicing a simple animation and I keep getting 3 null pointer exceptions.
Ive researched the best I can and apparently NullPointerExceptions in java have to do with trying to get the size of null arrays? The compiler hasn't marked any of my lists as problems so im a little confused. Any help would be greatly appreciated. All of the errors are commented out. There are three of them and they are in the Images class
Errors:
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)
Animation Class
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;
}
}
}
I included the animation class because the compiler is highlighting these three method calls as the source of the problem
a.update(timepassed);
MovieLoop();
I.run(dm);
Please Note: This is a really long comment
Let's start with Graphics g = s.getFullScreenWindow().getGraphics(); - getGraphics is NEVER a good idea, this can return null.
You should NEVER try and update any UI component from any thread other the EDT and you should NEVER draw directly to it in this manner, instead, you should be using paintComponent.
You should NEVER dispose of any Graphics context that you did not create yourself, this will prevent other components from been painted.
You should avoid overriding paint, especially of a top level container, if for no other reason, it's not double buffered (the top level container), and you will also be painting over any other child components.
Check out Performing Custom Painting for more details.
You should try using ImageIO instead of ImageIcon. ImageIO will throw exceptions if it can't read the file, where as ImageIcon simply fails silently, no very helpful.
I have just started learning java and I've been working on this code for a moving object with keyboard input. I am now trying to add in a background, but it keeps erroring with:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at game.GameLoop.run(GameLoop.java:24)
at java.lang.Thread.run(Unknown Source)
The code I have in Game.java is:
package game;
import java.applet.*;
import java.awt.*;
public class Game extends GameLoop{
public void init(){
setSize(864,480);
Thread th = new Thread(this);
th.start();
offscreen = createImage(864,480);
d = offscreen.getGraphics();
addKeyListener(this);
}
public void paint(Graphics g){
d.clearRect(0, 0, 864, 480);
d.drawImage(background, 0, 0, this);
d.drawRect(x, y, 20, 20);
g.drawImage(offscreen, 0, 0, this);
}
public void update(Graphics g){
paint(g);
}
}
And here is my GameLoop.java:
package game;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class GameLoop extends Applet implements Runnable, KeyListener{
public int x, y;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right;
public BufferedImage background;
public void run(){
x = 100;
y = 100;
try {
background = ImageIO.read(new File("background.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
while(true){
x = 100;
y = 100;
while(true){
if (left == true){
x-=4;
}
if (right == true){
x+=4;
}
if (up == true){
y-=4;
}
if (down == true){
y+=4;
}
if ( x <= 0 ){
x = 0;
}
if ( y <= 0 ){
y = 0;
}
if ( x >= 843 ){
x = 843;
}
if ( y >= 460 ){
y = 459;
}
repaint();
try{
Thread.sleep(20);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 37){
left = true;
}
if(e.getKeyCode() == 38){
up = true;
}
if(e.getKeyCode() == 39){
right = true;
}
if(e.getKeyCode() == 40){
down = true;
}
}
//#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 37){
left = false;
}
if(e.getKeyCode() == 38){
up = false;
}
if(e.getKeyCode() == 39){
right = false;
}
if(e.getKeyCode() == 40){
down = false;
}
}
//#Override
public void keyTyped(KeyEvent e) {
}
}
Sorry about the editing I can't seem to get it all in the ``, and I will also fix the messy code, but do you guys have any ideas what is causing this error, there is a file in the src dir called background.png, it is very basic and made in MS paint, if that helps.
Thanks.
There are two places a simple, sand-boxed applet can obtain images.
Where
A loose file on the same server the applet was supplied from. E.G. This might be used for a sand-boxed 'image slideshow' where the image names are supplied in applet parameters.
A Jar on the run-time class-path of the applet. Best for resources which would not typically change (barring localized images, where it becomes more complicated). E.G. This might be used for button/menu icons, or BG images.
"background.png" strongly indicates the 2nd scenario - 'part of the app. itself'.
How to find
Both types of resources should identified by URL (do not try to establish a File as it will fail when the applet is deployed).
The way to obtain an URL for the 2nd case is something along the lines of:
URL urlToBG = this.getClass().getResource("/path/to/the/background.png");
..where /path/to/the/ might simply be /resources/ or /images/. It is the path within a Jar on the classpath, where the image can be found.
How to load
Most methods that will load a File are overloaded to accept an URL. This notably applies to ImageIO.read(URL).
While the Applet class has inbuilt methods to load images, I recommend sticking with ImageIO since it provides more comprehensive feed-back on failure.
Further tips
Tip 1
Thread.sleep(20);
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See Concurrency in Swing for more details.
Tip 2
It is the third millennium, time to start using Swing instead of AWT. That would mean extending JApplet instead of Applet. Then you might shift the logic of painting into a JPanel that is double-buffered by default, and could be used in either the applet or a frame (or a window or a dialog..).
Tip 3
setSize(864,480);
The size of an applet is set in HTML, and the applet should accept whatever size it is assigned and work within that. Taking that into account, statements like:
d.clearRect(0, 0, 864, 480);
..should read more like:
d.clearRect(0, 0, getWidth(), getHeight());
#Patricia Shanahan Your comment actually helped me to solve the same problem.
I've used that code:
File here = new File(".");
try {
System.out.println(here.getCanonicalPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and from there you can figure out the correct path to use.