How to set relative path of images in report? - java

So I have a java application that displays a jasper report. There is an image I placed in the report using the iReport plugin for netbeans. Everything displays fine on my current machine but when I try to run the compiled jar on a different machine, the report won't load.
From looking at the windows console, I think it's because the path to the image is absolute, i.e. referencing a specific folder on the hard drive of the development machine. I need to make it relative to the jar file. I've placed the image into the package and have confirmed it's inside the compiled jar. But when I change the "image expression" value in iReport to "/reports/Logo.jpg" (where /reports is the package) and run the app I get
EXCEPTION: Byte data not found at : /reports/Logo.jpgnet.sf.jasperreports.engine.JRException: Byte data not found at : reports/Logo.jpg
Any ideas what to do? I am very stuck and would appreciate any help!
UPDATE: Got it. Had to create a parameter in the report and called the parameter from the image expression. Then I created a HashMap and InputStream in the Java code and placed the input stream into the hash map! So much code for so simple a thing!
Java code:
//to get images to display in report, pass their relative path as input stream and add to HashMap
//there must be one stream and one HashMap per image
InputStream imgInputStream = this.getClass().getResourceAsStream("/reports/omacLogo.jpg");
InputStream imgInputStream2 = this.getClass().getResourceAsStream("/reports/omacLogo.jpg");
parameters.put("omacLogo", imgInputStream);
parameters2.put("omacLogo", imgInputStream2);
InputStream jasper1 = this.getClass().getResourceAsStream("/reports/OmacYTDReportFinalpg1.jasper");
InputStream jasper2 = this.getClass().getResourceAsStream("/reports/OmacYTDReportFinalpg2.jasper");
JasperPrint jp1 = JasperFillManager.fillReport(jasper1, parameters,new JRBeanCollectionDataSource(ie.orderofmalta.BeanFactory.getCalcs()));
JasperPrint jp2 = JasperFillManager.fillReport(jasper2, parameters2, new JRBeanCollectionDataSource(ie.orderofmalta.BeanFactory.getCalcs()));
Hope this helps someone else! Be aware you have to create separate hash maps and input streams for each image you want to place, even if it's the same image.

I've personally had not tried this way with a jar, but i hope it helps. As you've stated the problem comes from the file path. On the iReport tool you can use relative paths and it works on the preview, but when the report generation is integrated within an application, it can only work with absolute paths.
The way i've dealt with this drawback was by getting the absolute path of the image inside the java application, and passing it as a parameter to the report. Example:
String image = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/Cards_Template/front.jpg");
NOTE: I've built a JSF app, that's why i'm getting the path from it's context. If you don't, Java's IO or NIO API does have some methods to do the same. Basically, i get an absolute path from a relative path.

Related

Creating a .jar file using ImageIcon class and JLabels in java

I am making a Cluedo boardgame in java and I cannot get my images to show up when converting it to a .jar file.I am adding the images on top of one another so I used JLabels(new ImagIcon ("..")) like so.To add the images and now the images can't be seen when I create a .jar file. Just wondering if there is any way to do without editing my code a significant amount. I have read all stackoverflow answers on this issue and none of them solves this particular problem. Here is what the board game looks like when I run it in Eclipse.
When I convert it to .jar file it no longer displays the board or any of the players.
ImageIcon(String) expects that the String value is "file" reference to the image residing on disk.
If you have externalised your resources then you need to ensure that the path you are using is correct. Remember, the "working directory" in which the Jar is executed isn't always the same as the directory that the Jar is stored in.
To this end, it's generally recommend to "embedded" the images (and other resources) within the Jar itself. This way you can simply perform a lookup for the resource regardless of where it's installed.
The means by which you embedded resources is slightly different for each IDE, but it basically requires that the images are included in the Jar and a specific location/package.
An important note, when embedded in the Jar, the resources can no longer be referenced as if they "files", because they're not, they are part of the Jar/Zip archive and need to be referenced in a different manner.
To load embedded resources you need to use Class#getResource, which returns a URL or Class#getResourceAsStream which returns a InputStream.
In most case, the first is enough. While ImageIcon does take a URL, it is generally recommended to use ImageIO.read, have a read through Reading/Loading images for more details.
The advantage of this is two fold:
It blocks until the image is read, meaning the image is fully realised when the method returns
It throws an IOException when the image can't be read, which is way more meaningful, as ImageIcon fails silently
So, all that would accumulated down to something like...
new JLabel(new ImageIcon(ImageIO.read(instanceOfMyAwesomeGameObject.getResource("/path/to/resource/ResourceName.png"))));
I think it comes from the path to your images. The image path for sources is probably not the same as for .jar

