Uncaught error fetching image in exported jar - java

i have an application that loads an image to create a button with an icon in it. When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Location of images :
+Project
-Source Packages
-Tools
-start.jpg
The code used :
static final String STARTIMAGE = "/Tools/start.JPG";
public static JButton createStartButton() {
Image img = Toolkit.getDefaultToolkit().getImage(GUITools.class.getResource(STARTIMAGE));
JButton b = new JButton("",new ImageIcon(img));
b.setPreferredSize(smallButton);
b.setMaximumSize(smallButton);
b.setMinimumSize(smallButton);
return b;
Now, the weirdest thing is that in another screen, a button is created in the exact same way, and this one works just fine...
Code:
static final String PREVIOUSIMAGE = "/Tools/previous.gif";
public JButton createPreviousButton(){
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
JButton b = new JButton("Previous",new ImageIcon(img));
b.setPreferredSize(dimensionButton);
b.setMaximumSize(dimensionButton);
b.setMinimumSize(dimensionButton);
return b;
}
The only difference is that one is static, but even if make it non-static like the other one, it still won't work.
I tried everything I found on this forum and other sites, including this good topic :
How to bundle images in jar file
(The generated url at the end of the topic is just 'null')
Nothing seems to work... Please help!
Thanks!

When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.
Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
This approach above is incorrect, use this instead:
private static BufferedImage readBufferedImage (String imagePath) {
try {
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream(imagePath);
BufferedImage bimage = ImageIO.read(is);
is.close();
return bimage;
} catch (Exception e) {
return null;
}
}
And better load all images at application startup and then use them.

It seems to me that your images are inside a package so the actual link might be "package.name/Tools/start.jpg" or something else when its compiled so the image should be moved.
Instead of having it inside of a package like:
+Project
-Source Packages
-Tools
-start.jpg
Do something like this instead.
+Project Folder
-Source Packages/
-Tools/
-start.jpg

Related

java class getResource can't find icons listed in jar file

I am really stumped. I'm just an old C X11/Motif programmer trying to write a little Java program. After a week of reading the Oracle Java Documentation, as well as the
Stack Overflow answers related to getResource, I still can not figure out how to retrieve the path to the icon files in my jar file.
My icons are contained within the jar file for my application. I wish to access them using the relative position within jar file. I am assuming the best way to do this is through the getResource method.
The core part of my code for my program called Fŭd (pronounced food - like the cat spells it in the comic strip "Get Fuzzy") is as follows:
package localhost.system1;
imports not shown for brevity.
public class Fud extends JPanel
implements FocusListener, ActionListener, ItemListener
{
private static final long serialVersionUID = 1L;
static Food data = null;
static int prev = 0;
static int next = 1;
static int plus = 2;
static int minus = 3;
public static void main(String args[]) throws Exception
{
LocalDate now = LocalDate.now();
int dateDifference = 0;
// load in the existing data
data = new Food(programName);
data.loadFood(programName);
// test to see if data is up to date. Add days if not
dateDifference = Math.abs((int)ChronoUnit.DAYS.between(now, data.day[0].date));
if ( dateDifference != 0)
{
data.adjustToToday(dateDifference, programName);
}
/////////////////////////////////////////////////
// create the GUI and switch running over to it.
/////////////////////////////////////////////////
Fud fud = new Fud();
Class<? extends Fud> fudClass = fud.getClass();
String className = fudClass.getName();
System.out.println("fudClass getname returns " + className);
URL testURL = fudClass.getResource("prev.png");
System.out.println("fudClass getResource returned " + testURL);
// Create GUI and turn the control over to it
javax.swing.SwingUtilities.invokeLater
(new Runnable()
{
public void run()
{
URL[] iconURL = new URL[4];
iconURL[prev] = Fud.class.getResource("prev.png");
iconURL[next] = Fud.class.getResource("next.png");
iconURL[plus] = Fud.class.getResource("plus.png");
iconURL[minus] = Fud.class.getResource("minus.png");
createAndShowGUI(fud, iconURL);
}
}
);
} // end of main
.
.
.
Rest of methods and subroutines needed
.
.
.
}
When run, the code returns the following results:
fudClass getname returns localhost.system1.Fud
fudClass getResource returned null
This has me quite frustrated. No matter what I try (and I have tried a number of things) the result remains the same. I keep getting NULL for a response from the getResource method. When I query the jar file with jar -tf Fud.jar I get the following:
jar tf Fud.jar
META-INF/MANIFEST.MF
localhost/
localhost/system1/
localhost/system1/Day.class
localhost/system1/Food.class
localhost/system1/Fud$1.class
localhost/system1/Fud$2.class
localhost/system1/Fud$3.class
localhost/system1/Fud$4.class
localhost/system1/Fud$5.class
localhost/system1/Fud$6.class
localhost/system1/Fud$7.class
localhost/system1/Fud.class
minus.png
next.png
plus.png
prev.png
So the icons are in the Jar file. Can anyone tell me what I am doing wrong? In Eclipse, my project explorer looks like:eclipse Project Explorer
I added the Image directory to my project Java build in eclipse as follows: Eclipse Java Build
I built the program using Eclipse Version: 2021-12 (4.22.0) Build id: 20211202-1639. Furthermore, I am using Java 17.0.1 2021-10-19 LTS on Windows 11 Pro build 22000.434.
You have to add a slash in front of the resource:
Fud.class.getResource("/prev.png");
otherwise java searching in the same folder as the class is located,
so it will search in localhost/system1

Keep dimension of new image when replacing old image using docx4j

I need to add an image to my docx file. The image is a png image of a signature that is to placed behind text in the signature line of a certificate to be downloaded by the user as a docx, a pdf or jpg. The first problem I encountered is that you can only add inline image using the latest version of docx4j (v6.1.2) and creating an image Anchor is currently disabled (see BinaryPartAbstractImage.java: line 1029). That's a problem since the signature image is not inline, it supposed to appear behind the name on the signature line. Instead of inserting one myself, my workaround is to place a placeholder image:
These images are mapped as image1.png and image2.png, respectively, on /word/media directory of the docx uncompressed version. The program then replaces these with the name, position, and actual png of the signature every time a certificate is generated.
The problem is that the images are scaled the same dimension as the placeholder image, where in fact it should look like this:
How can I get to keep the image dimension of the image after replacing, or at least the aspect ratio? Here is how I replace the placeholder image with the new image:
File approveBySignatureImage = new File(...);
final String approvedByImageNodeId = "rId5";
replaceImageById(approvedByImageNodeId,
"image1.png", approveBySignatureImage);
This is the actual method where the replacing happens:
public void replaceImageById(String id, String placeholderImageName, File newImage) throws Exception {
Relationship rel = document.getMainDocumentPart().getRelationshipsPart().getRelationshipByID(id);
BinaryPartAbstractImage imagePart;
if(FilenameUtils.getExtension(placeholderImageName).toLowerCase() == ContentTypes.EXTENSION_BMP) {
imagePart = new ImageBmpPart(new PartName("/word/media/" + placeholderImageName));
}
else if([ContentTypes.EXTENSION_JPG_1, ContentTypes.EXTENSION_JPG_2].contains(FilenameUtils.getExtension(placeholderImageName).toLowerCase())) {
imagePart = new ImageJpegPart(new PartName("/word/media/" + placeholderImageName));
}
else if(FilenameUtils.getExtension(placeholderImageName).toLowerCase() == ContentTypes.EXTENSION_PNG) {
imagePart = new ImagePngPart(new PartName("/word/media/" + placeholderImageName));
}
InputStream stream = new FileInputStream(newImage);
imagePart.setBinaryData(stream);
if(FilenameUtils.getExtension(newImage.getName()).toLowerCase() == ContentTypes.EXTENSION_BMP) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_BMP));
}
else if([ContentTypes.EXTENSION_JPG_1, ContentTypes.EXTENSION_JPG_2].contains(FilenameUtils.getExtension(newImage.getName()).toLowerCase())) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_JPEG));
}
else if(FilenameUtils.getExtension(newImage.getName()).toLowerCase() == ContentTypes.EXTENSION_PNG) {
imagePart.setContentType(new ContentType(ContentTypes.IMAGE_PNG));
}
imagePart.setRelationshipType(Namespaces.IMAGE);
final String embedId = rel.getId();
rel = document.getMainDocumentPart().addTargetPart(imagePart);
rel.setId(embedId);
}
You'll need to set the dimensions (or possibly just remove what you have?) on your placeholder image.
For help in doing that:-
docx4j inspects the image to work that out at https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L512 using org.apache.xmlgraphics ImageInfo.
See also CxCy:https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L1164
https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/BinaryPartAbstractImage.java#L815 shows scaling to maintain aspect ratio.

