NullPointerException when trying to display image? - java

This applet is a simple about the developer page in a website i'm creating for a class project. I'm trying to display an image and a bio for each different JButton.
I'm having an Issue with compiling, I keep getting a NullPointerException error
on this line
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
Which i'm assuming it goes null because it can't find the image based on the directory i'm giving it. However I can't understand what I can do different, I can't see any problems with how the directory is written. The directory is pics/filename.jpg and the folder is in the same package as the Java code.
Here is the full source code.
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Developers extends JApplet{
private JButton danButton = new JButton("Dan Skaggs");
private JButton brandonButton = new JButton("Brandon Shaw");
private JButton jamesButton = new JButton("James Simpson");
private JLabel bioLabel = new JLabel("Please click one of the buttons on the left.");
JPanel centerPanel = new JPanel(new GridLayout(1, 2));
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel westPanel = new JPanel(new GridLayout(1, 3));
private ImageIcon danPic;
private ImageIcon brandonPic;
private ImageIcon jamesPic;
private JLabel dLabel;
private JLabel bLabel;
private JLabel sLabel;
//This array carries the Bios of the group project members
String[] bio = new String[]{"Insert Bio",
"Insert Bio",
"Insert Bio"};
public Developers(){
mainPanel.add(westPanel, BorderLayout.WEST);
westPanel.add(danButton);
westPanel.add(brandonButton);
westPanel.add(jamesButton);
centerPanel.add(bioLabel);
mainPanel.add(centerPanel, BorderLayout.CENTER);
danButton.addActionListener(new Handler());
brandonButton.addActionListener(new Handler());
jamesButton.addActionListener(new Handler());
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
brandonPic = new ImageIcon(getClass().getResource("pics/brandonShaw.jpg"));
jamesPic = new ImageIcon(getClass().getResource("pics/jamesSimpson.jpg"));
dLabel = new JLabel (danPic);
bLabel = new JLabel (brandonPic);
sLabel = new JLabel (jamesPic);
centerPanel.add(dLabel);
add(mainPanel);
}
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
if(event.getSource()== danButton){
bioLabel.setText(bio[0]);
centerPanel.add(dLabel);
}
else if(event.getSource()== brandonButton){
bioLabel.setText(bio[1]);
centerPanel.add(bLabel);
}
else if(event.getSource()== jamesButton){
bioLabel.setText(bio[2]);
centerPanel.add(bLabel);
}
}
}//end Handler class
}//end Developer class

Use ImageIO instead, it will give the exception you can caught and process accordingly.
Or
danPic = new ImageIcon(getClass().getResource("pics/danSkaggs.jpg"));
You are missing the / as pics is package name, must use / to make url other wise pics will embed to the parent dir name to make mistake.So use (poor way)
danPic = new ImageIcon(getClass().getResource("/pics/danSkaggs.jpg"));
The Exception is on the first one because it is executed first also change other two statements that are getting the image.
I just tested that it is working fine.

So getResource is returning null: your path to the picture is wrong. Note that these are relative paths (relative to the class you fetched with getClass) so you are probably missing the initial slash which would make it an absolute path.

This should be:
danPic = new ImageIcon(getClass().getClassLoader().getResourceAsStream("danSkaggs.jpg"));
This will load the image from the class path assuming pics directory is on the class path.

getClass().getResource("pics/danSkaggs.jpg") is a relative path. If your class is at a package com.mydomain it expects to find the image in /com/mydomain/pics/danSkaggs.jpg
If the class and the image are in the same package just use getResource("danSkaggs.jpg"). For more details check this comment sample code that demonstrates loading resources using either a class or even better its classloader.

Related

How do I use a gif file in a Java program?

