Images from Jar Files?

C

Charles Thomas

Here is the code I'm using to retrieve a jpeg image from my Jar Bundler
stand-alone app:

url = getClass().getResource("Images/Splash.jpeg");
if (url != null)
{
splash_image = Toolkit.getDefaultToolkit().getImage(url);
}

What I'm seeing is that splash_image is returned as being valid, but if
I subsequently try to determine its dimensions, e.g.:

do
{
image_width = splash_image.getWidth(null);
image_height = splash_image.getHeight(null);
}
while (image_width == -1 || image_height == -1);

This never returns. So in essence, the image is never actually loaded
from the jar, even though splash_image returns as non-null.

If I declare my canvas as implementing ImageObserver and substitute
"this" for "null" above, I receive an ImageObserver.ABORT followed by an
ImageObserver.ERROR flag when trying to get the width and height of the
image.

Any ideas what I'm doing wrong? The image is in the jar and is fine.

CT
 
D

dhek bhun kho

Thu said:
Here is the code I'm using to retrieve a jpeg image from my Jar Bundler
stand-alone app:

url = getClass().getResource("Images/Splash.jpeg");
if (url != null)
{
splash_image = Toolkit.getDefaultToolkit().getImage(url);
}

What I'm seeing is that splash_image is returned as being valid, but if
I subsequently try to determine its dimensions, e.g.:
do
{
image_width = splash_image.getWidth(null);
image_height = splash_image.getHeight(null);
}
while (image_width == -1 || image_height == -1);

This never returns. So in essence, the image is never actually loaded
from the jar, even though splash_image returns as non-null.

If I declare my canvas as implementing ImageObserver and substitute
"this" for "null" above, I receive an ImageObserver.ABORT followed by an
ImageObserver.ERROR flag when trying to get the width and height of the
image.

Any ideas what I'm doing wrong? The image is in the jar and is fine.

You flooded the system. By making the loop like you did, the cpu will
spend all it's time on the loop, the other thread loading the image will
not get the opportunity to finish (or quick enough anyway).

1) If you are not solely coding for the JDK 1.1, you can use a
javax.swing.ImageIcon to load the Image.

2) Otherwise you can use the java.awt.MediaTracker to check on the load
status of the images.

3) Just code the loop like you did, but use a wait() with a timeout, e.g.:

Image image = Toolkit.getDefaultToolkit().createImage(url);
while (image.getWidth(null)==-1)&&image.getHeight(null)==-1)
{
synchronized (image)
{
try
{
image.wait(10);
} catch (InterruptedException ignore)
{
}
}
}

It's a big difference because your CPU can handles lots and lots of calls
per millisecond. If you use the other loop the cpu will spend all
available time on checking whether getWidth() and getHeight() return -1.
By issuing the wait() the thread executing the code will be put into a
'waiting' state and not consume any cycles until it is notified it should
wake up.

You can ignore the exception in this case.

<code>
import java.awt.Frame;

public
class SynchronizationProblem
{
public
static
void main(String[] args)
throws Exception
{
Image image = Toolkit.getDefaultToolkit().getImage("p.png");
for (int i=0;i<1000;i++) getStatus(image);
synchronized (image) { image.wait(1000); }
getStatus(image);
}

static
void getStatus(Image image)
{
System.out.println(image.getWidth(null)+"x"+image.getHeight(null));
}
}
</code>

--
Have fun. And prosper.
Have fun. And prosper.
Have fun. And prosper.
Have fun. And prosper.
Have fun. And prosper. (is it working?)
 
T

Thomas Weidenfeller

Charles Thomas said:
Here is the code I'm using to retrieve a jpeg image from my Jar Bundler
stand-alone app:

url = getClass().getResource("Images/Splash.jpeg");
if (url != null)
{
splash_image = Toolkit.getDefaultToolkit().getImage(url);
}

What I'm seeing is that splash_image is returned as being valid, but if
I subsequently try to determine its dimensions, e.g.:

do
{
image_width = splash_image.getWidth(null);
image_height = splash_image.getHeight(null);
}
while (image_width == -1 || image_height == -1);

Use a media tracker instead of burning CPU cycles. What you are doing
is called "busy waiting" and is an absolute no-no in time-sharing
systems.

