Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (516)
Games in Android Showcase (122)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Applet Image Loading  (Read 3249 times)
0 Members and 1 Guest are viewing this topic.
Offline Dreamcatchermatt

Junior Duke





« Posted 2010-07-21 16:25:58 »

What is the best way to load images and XML data to a java applet?

What I have at the moment is an Slick2D Game applet. I have a content loader from an application project that takes an XML file containing links to the games separate image/sound/particles, etc that need to be loaded.

Finally I have a directory called 'art' that contains the actual image files.

On my server I have kept the same directory structure as the application version:

MyApplet
    - data
        - resources.xml
    - art
        - image1.png
        - image2.png
        - image3.png
        - image4.png

When running the applet, I get the following error:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
Exception in thread "Thread-14" java.lang.ExceptionInInitializerError
   at DecoGame_NixieClock.NixieClockGame.init(NixieClockGame.java:43)
   at org.newdawn.slick.AppletGameContainer$Container.initApplet(AppletGameContainer.java:272)
   at org.newdawn.slick.AppletGameContainer$ContainerPanel.initGL(AppletGameContainer.java:229)
   at org.newdawn.slick.AppletGameContainer$ContainerPanel.start(AppletGameContainer.java:216)
   at org.newdawn.slick.AppletGameContainer$1.run(AppletGameContainer.java:92)
Caused by: java.security.AccessControlException: access denied (java.io.FilePermission data\resources.xml read)
   at java.security.AccessControlContext.checkPermission(Unknown Source)
   at java.security.AccessController.checkPermission(Unknown Source)
   at java.lang.SecurityManager.checkPermission(Unknown Source)
   at java.lang.SecurityManager.checkRead(Unknown Source)
   at java.io.FileInputStream.<init>(Unknown Source)
   at Content.ResourceManager.<init>(ResourceManager.java:50)
   at Content.ResourceManager.<clinit>(ResourceManager.java:33)
   ... 5 more


If I'm right, this is because applets are not allowed to access the local file-system.
Is there a method for loading data to an applet from the server?

This is the layout of the XML file I use to store my content links:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<!-- GAMEPLAY -->

  <!-- GUI -->
  <resource type="image" id="IMAGE_1">art\image1.png</resource>
  <resource type="image" id="IMAGE_2">art\image2.png</resource>
  <resource type="image" id="IMAGE_3">art\image3.png</resource>

</resources>


Would it just be a matter of changing these links to say 'www.mydomain.com/applet/art/image1.png' or is there a better way?
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #1 - Posted 2010-07-21 17:19:59 »

Instead of using java.io.File stuff to load your resources, you should be using java.lang.ClassLoader's getResource methods.
These will search the classpath and return a stream from which you can load your xml file and images. This works for applications and applets alike, you just need to make sure that your resource files are on the classpath: for applications you add the resource directory to the classpath, for applets you package the resources into a jar file and include it just like a code jar.
Offline Dreamcatchermatt

Junior Duke





« Reply #2 - Posted 2010-07-21 17:25:56 »

Ok, I'll give that a go.

Is it possible in NetBeans to include folders and images into the class path, or only java class files?
Just now I'm adding them in after build with 7-zip ... which I guess is a bit silly.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #3 - Posted 2010-07-22 10:04:38 »

You can also use Java.io.File if you pass in a URL instead of a local file, then you can pass in your server's URL. This, however, is quite slow and not something I would do unless you want to be swapping just this image out frequently or something. Instead use the classpath.

See my work:
OTC Software
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #4 - Posted 2010-07-22 10:20:35 »

Not sure how it works in Netbeans, but in Eclipse there's a "Classpath" tab in the run configuration dialog that lets you add directories. From the command line you just use the -cp option.
Offline Dreamcatchermatt

Junior Duke





« Reply #5 - Posted 2010-07-22 15:40:16 »

Hi,

I've had a go at modifying my resource manager class to use ClassLoader (rather than fileIo). I'm having a lot of trouble understanding how this is meant to work. Does anyone know of any basic tutorials that cover loading files this way? Everything I've been able to find seems to only work with actual classes.

Here's the code I have tried for reference:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
public class ResourceManager {

   private static ResourceManager _instance = new ResourceManager();
        private static ClassLoader classLoader;

   private Map<String, Sound> soundMap;
   private Map<String, Image> imageMap;
   private Map<String, ResourceAnimationData> animationMap;
   private Map<String, String> textMap;
        private Map<String, ParticleSystem> particleMap;

