I'm having massive issues packaging my java program which contains images into a jar for conversion into and executable file. The images have been used in the background of the program and buttons. Please see the diagram below which shows the program I desire to convert to a jar.
IMAGE
As you see above the program runs OK. I created the same program with no custom background and custom buttons containing no images and I successfully packaged it into a jar and subsequently into an .exe file.
With regards to drawing my background I'm doing this as follows:
public void paintComponent(Graphics g) {
Image img = new ImageIcon("imgs/Bgnd1.jpg").getImage();
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
g.drawImage(img, 0, 0, null);
}
With regards to creating my 4 custom buttons with images, I'm doing the following:
// Prepare rollover images
ImageIcon F1 = new ImageIcon("imgs/btn_f1_not_selected.jpg");
ImageIcon F1rollOver = new ImageIcon("imgs/btn_f1_selected.jpg");
// Create F1 button
final JButton btnF1 = new JButton(F1);
//btnF1.setOpaque(false);
btnF1.setContentAreaFilled(false);
btnF1.setBorder(null);
btnF1.setBorderPainted(false);
btnF1.setFocusPainted(false);
btnF1.setRolloverIcon(F1rollOver);
I attempted placing the images in the bin folder and for the creation of the background I altered the above method with regards to the declaration/fetching of the image.
public void paintComponent(Graphics g) {
String path = "Bgnd11.jpg";
java.net.URL imgURL = getClass().getResource(path);
Image img = new ImageIcon(imgURL).getImage();
Dimension size = new Dimension(img.getWidth(observer), img.getHeight(observer));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
g.drawImage(img, 0, 0, null);
}
I also attempted fetching the images needed for the creation of my buttons as indicated below and then passing them to my button but this did not work.
String path = "Bgnd11.jpg";
java.net.URL imgURL = getClass().getResource(path);
Image img = new ImageIcon(imgURL).getImage();
How to locate & load the images?
In your first attempt, you're loading images from the file system, in the current directory, which is the directory from which the java of javaw command is started. That's what prevents you from bundling the images with your applications. Obviously, the end user of your app won't have the images in his current directory, and his current directory will change depending on how he launches the application.
You should instead have the images packaged inside the jar file, and thus be present in the classpath, and thus load them using the ClassLoader as you're doing in your second attempt.
Let's say they're in the folder /resources/images of the jar, which thus corresponds to the package resources.images.
Using getClass().getResource("Bgnd11.jpg"), as the javadoc indicates, tries to find Bgnd11.jpg in the same package as the class returned by getClass(). So, it would work in our example if the class was in the package resources.images. If it's not, you should use the absolute path of the resource:
URL imgURL = getClass().getResource("/resources/images/Bgnd11.jpg");
Also, don't mess with the bin folder. This is the destination folder of Eclipse, and doing a clean build will remove everything from this directory. Just add the images to the appropriate package in the source directory, and Eclipse will automatically copy them to the destination directory when building the project.
Related
So I am trying to add an image to a JLabel object which is added to a JPanel called "topPanel" which is part of a JFrame called
"primaryWindow". I have already declared the "topPanel" and "primaryWindow". I found on other forms that you have to create a separate source folder and add the image file in that folder in order to access it and I did so.
However, when I execute the following, the image does not appear to be on the Label. I know that it has nothing to do with adding the JLabel to the panel properly because when I enter a String into the JLabel constructor, the String appears on the panel. An image however does not appear. Am I properly adding the image? I am using a mac if this helps.
private JLabel image = new JLabel();
image.setIcon(new ImageIcon("Check.png"));
topPanel.add(image);
primaryWindow.add(topPanel, BorderLayout.NORTH);
You can also use BufferedImage
BufferedImage myPicture = ImageIO.read(new File("C:\\xx\\xxx\\Check.png.jpg"));
Image scaled = myPicture.getScaledInstance(100,70,Image.SCALE_SMOOTH);
image = new JLabel(new ImageIcon(scaled));
topPanel.add(image);
primaryWindow.add(topPanel, BorderLayout.NORTH);
Note that "C:\\xx\\xxx\\Check.png.jpg" is the path where you save Check.png.
Hope this helped.
The ImageIcon that you passed into the setIcon method of the JLabel could be null. Have you tried to check if it is null before calling setIcon? If you create a "res" resource folder in the root directory of your project, you could try the following:
image.setIcon(new ImageIcon(ImageIO.read(new File("res/Check.png"))));
Additionally, if you are using Eclipse, you should try and refresh the project directory by right clicking and pressing refresh; sometimes Eclipse doesn't register files added.
Lastly, try setting the background of the JPanel to a certain color to see if it is displaying it and make sure its width and height are not 0 (it is possible that the layout you are using changed its size).
I want to know what is the problem in my code that caused .JAR file to be broken? when I double click on jar file it doesn't open but it was fine before adding background image to JFrame.
I created a class called Cube to draw cube and I want to set background image to JFrame, so I added field in Cube class
private BufferedImage bg;
bg initialization in the class constructor
publice Cube() {
bg = ImageIO.read(new File("bg_image.jpg"));
}
this piece of code used to set the background
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, this);
}
in main class I created JFrame object to draw the cube
JFrame jf = new JFrame();
jf.add(new Cube());
jf.setEnabled(true);
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jf.setResizable(false);
jf.setSize( 500, 500 );
jf.setVisible( true );
Since I do not have your jar file there is no way for me to know the problem. You need to access the file as a resource and not as a new file because it is inside the jar. First you should use cmd to run the jar and see if it gives you a stack trace. Use the command: java -jar filename.jar to run the jar via command prompt.
Try using:
Cube.class.getResourceAsStream("bg_image.jpg");
bg = ImageIO.read(new File("bg_image.jpg"));
This code says that bg_image.jpg should be near with .jar
You may put image into resources and load it like:
Cube.class.getClassLoader().getResourceAsStream("bg_image.jpg");
ps: load resources in constructor is bad idea!
I am using eclipse and wondering where to put an image so that I can import it into java. I am trying to import an image called viewport.png into JPanel from a folder called pictures that I have placed in my src folder within my workspace. This is what I have tried:
private Image viewport = new ImageIcon("src/images/viewport.png").getImage();
then of course later,
g.drawImage(viewport, 2, 2, null);
I really just want to be able to import a picture from the same folder, as this project is being moved to another computer where it will have a different path, but still be in the same folder. I was wondering if there is a shortcut to finding it that way (just be looking in the same folder as the classes are in).
Access the image via the classpath. You can do it by using getClass().getResource() which returns an URL you can pass the ImageIcon(URL) or ImageIO.read(URL) (which returns an Image. The latter is preferred, as an exception will be thrown is something is wrong with the path
BufferedImage viewPort;
...
try {
viewPort = ImageIO.read(getClass().getResource("/pictures/viewport.png"));
} catch (IOException ex) {
// print some message
}
Your pictures should be in the src
ProjectRoot
src
pictures
viewport.png
I'm trying to make my panel show image as background. I already can do that in NetBeans, but when I build my jar and run it image doesn't show there. I know I have to access it differently. I have seen many tutorials but every one of them shows how to do it with ImageIcon, but I don't need that, I need just Image. Can anyone point out what piece of code do I need to do this? Thanks.
This is my code for backgrounded JPanel:
public class JPanelWB extends JPanel { // Creates JPanel with given image as background.
private Image backgroundImage;
public JPanelWB(String fileName){
try {
backgroundImage = ImageIO.read(new File(fileName));
} catch (IOException ex) {
new JDialog().add(new Label("Could not open image."+ex.getMessage()));
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw the background image.
g.drawImage(backgroundImage, 0, 0, getWidth(),getHeight(),this);
}
}
Yeah, you're trying to read in the image as a file -- don't do that since files don't exist within a Jar file. Instead read it in as a resource.
Something like so:
public JPanelWB(String resourceName){
try {
// backgroundImage = ImageIO.read(new File(resourceName));
backgroundImage = ImageIO.read(getClass().getResource(resourceName));
} catch (IOException ex) {
new JDialog().add(new Label("Could not open image."+ex.getMessage()));
}
}
But note that resource path is different from file path. The resource path is relative to the location of your class files.
If you want to read new image and import it as background, people smarter than me already answered your question.
But, if your problem is similar to mine, then this migh help:
If you already have images to show, then the point is to call them from absolute path. Executable class form JAR will read drive created inside virtual machine, not the physical drive in your computer.
Put images in short-pathed folder like
C:\J\proj\img\
and call them with absolute path like
"C:\\J\\proj\\img\\your_image.png" // (Don't forget the double backslashes.)
(If you don't mind path lenght, leave them in image folder inside your project package, and call them from there.)
NetBeans will pack them into JAR with absolute path. On execution JRE will create JVM with that path in it, take the images from JAR and put them to that virtual path. Class will be able to find them, because it doesn't read path from physical drive, but from own virtual one newly created inside JVM.
In that case avoiding ImageIcon is just more clutter, not less.
You can add "blackBoard" as JLabel to be background to your JFrame, set its layout to null, something like this:
private JLabel blackBoard;
private JLabel noteToSelf;
//.....
blackBoard = new JLabel();
noteToSelf = new JLabel();
//.....
// putting JLabel "blackBoard" as background into JFrame
blackBoard.setIcon(new ImageIcon("c:\\Java\\images\\MarbleTable.png"));
getContentPane().add(blackBoard);
blackBoard.setBounds(1, 1, 400, 440);
blackBoard.setLayout(null);
and then add components into "blackBoard" instead of your JFrame, like this.
// putting JLabel "noteToSelf" onto background
noteToSelf.setIcon(new ImageIcon("c:\\Java\\images\\Sticker_a1.png"));
// or: noteToSelf.setText("Remind me at 6:30am...");
blackBoard.add(noteToSelf);
noteToSelf.setBounds(noteX, noteY, 64, 48);
Now your JFrame is table board and "blackBoard" is table sheet on it.
Hope this helps.
I wrote a method in order to get icon for my swing:
public Icon getIcon(String iconName) {
Icon icon = null;
if(iconName.equals("NEXT")){
icon = new ImageIcon( getClass().getResource("resources/img/next.png" ) );
}
return icon;
}
but
icon = new ImageIcon( getClass().getResource("resources/img/next.png" ) );
goes in null pointer
I created a source folder "resources" and a folder "img" inside it with "next.png" icon
Where's the problem?
Thanks
For this to work, the resources folder should be in the same folder as the folder corresponding to the package of this.getClass(). To start from the root of the classpath, use getClass().getResource("/resources/img/next.png"). (with a leading /)
so, I found the right method:
public static ImageIcon getImageIcon(String iconName) {
ImageIcon imageIcon = null;
if(iconName.equals("DOWNLOAD")){
imageIcon = new ImageIcon(ImagesLocation.class.getResource("/img/download.png"));
}
return imageIcon;
}
with a "resources" source folder at the same level of the project and with an img folder inside (package styled)
ImagesLocation is a generic class containing this method
For those in need of help that have come across this page in Google - I wrote an answer in another StackOverflow question giving the best way to handle images in JAVA apps so that you can easily access the images for all image method types in Java:
This IS the best way to handle all images and icons in a JAR App.
Once you've zipped up all of your images and icons into its own JAR file - Configure your build path by adding the images JAR file into your libraries tab so that its now included in your classpath.
Then simply use the following 3x lines of code at the start of your constuctor to access any image you need for anything including a SystemTray image which doesn't accept the simple ImageIcon's as its main icon (weird I know). The 3x lines are:
URL iconUrl = this.getClass().getResource("/image-iconb.png");
Toolkit tk = this.getToolkit();
someimgicon = tk.getImage(iconUrl);
(someimgicon is just a constructor declared Image variable)
Now you can set a window icon as simply as:
setIconImage(someimgicon);
and at the same time use the same variable when setting the System TrayIcon by declaring:
trayIcon = new TrayIcon(someimgicon, "SystemTray Demo", popupMenu);
The above allows you to declare Images or ImageIcons easily and centrally without running the risk of not keeping image resources in the right place. It keeps it nice and tidy, with the JAR containing all your images automatically compiled at run time and distribution of your program.
As a bonus, once the JAR is registered in your classpath - you can keep adding any other images into the same JAR at any time without any fuss too - Everything just works and the added images are instantly available to your app.
Much better in my view.