I'm trying to add a .gif image to a JButton, but can't seem to get the image to load when i run the code. I've included a screenshot. Included is the frame that's created. I'd really appreciate any help that can be provided. Stack is telling me I can't enter images yet, so it created a link for it. I'm also going to enclose the actual code here:
package java21days;
import javax.swing.*;
import java.awt.*;
public class ButtonsIcons extends JFrame {
JButton load, save, subscribe, unsubscribe;
public ButtonsIcons() {
super("Icon Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
//Icons
ImageIcon loadIcon = new ImageIcon("load.gif");
ImageIcon saveIcon = new ImageIcon("save.gif");
ImageIcon subscribeIcon = new ImageIcon("subscribe.gif");
ImageIcon unsubscribeIcon = new ImageIcon("unsubscribe.gif");
//Buttons
load = new JButton("Load", loadIcon);
save = new JButton("Save", saveIcon);
subscribe = new JButton("Subscribe", subscribeIcon);
unsubscribe = new JButton("Unsubscribe", unsubscribeIcon);
//Buttons To Panel
panel.add(load);
panel.add(save);
panel.add(subscribe);
panel.add(unsubscribe);
//Panel To A Frame
add(panel);
pack();
setVisible(true);
} //end ButtonsIcon Constructor
public static void main(String[] arguments) {
ButtonsIcons ike = new ButtonsIcons();
}
} //end ButtonsIcon Class
enter image description here
The easiest way is.
Label or Jbutton and what ever else supports HTML 3.5
JLabel a = new JLabel("");
add that to your container.
Haven't figured out how to enter code sorry

Referencing an external parent JPanel

I am currently trying to code a GUI for an assignment as extra credit, as a learning opportunity. I need to have a menu of buttons, with each button effectively changing the main panel to enter or display data. Right now, I have a class called buttonContainer, which holds the main menu, and mainPanel, which holds the main panel for the entire GUI. Basically I need a way to have buttonContainer add and remove elements from its parent, mainPanel- with the two of them remaining seperate files.
My buttonContainer class looks like this:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class buttonPanel extends JPanel implements ActionListener
{
private JButton load, save, list, find, input, sort, exit;
private JPanel BtnContainer, parent;
private newContactPanel newContact;
public buttonPanel()
{
load = new JButton("Load Contacts");
save = new JButton("Save Contacts");
list = new JButton("List Contacts");
find = new JButton("Find Contact");
sort = new JButton("Sort Contacts");
input = new JButton("New Contact");
exit = new JButton("Exit Program");
newContact = new newContactPanel();
parent = this.getParent();
BtnContainer = new JPanel();
BtnContainer.setLayout(new GridLayout(0,1));
BtnContainer.add(load);
BtnContainer.add(save);
BtnContainer.add(list);
BtnContainer.add(sort);
BtnContainer.add(find);
BtnContainer.add(input);
BtnContainer.add(exit);
add(BtnContainer);
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == input)
{
//Change panel command here
}
}
}
With the mainPanel code looking like this:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class mainPanel extends JPanel //implements ActionListener
{
private buttonPanel MainMenu;
private newContactPanel newContact;
private JPanel wrapper;
public mainPanel()
{
wrapper = new JPanel();
this.setLayout(new BorderLayout());
wrapper.setLayout(new BorderLayout());
MainMenu = new buttonPanel();
newContact = new newContactPanel();
wrapper.add(MainMenu, BorderLayout.WEST);
add(wrapper, BorderLayout.WEST);
}
}
contactPanel is a different panel, that I want buttonPanel to trigger mainPanel to show. Is there any easy way of refrencing the parent class like this, while keeping the two classes separate?
I know variants of this question have been asked before, but, nothing I read here seemed to get done what I wanted. Several of them didn't really match exactly what I was looking for- most of them were from the same file. several used a getParent()- but if I try to use it, it only grabs a Container, and not a JPanel.
EDIT: Thanks to the people who answered. A couple of good ideas were presented- which helped me realize I forgot to actually add the action listener to the button. This question has been fully solved!
Basically I need a way to have buttonContainer add and remove elements from its parent, mainPanel- with the two of them remaining
seperate files.
You can use SwingUtilities.getAncestorOfClass(class, comp) from within your ButtonContainer class as you know it will be a child of that class. For example:
class ButtonContainer extends JPanel implements ActionListener {
...
#Override
public void actionPerformed(ActionEvent e) {
MainPanel mainPanel = (MainPanel)SwingUtilities.getAncestorOfClass(MainPanel.class, ButtonContainer.this);
if (mainPanel != null) {
// Change panel command here
}
}
}
Off-topic
Please read Java Code Conventions and stick to them. Class' names start with a capital letter; variables and methods names start with lower case.
you can make wrapper public static
public static JPanel wrapper;
then from buttonPanel you can use this code
mainPanel.wrapper.remove(<whatever component>);
mainPanel.wrapper.add(<whatever component>);
mainPanel.wrapper.validate();
mainPanel.wrapper.repaint();
i think this will work

Failed to get my image loaded [duplicate]

This question already has answers here:
Displaying an ImageIcon
(2 answers)
Add a picture to a JFrame
(3 answers)
Closed 9 years ago.
I am trying to add a picture of a cow and eclipse is failing me. It won't allow any images, I think I may be doing my path wrong, but I am getting it straight from the properties that eclipse supplies upon right-clicking the image. So if anyone has any idea why my picture fails to load please tell me. NO ERROR MESSAGE!
package odin;
import java.awt.event.*;
import javax.swing.*;
public class Main extends JFrame implements ActionListener{
JPanel mypanel;
JButton mybutton;
JLabel mylabel;
int Counter = 0;
public Main(){
mypanel = new JPanel();
mybutton = new JButton("OK");
mybutton.addActionListener(this);
mylabel = new JLabel();
JLabel imgLabel = new JLabel(new ImageIcon("/GuiTest/src/odin/COW.png"));
mypanel.add(mybutton);
mypanel.add(mylabel);
mypanel.add(imgLabel);
this.add(mypanel);
}
public static void main(String[] args){
Main first = new Main();
first.setTitle("First Attempt");
first.setSize(800,600);
first.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
first.setVisible(true);
first.setResizable(false);
first.setLocationRelativeTo(null);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==mybutton)
{
Counter = Counter + 1;
mylabel.setText("My Clicks " + Counter);
}
}
}
The problem is the path to the image...
JLabel imgLabel = new JLabel(new ImageIcon("/GuiTest/src/odin/COW.png"));
Basically, ImageIcon(String) expects that the String represents a file. This means, that Java is look for the image starting from the root of the current drive...which probably isn't what you really want...
You should also not store resources within the src directory in Eclipse, as I understand it, Eclipse requires you to place these resources within the "resources" directory within the project. These will be included within the project when you build it...
Once you've move the image to this location, you should be able to access it as an embedded resource using something like...
JLabel imgLabel = new JLabel(new ImageIcon(getClass().getResource("/odin/COW.png")));