Substitute ImageIcon with ImageIO to load images

I'm making a java game using Eclipse. When I export to a runnable jar and try to run the game on different computer the images aren't visible. After checking the web and stack overflow for similar problems I think it has something to do with my using ImageIcon instead of ImageIO. However, I'm not sure how to change my code so that I'm uploading the images with ImageIO instead of ImageIcon.
Here is the method that uses ImageIcon to load the images
void loadImage() {
ImageIcon earth_image_icon = new ImageIcon("earth2.png");
earth = earth_image_icon.getImage();
ImageIcon sun_image_icon = new ImageIcon("sun2.png");
sun = sun_image_icon.getImage();
ImageIcon asteroid_image_icon = new ImageIcon("asteroid.png");
asteroid = asteroid_image_icon.getImage();
ImageIcon bg_image_icon = new ImageIcon("bg_pr.png");
background = bg_image_icon.getImage();
ImageIcon shipA_image_icon = new ImageIcon("ship_alpha.png");
ship_on_asteroid = shipA_image_icon.getImage();
ImageIcon ship_image_icon = new ImageIcon("ship_beta.png");
ship_no_thrust = ship_image_icon.getImage();
ImageIcon shipL_image_icon = new ImageIcon("ship_betaL.png");
ship_left_thrust = shipL_image_icon.getImage();
ImageIcon shipR_image_icon = new ImageIcon("ship_betaR.png");
ship_right_thrust = shipR_image_icon.getImage();
ImageIcon shipU_image_icon = new ImageIcon("ship_betaU.png");
ship_up_thrust = shipU_image_icon.getImage();
ImageIcon shipD_image_icon = new ImageIcon("ship_betaD.png");
ship_down_thrust = shipD_image_icon.getImage();
ImageIcon leftarrow_image_icon = new ImageIcon("leftarrow.png");
leftarrow = leftarrow_image_icon.getImage();
ImageIcon rightarrow_image_icon = new ImageIcon("rightarrow.png");
rightarrow = rightarrow_image_icon.getImage();
ImageIcon downarrow_image_icon = new ImageIcon("downarrow.png");
downarrow = downarrow_image_icon.getImage();
ImageIcon uparrow_image_icon = new ImageIcon("uparrow.png");
uparrow = uparrow_image_icon.getImage();
}
And here is one of the methods that draws the image onto the JPanel as an example
void drawEarth(Graphics g) {
g.drawImage(earth, earth_x_coordinate, earth_y_coordinate, this);
Toolkit.getDefaultToolkit().sync();
}
How do I convert to using ImageIO? I've checked out the Oracle documentation but I'm getting lost trying to sort it out and I'm very new to programming and java at that.
Update It's been suggested that this might be the solution my particular problem but I tried the answers given on this post and they didn't work for my case.
You will need to include the image resources in your compiled jar. An easy way of doing this if you are using an IDE like eclipse is to create a res or img folder and put your files in there. (Use the methods given here.)
In that case, you probably won't need to use ImageIO. However, if you still want to use ImageIO (which is recommended because of its wider support for formats and better exception handling, as mentioned in the comments), you can do the following:
Icon foo = new ImageIcon(ImageIO.read(getClass().getResource("foo.png")))
I created a new project in eclipse and copied the class files into the new projects src folder. I then made a resource folder, added it to the build path, created an images package in that resource folder and copied the images into that images package. For some reason this all worked. Thanks everyone for your help