/Thomas
 
C

Charles Thomas

Update:

I've added the following code in an attempt to coerce my application
into loading the images:

if (splash_image != null)
{
mt = new MediaTracker(this);
mt.addImage(splash_image, 0);
boolean loaded = mt.waitForAll(1000);
Object[] errors = mt.getErrorsAny();
if (errors != null)
{
displayMessage("Errors were generated during splash image
loading!");
}

drawSplashImage();
}
else
throw new Exception("Splash image was not found!");


Still no luck. The images load fine when I run the application in
Codewarrior, but as soon as I make it a stand-alone application with Jar
Bundler, none of the images load.

Other than that, the application works fine.

CT
 
J

Jon A. Cruz

Charles said:
Still no luck. The images load fine when I run the application in
Codewarrior, but as soon as I make it a stand-alone application with Jar
Bundler, none of the images load.

Have you tried printing the URLs just before they are used to try to
start a load?

You might see something suprising.
 
C

Charles Thomas

It occurs to me that this may be the best way to approach this situation:

If you have a stand-alone java application that runs from a JAR file,
and you have images contained in that JAR file that your application
loads... how do YOU do it?

I'm specifically interested in Jar Bundled applications for OSX, but any
code will do.

If anyone could provide sample code, it would be very much appreciated!

CT
 
H

Harald Hein

Charles Thomas said:
It occurs to me that this may be the best way to approach this
situation:

If you have a stand-alone java application that runs from a JAR
file, and you have images contained in that JAR file that your
application loads... how do YOU do it?

new ImageIcon(getClass().getResource("path_to_image_in_the_jar")) /*
..getImage() */;

plus some exception handling.
I'm specifically interested in Jar Bundled applications for OSX,
but any code will do.

Platform doesn't matter here.
 
C

Charles Thomas

If you have a stand-alone java application that runs from a JAR
file, and you have images contained in that JAR file that your
application loads... how do YOU do it?

new ImageIcon(getClass().getResource("path_to_image_in_the_jar"))[/QUOTE]


This part is roughly what I'm doing:

url = getClass().getResource("Images/Splash.jpeg");
if (url != null)
{
splash_image = Toolkit.getDefaultToolkit().getImage(url);
}

And "splash_image" is returned as being valid and non-null.

However, when I go to do anything with the image (e.g., display it, or
determine its dimensions), nothing happens. It's like a handle to the
image is getting returned, but not the content of the image itself.

I've tried using MediaTracker to see when it's loaded:

mt = new MediaTracker(image_canvas);
mt.addImage(splash_image, 0);
boolean loaded = mt.waitForAll(10000);

But the image never seems to load.

When call g.drawImage(splash_image, 0,0, null);

subsequently nothing happens, and if I register the canvas as an image
observer, I get an ImageObserver.ABORT followed by an
ImageObserver.ERROR thrown in ImageObserver.imageUpdate().

The odd thing is that the images load just fine with the same exact code
from an OS9 stand-alone java app. But I get these weird problems in OSX.

CT
 
J

James Hicks

If it works on OS9 and not on OSX, it is most likely a JVM issue. Try
another JVM or another platform.

James

Charles Thomas said:
new ImageIcon(getClass().getResource("path_to_image_in_the_jar"))


This part is roughly what I'm doing:

url = getClass().getResource("Images/Splash.jpeg");
if (url != null)
{
splash_image = Toolkit.getDefaultToolkit().getImage(url);
}

And "splash_image" is returned as being valid and non-null.

However, when I go to do anything with the image (e.g., display it, or
determine its dimensions), nothing happens. It's like a handle to the
image is getting returned, but not the content of the image itself.

I've tried using MediaTracker to see when it's loaded:

mt = new MediaTracker(image_canvas);
mt.addImage(splash_image, 0);
boolean loaded = mt.waitForAll(10000);

But the image never seems to load.

When call g.drawImage(splash_image, 0,0, null);

subsequently nothing happens, and if I register the canvas as an image
observer, I get an ImageObserver.ABORT followed by an
ImageObserver.ERROR thrown in ImageObserver.imageUpdate().

The odd thing is that the images load just fine with the same exact code
from an OS9 stand-alone java app. But I get these weird problems in OSX.

CT[/QUOTE]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top