0

The issue I'm having is I cannot see any of the pictures I'm referencing with the ImageIO class on my Applet Viewer in JAVA. I was following a tutorial online and have yet to hear back from the author - there were similar questions on his page he didn't answer, so I'm assuming he's trying to figure it out himself.

Here's what I have so far.

import java.applet.Applet;
import java.awt.Graphics;


public class SuperheroGame extends SuperHeroGameLoop{


/**
 * 
 */
private static final long serialVersionUID = 1L;

public void init () {
    setSize(320,240);
    Thread th = new Thread(this) ;
    th.start();
    offscreen = createImage(320,240);
    d = offscreen.getGraphics();
    addKeyListener(this);
}

public void paint (Graphics g) {
    d.clearRect(0, 0, 320, 240);
    d.drawImage(background, 0, 0, this);
    d.drawImage(w2, x,y, this);
    //d.drawImage(foreground, 0, 0, this);
    //g.drawImage(offscreen, 0, 0, this);

}

public void update(Graphics g) {
    paint(g);
}

}

And below is my Tester class with the bulk of the functions nested in the code.

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;


public class SuperHeroGameLoop extends Applet implements Runnable, KeyListener {

/**
 * 
 */
private static final long serialVersionUID = 1L;
public int x,y;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right;
public BufferedImage background, foreground, w1, w2, w3, w4;

public void run() {

    x = 100;
    y = 100;
    try {
        //background = ImageIO.read(new File ("background.png"));
        //foreground = ImageIO.read(new File ("foreground.png"));
        w1 = ImageIO.read(new File("red copy.png"));
        w2 = ImageIO.read(new File("red copy.png"));
        w3 = ImageIO.read(new File("red copy.png"));
        w4 = ImageIO.read(new File("red copy.png"));
    } catch (IOException e1) {

        e1.printStackTrace();
    }
    while(true) {
    if (left == true) {
        x-=2;
    }
    if (right == true) {
        x+=2;
    }
    if (up == true) {
        y-=2;
    }
    if (down == true) {
        y+=2;
    }

    repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == 37) {
        left = true;
    }

    if (e.getKeyCode() == 39) {
        right = true;
    }

    if (e.getKeyCode() == 38) {
        up = true;
    }

    if (e.getKeyCode() == 40) {
        down = true;
    }
}
public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == 37) {
        left = false;
    }

    if (e.getKeyCode() == 39) {
        right = false;
    }

    if (e.getKeyCode() == 38) {
        up = false;
    }

    if (e.getKeyCode() == 40) {
        down = false;
    }
}
public void keyTyped(KeyEvent e) {

}

}