"mimetype: application" display on a picture instead of "mimetype: image" after a ImageIO.write

When I simply create a new image from another like this:
public static void scaleByTwoRight(String src, String dest)
throws IOException {
BufferedImage bsrc = ImageIO.read(new File(src));
int width = bsrc.getWidth()/2;
int height = bsrc.getHeight();
BufferedImage bdest = bsrc.getSubimage(width, 0, width, height);
ImageIO.write(bdest,"PNG",new File(dest));
}
Source file (src) = C:...\Manga\Shonan Juna_ Gumi Tome 11\Shonan Junaï Gumi Tome 11 - 091B.png
Destination file (dest) = C:...\Manga\Shonan Junaï Gumi Tome 11 - 091B_A.png
Example of generated file: https://docs.google.com/file/d/0B1vKCZzB5hxqYzNsUWF5RHA2Wm8/edit?usp=sharing
Problem: The new image has mimetype: application instead of mimetype: image
How I arrive to this conclusion: I'm using a function to test if the file is an image or not:
public static boolean isImage(String src)
throws IOException {
File f = new File(src);
String mimetype= new MimetypesFileTypeMap().getContentType(f);
String type = mimetype.split("/")[0];
if(type.equals("image")){
return true;
}else{
System.out.println("mimetype: "+type);
return false;
}
}
It has not a huge impact if the Mime-type is not correct but I prefer to have that working properly..
Thanks for your help!
Note:
I'm running under Windows 7 / 32b
JVM 1.7 / Eclipse Helios
Your code is working fine in my machine.
I have windows XP,32 bit,
Tried with jpeg image and it is returning the mimetype as image/jpeg only.
Hope you are not trying to execute both the functions simultaneously.
Also the destination file name should contain proper extension like .jpeg or. png etc...