Program's executable file to image in Java

I know this might seem a bit odd, but i have this requirement and I want to know if this is possible.
I have a java swing application that I select a file (program) and this program is added to a list. When the list is completed, i execute the list of programs (this is like a start-up manager).
What I want to do is somehow, grab the file that I select and display it as image to my UI. For common files like pdf, doc, txt this is easy, I just have a generic image for each type. But lets say I want to execute regedit.exe or msconfig.exe, I want to be able to grab its icon (picture below) .
Does anyone know how this can be done?
Thanks
Take a look at FileSystemView.getSystemIcon(File).
It's a little limited (in that you will only get one size), but it's build in and doesn't require any additional libraries or JNA or JNI even...
File f = new File(...);
Icon icon = FileSystemView.getFileSystemView().getSystemIcon(f);
If you want the native icons you need JNI. Java has no default API for fetching the native icons in different sizes. Here are some startingpoints for windows & linux:
File icon overlay in java for windows
How do you get the icon, MIME type, and application associated with a file in the Linux Desktop?
If you do not need the exact native icons you can get the mimetype of the file and set a icon on your own:
Getting A File's Mime Type In Java

getClassLoader().getResource(filepath) returns a null pointer

I'm using a method to generate XML files dynamically for a research project, they get put into a loader that reads from a file path, I don't have any control over how the loader handles things (otherwise I'd pass the internal XML representation instead of monkeying with temp files), I'm using this code to save the file:
File outputs = File.createTempFile("lvlFile", ".tmp.xml");
FileWriter fw = new FileWriter(outputs);
fw.write(el.asXML());
fw.close();
// filenames is my list of file paths which gets returned and passed around
filenames.add(outputs.getAbsolutePath());
Now, I'm sure that the file in question is written to directly. If I print outputs.getAbsolutePath() and navigate there via terminal to check the files, everything is generated and written properly, so everything is correct on the filesystem. However, this code:
URL url = this.getClass().getClassLoader().getResource(_levelFile);
Where _levelFile is one of my filenames generated above, causes url to be null. The path isn't getting corrupted or anything, printing verifies that _levelFile points to the correct path. The same code has succeeded for other files. Further, the bug doesn't seem related to whether or not I use getPath(), getCanonicalPath(), or getAbsolutePath(), further setting outputs.isReadable(true) doesn't do anything.
Any ideas? Please don't offer alternatives to the Url url = structure, I don't have any control over this code*, I'm obligated to change my code so that the url is set correctly.
(*) At least without SIGNIFICANT effort rewriting a large section of the framework I'm working with, even though the current code succeeds in all other cases.
Edit:
Again, I can't use an alternative to the URL code, it's part of a loader that I can't touch. Also, the loading fails even if I set the path of the temp file to the same directory that my successfully loaded files come from.
I assume that the ClassLoader will only look for resources within the class path - which probably doesn't include /tmp. I'm not sure if it actually supports absolute path names. It might just interpret them as relative to the root of the individual class path.
How about using _levelFile.toURI().toURL() instead?
Your are creating file in file system and then trying to read it as a resource. Resource is where JVM takes its classes, i.e. the classpath. So this operation will work only if your are writing file into your classpath.
And even if this is correct be careful: if for example you are running from eclipse your process will not probably "see" the new resource until you refresh your workspace.
Now my question is: Are your really sure that you want to read files as resources. It seems that your just should create new FileInputStream(_levelFile) and read from it.
Edit
#Anonymouse is right. You are creating temporary file using 2-arg version of createTempFile(), so your file is created in your temporary directory. The chance that it is into your classpath is very low... :)
So, if you want to read it then you have to get its path or just use it when creating your input stream:
File outputs = File.createTempFile("lvlFile", ".tmp.xml");
..........................
InputStream in = new FileInputStream(ouptuts);
// now read from this stream.

Adding a path for a ImageIcon - Java

Hey So I'm pretty much awful at java and I want to add a ImageIcon now I've done this before and I even have the images to work the only issue is the program I am making is for University work and when I submit the work it will be submitted online through a .rar file.
So my issue is currently the image's have a huge direct path so i.e.
C:\Users\MY-NAME\Documents\NetBeansProjects\UNI-PROJECT\src\IMAGES\image.png
Since they will be reviewing my work on their work PC or home PC whatever the images wont work for them since it's using my home reference. How can I reference a image so they can open it where ever and the images will still work?
Thanks in advance
-SKENG-
The Java Tutorial on How to Use Icons has a small section explaining how to use Class#getResource() when the image is included with the application - look at the createImageIcon() method and the description that follows it.
You can put your images in the current folder or subfolders and then use the following path (for example):
System.getProperty("user.dir") + "images\pic1.gif"
Simply do not use absolute path, and put the images into a subdirectory where is located your sources or binaries.

Having a lot of trouble deploying a java applet

I'm new to Java. I'm simply trying to build a .jar file of my applet so I can run it from my browser. This is what my directory structure looks like:
C:\java\pacman\src
contains all of the .java class files.
C:\java\pacman\assets
contains about 4-5 images and audio files.
If I try to use the following code:
Image someFile=getCodeBase().toString() + "file.png";
The result of getCodeBase() is
file:/C:/java/pacman/bin/
However the following code fails to load:
img=new ImgHelper(getCodeBase().toString() + "assets/");
ImageIO.read(new File(img.getPath("pacman.png")));
Moving my 'assets' folder to the 'bin' folder didn't fix this either. It tries loading:
file:/C:/java/pacman/bin/assets/pacman.png
saying:
Can't read input file!
But the url it gave opens fine if I paste it into run and hit enter:
So to avoid myself a lot of headache i commented out the code in my ImgHelper class and did this:
public ImgHelper(String dir)
{
//this.imgDir=dir;
imgDir="C:\\java\\pacman\\assets\\";
}
Which works perfectly. But I want to put this on a web server, and I have no idea how/what I should do to make all the images and sounds work. Any ideas?
Thanks...
Why not put it all in a JAR file and then call Class.getResourceAsStream?
A JAR file is better as it is a single HTTP connection rather than one HTTP connection per file. It is also much more flexible to use a Stream than a File.
getResourceAsStream will work when the files are not in a JAR as well, they need to be relative to the class file.
EDIT:
Another thing, the File method won't work if the applet is on a server as it will be trying to open the file from the local machine (I think, I haven't tried it) rather then from the server. Even if it tried to create a file path to the server that won't work.
I agree with tofubeer about the JAR, but if you want to put the image on your server, see the tutorial on Applet images here. The codebase will be whatever location your applet is on the server, and you can put images relative to that on the server as well. Use a media tracker along with the Applet.getImage() method to retrive the url. From the example:
my_gif = getImage(getDocumentBase(),"imageExample.gif");
There are two possible solutions that would work:
The images could be present outside the applet JAR. The applet could then be initialized with the location of the directory where the images are present. Once you have that information you could then load images from the server. The Sun Java tutorial provides an example usage of the applet parameter to pass the image source directory.
The applet class loader could be utilized to load the images from the applet's JAR, using the getResourceAsStream() method.
PS: It would be helpful if you referred to the section in the Java tutorials to load icons for your application. The same section discusses a lot of the points brought forth by TofuBeer and John.
EDIT : The usage of the File API is not recommended because it ends up reading off the local file system. That is unacceptable for most users on the internet.

Categories

Resources