Why does this simple code not work

I am having trouble with this simple example code from the book. It is supposed to represent the same image 2 times in one window (north and south labels), one above the other. When I run it, it displays this instead of this (I am sorry for not cutting the images or resizing them) Below is my code. I am running Eclipse Juno on Ubuntu 13.04.
package gui;
import java.awt.BorderLayout;
import javax.swing.*;
public class Gui {
public static void main(String[] args) {
JLabel northLabel = new JLabel ( "North" );
ImageIcon labelIcon = new ImageIcon ("GUItip.gif");
JLabel centerLabel = new JLabel (labelIcon);
JLabel southLabel = new JLabel (labelIcon);
southLabel.setText("South");
JFrame application = new JFrame();
application.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
application.add(northLabel, BorderLayout.NORTH);
application.add(centerLabel, BorderLayout.CENTER);
application.add(southLabel, BorderLayout.SOUTH);
application.setSize(300, 300);
application.setVisible(true);
}
}
You need to concentrate on the following statement:
ImageIcon labelIcon = new ImageIcon ("GUItip.gif");
When initiating new ImageIcon.. it searches the provided address in execution folder by default i.e. in this case "GUItip.gif" shall be searched within workspace/user directory.
One solution is to make available GUItip.gif image in you workspace (program execution) folder.
Another solution would be to provide absolute path.. eg.
C:\USER\Workspace\project_name\GUItip.gif
Though a better approach would be to create a specific folder where you save all images used in your project. Create a final static String variable with absolute path to your folder. Now it would be easy for any programmer in that project to know where to look for images.
There are good approaches to use this mapping.. through XML to be loaded in the beginning.. through resourcebundle etc but that is a different topic altogether.
The image probably isn't loading properly. Try using a try/catch block to see if that's the case.
Ex:
Image img;
File f = new File(//image url);
try {
img = ImageIO.read(f);
} catch (IOException e) {
String curr_dir = System.getProperty("user.dir");
throw new IllegalArgumentException("Image could not be found from " + curr_dir);
}
ImageIcon labelIcon = new ImageIcon(img);

refresh the contents of frame in real time [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
When does one need to call revalidate() on a swing component to make it refresh, and when not?
i am making a Explorer program in Java it works as follows
i input the path from the user, a textbox after the user presses enter the path is set and the list is computed of the folder and corresponding labels are created which are supposed to be displayed on the window but the application doesn't display the new contents of the folder, if i change the text then it directs to a new directory so when i press enter then it must show the contents of the new directory loaded but only after resizing the window does it show the new contents of the frame
the code is as follows
package explorer;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Explorer extends JFrame{
File file;
Scanner scan;
String path;
String [] listOfFiles;
JTextField txtPath;
JLabel lblLocation;
JLabel child[];
JPanel childPanel;
JPanel masterPanel;
public Explorer(){
lblLocation = new JLabel("Location: ");
/*
* the declaration of panels
*/
masterPanel = new JPanel();
childPanel = new JPanel();
JPanel panel = new JPanel();
/*declaration of other components*/
txtPath = new JTextField("",20);
/*addition of components to panel for layout*/
panel.add(lblLocation);
panel.add(txtPath);
/*adding to master panel, for sophisticated layout*/
masterPanel.add(panel, BorderLayout.NORTH);
masterPanel.add(childPanel, BorderLayout.SOUTH);
getContentPane().add(masterPanel);
/*this place from where address is fetched like /home/revolution/Desktop etc on ubuntu*/
txtPath.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
childPanel.removeAll();
path = new String(txtPath.getText());//the absolute path
file = new File(path);
File childFiles[];
String name = path.substring(path.lastIndexOf('/')+1, path.length());//the name of the directory being displayed
setTitle(name);
if(!file.isDirectory()){
JOptionPane.showMessageDialog(null, "Error file is not a directory");
} else {
listOfFiles = file.list();
child = new JLabel[listOfFiles.length];// labels equal to the number fo files and with name of the coresponding file/folder
childFiles = new File[listOfFiles.length];//references to files
childPanel.setLayout(new GridLayout(listOfFiles.length/2,listOfFiles.length/2));//setting grid layout
for(int i=0; i<listOfFiles.length;i++){
childFiles[i] = new File(listOfFiles[i]);
child[i] = new JLabel(listOfFiles[i]);
child[i].setToolTipText(childFiles[i].isFile()?"File":"Folder");
childPanel.add(child[i]);
}
childPanel.setVisible(true);
}
}
});
}
}
what is wrong? how can i 'refresh' the contents of the window??
I think you need to revalidate() the panel.
More precisely at the end of your action listener you can add childPanel.revalidate();
childPanel.setVisible(true);
}
}
childPanel.revalidate();
});

Categories