Changing JRadioButton Icon on Windows 7

I created a method which changes the icon of all jradiobuttons from a buttongroup:
public void setRadioButtonIcons(final ButtonGroup gruppe){
Enumeration<AbstractButton> gruppeEnum = gruppe.getElements();
while (gruppeEnum.hasMoreElements()){
AbstractButton radio = gruppeEnum.nextElement();
Icon unselIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox0.jpg").getPath());
Icon selIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox1.jpg").getPath());
radio.setIcon(unselIcon);
radio.setSelectedIcon(selIcon);
}
}
This works fine under Ubuntu with Java 1.6.0_16.
When I use the methode under windows 7 with java 1.6.0_18, the icons do not apear. They are simply missing. The programm does not throw a Nullpointer... it finds the icons, but does not display them. Any ideas? It seems somewhat hard to believe that I can not use such a simple functionality under windows.
I tried it with gif and jpg. I also put the images inside the jar and tried to load them from the filesystem -> same result.
Edit: In this configuration, the files are loaded from the jar.
Icon unselIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox0.jpg").getPath());
Icon selIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox1.jpg").getPath());
You shouldn't be calling getPath() there, should just be:
Icon unselIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox0.jpg"));
Icon selIcon = new ImageIcon( Thread.currentThread().getContextClassLoader().getResource("checkbox1.jpg"));
It won't be able to access a resource in a jar by path and an ImageIcon can load an image using a URL just fine.
If you still are not seeing your icons then it may be that the L&F you are using does not use those icons and instead uses its own. Perhaps try testing the code with a different L&F.
Try removing the calls to getPath(), like this:
public void setRadioButtonIcons(final ButtonGroup gruppe) {
Enumeration<AbstractButton> gruppeEnum = gruppe.getElements();
while (gruppeEnum.hasMoreElements()){
AbstractButton radio = gruppeEnum.nextElement();
Icon unselIcon = new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("checkbox0.jpg"));
Icon selIcon = new ImageIcon(Thread.currentThread().getContextClassLoader().getResource("checkbox1.jpg"));
radio.setIcon(unselIcon);
radio.setSelectedIcon(selIcon);
}
}
The problem is that URL.getPath() gives you a string URL, which isn't necessarily a valid string filename of the sort that the ImageIcon string constructor expects. Fortunately, ImageIcon has another constructor that understands URL objects, and so there's no need to call getPath().

Categories

Resources