   private ResourceManager() {
      soundMap = new HashMap<String, Sound>();
      imageMap = new HashMap<String, Image>();
      animationMap = new HashMap<String, ResourceAnimationData>();
      textMap = new HashMap<String, String>();
                particleMap = new HashMap<String, ParticleSystem>();

                classLoader = ClassLoader.getSystemClassLoader();

                try
                {
                    /* NTS:
                     * Modifying this class to load resources from the classPath
                     * so that it can be used within applets.
                     * 22 July 2010, Matt
                     */

                    URL url = classLoader.getResource("assets/data/resources");
                    if(url != null)
                    {
                        File f = new File(url.getPath());
                        this.loadResources(new FileInputStream(f));
                    }
                    else
                    {
                        throw new NullPointerException();
                    }
                }
                catch(SlickException e)
                {
                    e.printStackTrace();
                }
                catch(FileNotFoundException e)
                {
                    e.printStackTrace();
                }
   }

   public final static ResourceManager getInstance(){
      return _instance;
   }

   public void loadResources(InputStream is) throws SlickException {
      loadResources(is, false);
   }

   public void loadResources(InputStream is, boolean deferred) throws SlickException
        {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = null;
            try
            {
                docBuilder = docBuilderFactory.newDocumentBuilder();
            }
            catch (ParserConfigurationException e)
            {
                throw new SlickException("Could not load resources", e);
            }

            Document doc = null;

            try
            {
                doc = docBuilder.parse (is);
            }
            catch(SAXException e)
            {
                throw new SlickException("Could not load resources", e);
            }
            catch (IOException e)
            {
                throw new SlickException("Could not load resources", e);
            }

      // normalize text representation
            doc.getDocumentElement ().normalize ();

            NodeList listResources = doc.getElementsByTagName("resource");

            int totalResources = listResources.getLength();

            if(deferred)
            {
           LoadingList.setDeferredLoading(true);
            }


            for(int resourceIdx = 0; resourceIdx < totalResources; resourceIdx++)
            {

           Node resourceNode = listResources.item(resourceIdx);

           if(resourceNode.getNodeType() == Node.ELEMENT_NODE){
                    Element resourceElement = (Element)resourceNode;

                    String type = resourceElement.getAttribute("type");

                    if(type.equals("image")){
                            addElementAsImage(resourceElement);
                    }else if(type.equals("sound")){
                            //addElementAsSound(resourceElement);
                    }else if(type.equals("text")){
                            //addElementAsText(resourceElement);
                    }else if(type.equals("font")){

                    }else if(type.equals("animation")){
                           // addElementAsAnimation(resourceElement);
                    }
                    else if(type.equals("particleSystem")){
                            addElementAsParticleSystem(resourceElement);
                    }
           }
            }
   }

       ... loads of methods for getting the files from the XML nodes ...


Where I'm having trouble is here:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
                     /* NTS:
                     * Modifying this class to load resources from the classPath
                     * so that it can be used within applets.
                     * 22 July 2010, Matt
                     */

                    URL url = classLoader.getResource("assets/data/resources.xml");
                    if(url != null)
                    {
                        File f = new File(url.getPath());
                        this.loadResources(new FileInputStream(f));
                    }
                    else
                    {
                        throw new NullPointerException();
                    }


Which always throws the nullPopinterException with 'url' always returning null.

This is all rater new to me, so thanks for being patient Smiley
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #6 - Posted 2010-07-23 09:13:36 »

A couple of things to try:
  • Use the context classloader: Thread.currentThread().getContextClassLoader().
  • Ensure that your paths are correct. Take a look into your resource jar with a zip tool and verify that "assets/data/resources.xml" actually exists.
  • Unrelated to the issue you're having right now, but there's no need to use the File and FileInputStream classes - the classloader can return a stream to load from directly with getResourceAsStream()

Also: there's no need to manually throw a NullPointerException - it'll be done for you when you call .getPath() on the null reference.
Offline Dreamcatchermatt

Junior Duke





« Reply #7 - Posted 2010-07-23 15:31:13 »

ok, i'll have a read-up on those.

Would it be better to continue using my hash-tables to store my resources in memory, or to change them to using something like HashTable<String name, String path> and using getResource(path) each time I want to get a resource?

(I assume this would then either load the file from the classpath, or try findLoadedClass() first to get it from the cache, right?)
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #8 - Posted 2010-07-23 16:02:40 »

Definitely load the resources once and keep them around, as you have been doing.
Offline Dreamcatchermatt

Junior Duke





« Reply #9 - Posted 2010-07-23 18:56:21 »

Thanks ryanm!

Loading images this way seems to be working now, and I've set-up my game template project to include an assets.art, assets.data, assets.art.sound and assets.art.music class-path, and also a template resources.xml document to load in some default images.

I've used this to move my template project over to using Slick's StateBasedGame class and added an Intro state that show's my (WIP) blog-site logo with a nice fade-in fade-out effect  Smiley

I actually feel like I've got something done today.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Dreamcatchermatt

Junior Duke





« Reply #10 - Posted 2010-07-24 10:46:51 »

Code:
public Image loadResource(String id, String path) {
       
        try
        {
            if(path == null || path.length() == 0)
                throw new SlickException("Image resource [" + id + "] has invalid path");

            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            Image image = null;

            /* NTS:
             * Modifying this class to load resources from the classPath
             * so that it can be used within applets.
             * 22 July 2010, Matt
             */
            InputStream str = classLoader.getResourceAsStream(path);

            image = new Image(str, id, false);

            System.out.println("Loaded Image "+ id + ": " + path);
           
            ResourceManager.getInstance().PutObject(id, image); // store the loaded image in a hashTable for later use.
           
            return image;
        }

        catch( ... ) { ... }

}


Here is the stack trace i'm getting;

Code:
Loaded Image IMAGE_GAMEWORKS_LOGO: assets/art/rbgwLogo.png
Exception in thread "main" java.lang.ExceptionInInitializerError
        at slickgametemplate.RBGWIntroState.init(RBGWIntroState.java:56)
        at slickgametemplate.SlickGame.initStatesList(SlickGame.java:39)
        at org.newdawn.slick.state.StateBasedGame.init(StateBasedGame.java:164)
        at org.newdawn.slick.AppGameContainer.setup(AppGameContainer.java:390)
        at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:314)
        at slickgametemplate.Main.main(Main.java:33)