Any help or feedback will be appreciated.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 3
    See [*What Applets Can and Cannot Do*](http://docs.oracle.com/javase/tutorial/deployment/applet/security.html). – trashgod Jan 01 '13 at 01:07
  • 1
    I think this is because File loading in applets doesn't work like this. See [*Finding and Loading Data Files*](http://docs.oracle.com/javase/tutorial/deployment/applet/data.html) – Philip Whitehouse Jan 01 '13 at 01:07
  • I'd like to add that my image files are only on my computer and not being read remotely from a URL or anything on the net. the images I have are in the SRC directory of the folder I'm using to call them. – user1801053 Jan 01 '13 at 01:21

2 Answers2

4

..my image files are only on my computer and not being read remotely from a URL or anything on the net.

How is that supposed to work when the applet is deployed to the audience on the World Wide Web?

When the applet loads from your site onto my PC, there is no longer any option for it to be loading images off your PC (unless your PC is the server). Images for an applet must come from an URL rather than a File, and barring a trusted applet they must come from URLs at the same site as the applet.

ImageIO.read(..) is overloaded for streams, files or URLs, so still can be used to load the image.

To form the URL for an applet there are at least 3 ways. If the image is:

  • A loose resource on the same server. Form the URL relative to the document base or code base.
  • In a Jar mentioned in the archive attribute (is on the run-time class-path). Use:
URL urlToImage = this.getClass().getResource("/path/to/image.png");

Further tips.

  1. It is not entirely clear, but seems SuperheroGame is an instance of Applet. This millennium use Swing, so that should extend JApplet.
  2. But then we come to the 2nd problem, wherein SuperheroGame actually extends SuperHeroGameLoop (shudder). At this point we come to the realization that SuperHeroGameLoop should have been coded in a Panel or JPanel rather than extending either Applet or JApplet. The general principle is 'do custom painting in a container that can itself be added to an applet, or a frame, or a dialog or window, or a constraint in a layout, or a tab or an internal frame..'.
  3. setSize(320,240); This is inadvisable in most GUIs, but more so in an applet. The size of an applet is set in the HTML, and that size should be honored.
  4. Thread th = new Thread(this) ; To do animation, use a Swing Timer. The following message was written for Swing, but applies equally to AWT AFAIU (after all, the EDT is itself a thread started, used and controlled by the AWT).
    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.
  5. addKeyListener(this);
    1. For more reliable focus make the GUI free floating. To do that, put the game in a frame (JFrame) and launch it from a link using Java Web Start.
    2. For a Swing based GUI, look to Key Bindings.

That is 5+ tips, and we've just reached the end of the init. That suggests it would be more optimal to learn to write code from different sources than what led to that code.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • @ Andrew Thompson , thank you for the very informative reply. I was actually following the tutorial online to a T and had no plans of deploying this on the net anytime soon. I completely understand what you are saying and already knew that, it does make a whole lot of a sense to get into the habit of doing it the way you've told me, but again for the sake of the video tutorial I was watching - where everything I've implemented DOES seem to work on the hosts computer, but I'm guessing they left stuff out on the contrary - I didn't deviate. – user1801053 Jan 01 '13 at 15:27
3

You're using an applet - which is designed to run in a browser and constrained by a security manager. The security manager is likely to prevent you from doing local disk i/o.

Trashgod and Philip point you to useful articles on this subject.

However, if we take a different tack ...

An Applet is a Component which can be added to a JFrame's content pane. You can turn your applet into a stand-alone application (which won't have a restrictive security manager) by doing something like this following ...

Add a new class:

public class SwingApp
{
  public static void main(String[] args)
  {
    final JFrame frame = new JFrame("Swing App");

    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        final SuperHeroGameLoop loop = new SuperHeroGameLoop();

        frame.getContentPane().add(loop);
        frame.setSize(320, 240);

        loop.init();

        frame.setVisible(true);
      }
    });
  }
}

(I did, however, just type this from memory without running it through a compiler - so I apologise for any compilation errors) ...

Compile and run this as a stand-alone application.

Another alternative is to ditch the applet approach altogether and write it as a desktop Swing application using JComponents ...

Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
  • Hi, Greg. Thanks for the reply. I added your class, but to no avail. I'm running into the same issue with the images not appearing. I chose to Run As a Java Application and I get the same results. I guess it's a problem with the images themselves? They're in the right folder tho. – user1801053 Jan 01 '13 at 02:06
  • @user1801053: I take it you're not getting an i/o exception? – Greg Kopff Jan 01 '13 at 02:26
  • @user1801053: ah - ok, it could be a threading issue - I'll try to take a closer look a bit later today ... Question: do you _really_ want to make it use the applet - or can be scrub that? – Greg Kopff Jan 01 '13 at 02:33
  • *"ditch the applet approach and write it using Swing components."* Ever heard of `JApplet`? ;) – Andrew Thompson Jan 01 '13 at 03:14
  • @AndrewThompson: yeah, but that wasn't my point - my point was about _not_ using an applet (whether that be `Applet` or `JApplet` derived). :-) *Edited. – Greg Kopff Jan 01 '13 at 04:11
  • @GregKopff , I'm new to the whole "gaming" thing in Java. It's actually my first time ever creating a game, and what I have there is from what "I" got watching a tutorial. So I really have no clue what's best to use when it comes to making a simple 2D game in java, but I take it you do. ANY advice or push in the right direction would be greatly appreciated, as is you looking further into helping me out with this. Thanks again, Greg! – user1801053 Jan 01 '13 at 15:11
  • Take a look at: [Killer Game Programming In Java](http://www.amazon.com/Killer-Game-Programming-Andrew-Davison/dp/0596007302) and [this](http://stackoverflow.com/a/10378724/1212960). – Greg Kopff Jan 01 '13 at 22:02