Caused by: java.lang.NullPointerException
        at content.loaders.ImageLoader.loadResource(ImageLoader.java:47)
        at content.ResourceManager.loadImage(ResourceManager.java:211)
        at content.ResourceManager.loadImage(ResourceManager.java:206)
        at content.ResourceManager.loadResources(ResourceManager.java:181)
        at content.ResourceManager.loadResources(ResourceManager.java:126)
        at content.ResourceManager.<init>(ResourceManager.java:80)
        at content.ResourceManager.<clinit>(ResourceManager.java:46)
        ... 6 more
Java Result: 1


I've run a few breakpoints, and it seems that the Image being created from the InputStream has zero dimensions (the actual .png is 640*480)

I've checked everything I can think of, but got nothing. Any ideas what is happening here?

Thanks,
Matt
Offline zoto

Senior Duke


Medals: 4



« Reply #11 - Posted 2010-07-24 11:01:52 »

I made a simple image loader class like you described, it could easily be modified to do other file types. http://www.java-gaming.org/topics/unsigned-web-start-image-loader/20634/view.html hope it helps.
Offline Dreamcatchermatt

Junior Duke





« Reply #12 - Posted 2010-07-24 16:16:15 »

Ahh, that looks cool Zoto, I'll give it a go.

The method I've been using is to load everything into a HashTable at start up, instead of loading on demand, which is what your code does. Do you know if there is any advantage to either solution?

Offline zoto

Senior Duke


Medals: 4



« Reply #13 - Posted 2010-07-25 08:34:51 »

If you load the same image twice, it will load it from disk the first time, every other time the preloaded image is returned.

To pre-load at the beginning just call the function and don't worry about the return value, when you load it later it will already be in the hash map.

Remember I posted that code to ask a specific question so it's stripped down, if you use it you will probably want to add some public wrapper functions to at least remove images and clear the hash map. 

The trade offs with pre-loading is just the normal ram usage v/s access speed.
Reading from the hard drive will take a relatively long time but ram is a limited resource, you just need to find the right balance for the game your making.

I believe applets have 64MB of ram by default and can only be changed client side, but web start can be set in the jnlp file.
Offline Dreamcatchermatt

Junior Duke





« Reply #14 - Posted 2010-07-25 13:31:16 »

I believe applets have 64MB of ram by default and can only be changed client side...

I did not know that. Useful to know though, I think you may just have saved me days of 'why, WHY is it not working!?' time in a few months Smiley
Offline kappa
« League of Dukes »

JGO Kernel


Medals: 78
Projects: 15


★★★★★


« Reply #15 - Posted 2010-07-25 13:39:10 »

I believe applets have 64MB of ram by default and can only be changed client side, but web start can be set in the jnlp file.

you can allocate the memory for an applet by using the following parameter in your applet tag
1  
<param name="java_arguments" value="-Xmx128m">

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (31 views)
2014-10-27 03:28:38

TehJavaDev (26 views)
2014-10-27 03:27:51

DarkCart (40 views)
2014-10-26 19:37:11

Luminem (21 views)
2014-10-26 10:17:50

Luminem (26 views)
2014-10-26 10:14:04

theagentd (32 views)
2014-10-25 15:46:29

Longarmx (61 views)
2014-10-17 03:59:02

Norakomi (57 views)
2014-10-16 15:22:06

Norakomi (46 views)
2014-10-16 15:20:20

lcass (43 views)
2014-10-15 16:18:58
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!