So when i'm tried to put an icon to my button with createIcon() method that i declared inside of the button's class, it works fine.
BUT,
when i try to put the method in another class (say Utils.java), so that i don't need to re-declare the method in the class where the object needs icon, i get this message.
Unable to load image: /images/Save16.gif
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because "location" is null
*there's more message if needed
this is the button's class with createIcon() method inside
public class Toolbar extends JToolBar implements ActionListener{
private final JButton saveBtn;
public Toolbar() {
saveBtn = new JButton();
saveBtn.setIcon(createIcon("/images/Save16.gif"));
saveBtn.setToolTipText("Save");
saveBtn.addActionListener(this);
add(saveBtn);
}
private ImageIcon createIcon(String path) {
URL url = getClass().getResource(path);
if(url == null) {
System.err.println("Unable to load image: " + path);
}
ImageIcon icon = new ImageIcon(url);
return icon;
}
}
this is the createIcon() method that i'm trying to declare in another class
public class Utils {
public static ImageIcon createIcon(String path) {
URL url = System.class.getResource(path);
if(url == null) {
System.err.println("Unable to load image: " + path);
}
ImageIcon icon = new ImageIcon(url);
return icon;
}
}
which changed the setIcon() method into:
saveBtn.setIcon(Utils.createIcon("/images/Save16.gif"));
from what i analyzed in the message the problem is might be the url which can't get the path from my button's class, i've tried several alternatives but it's still didn't work. how should i properly set this up? thanks
This works:
URL url = getClass().getResource(path);
because you get the class of your Toolbar class, which is where all your other classes/files are located.
This doesn't work:
URL url = System.class.getResource(path);
because the "System" class is found in the JDK not with your application classes.
I would guess you could try:
URL url = Utils.class.getResource(path);
Related
everybody.
I am novice in Java and making training project with UI.
In process of trainings I decided to load icons from resources and to move its loading in the different class.
And got problem.
I really tried to find answers by myself but could not.Code bellow.
Main class
package scv.paul;
…
/**
* Create the application.
*/
public TestApp() {
Logger.getLogger(loggerName).fine("Showing main window");
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setTitle("Test App");
**frame.setIconImage( MyImages.appIcn.getImage());**//here try to load icon
And get exception:
Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError
Utility class
package scv.paul;*
import javax.swing.ImageIcon;
public class MyImages {
public static final ImageIcon appIcn = new ImageIcon ( MyImages.class.getResource ( "AppIcon.png" ) );
public static final ImageIcon BtnIcn = new ImageIcon ( MyImages.class.getResource ( "OK.png" ) );
public static final ImageIcon exitIcn = new ImageIcon ( MyImages.class.getResource ( "door.png" ) );
}
Images lay in "\bin" folder
I understand that the problem in the initialization of the static fields. But can’t understand reason.
I got this error if I call even such static field
public static final String imgPath = System.getProperties().getProperty("user.dir")+"\\img\\";
But I have no errors if I call in main class this static field
public static final String imgPath = "c://myProjectPath//bin";
And I could not find how to work with resources in good stile. Where I could read it?
Don't use static variables for something like this. There is no need to keep a reference to the icon. Just read the Icon and add it to your button.
Just load the images in the constructor of your class (when you create your buttons). See the section from the Swing tutorial on How to Use Icons for more information and working examples.
The tutorial will also show you how to better structure your code so the Swing components are created on the Event Dispatch Thread.
Keep a link to the tutorial handy for other Swing basics.
Put you images in the directory of the projecet, e.g. where the bin and src folders are located.
Its best to use a static method to read in files aswell incase they fail. Say you your resource folder within the directory called resources, your code would look something like this.
public static ImageIcon makeImageIcon(String filename) {
BufferedImage myPicture = null;
try {
myPicture = ImageIO.read(new File("resources/" + filename));
} catch (IOException e) {
e.printStackTrace();
}
return new ImageIcon(myPicture);
}
And then call this with the file name you want the same way you have done above.
public static ImageIcon image= makeImageIcon("myImage.png");
Hope this helps.
Currently I pass a hardcoded string file location to my object method which uses the string in the .getResources() method to load an image file. I am now trying to chooses an image using a load button and pass the loaded file location as a string into the getResource() method. I am using the filename.getAbsolutePath() method to retrieve the file location then passing the filename variable into the object method however this provides me with the following error -
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException.
The line of code that it points to having the error is the .getResources line where the image is loaded. I will post the code below to better understand my problem.
btnLoad.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser();
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
File loadImage = fc.getSelectedFile();
String filename = loadImage.getAbsolutePath();
filename = filename.replaceAll("\\\\", "\\\\\\\\");
picLocation = filename;
ImageSwing imageSwing = new ImageSwing(filename);
System.out.println(filename);
}
}
The output of the file name is correct yet it still wont pass into the object.
public class ImageSwing extends JFrame
{
public JLabel label;
public ImageSwing(String S){
super("Card Stunt"); //Window Title
setLayout(new FlowLayout()); //lookup grid layout
Icon flag = new ImageIcon(getClass().getResource(S));
label = new JLabel(flag);
label.setToolTipText(S);
setSize(1350, 800);
//setMinimumSize(new Dimension(1200, 760));
}//main
}
It seems like you create an absolute filename with loadImage.getAbsolutePath(), but then you try to use this as a class path resource with new ImageIcon(getClass().getResource(S)).
Instead, you should just pass the absolute filename, as a string, to ImageIcon:
Icon flag = new ImageIcon(S);
Also, don't forget to add the label to the frame...
getContentPane().add(label);
Also, I'm not on Windows right now, but I don't think filename.replaceAll("\\\\", "\\\\\\\\"); is necessary.
I want to call the return statement tempimage in load_picture by passing it to showWindow, but I'm not sure how. heres a snippet of my code. edit:
i guess what I'm trying to say is, I'm not exactly sure what to do with the hardcoded "picture1.gif". I understand that I need to call a method to load the image, but I'm not too sure what to put in place of it.
:
package project3;
import java.util.Scanner;
import javax.swing.;
import java.awt.;
import java.net.*;
public class Project3 {
//initializing global
static Project3 theobject = new Project3();
final static int MIN_NUMBER=1;
final static int MAX_NUMBER=8;
static int image_number=1;
static Image theimage;
// This routine will load an image into memory, non-static requires an object
// It expects the name of the image file name and a JFrame passed to it
// It will assume an Internet conection is available
// It can only be called AFTER the program object has been created
// It will return a type Image variable, call it like this: theimage = object.load_picture("picture1.gif", frame);
// (hard code 'picture1.gif' only when testing - USE a method or variable for 'real' call)
// This code requires you to do an 'import java.awt.*' and an 'import java.net.*'
// Note: this method is using parameter and return type for input/output
// This routine will load an image into memory, non-static requires an object
// It expects the name of the image file name and a JFrame passed to it
// It will assume an Internet conection is available
// It can only be called AFTER the program object has been created
// It will return a type Image variable, call it like this: theimage = object.load_picture("picture1.gif", frame);
// (hard code 'picture1.gif' only when testing - USE a method or variable for 'real' call)
// This code requires you to do an 'import java.awt.*' and an 'import java.net.*'
// Note: this method is using parameter and return type for input/output
public Image load_picture(String imagefile, JFrame theframe)
{
Image tempimage;
// Create a MediaTracker to inform us when the image has
// been completely loaded.
MediaTracker tracker;
tracker = new MediaTracker(theframe);
// getImage() returns immediately. The image is not
// actually loaded until it is first used. We use a
// MediaTracker to make sure the image is loaded
// before we try to display it.
String startURL;
if (imagefile.startsWith("http"))
startURL = "";
else
startURL = "http://www.canyons.edu/departments/comp_sci/ferguson/cs111/images/";
URL myURL=null;
try
{
myURL = new URL(startURL + imagefile);
}
catch(MalformedURLException e) {
System.out.println("Error caught " + e.toString());
}
//tempimage = getImage(myURL); // JApplet version
tempimage = Toolkit.getDefaultToolkit().getImage(myURL); // stand alone program version
// Add the image to the MediaTracker so that we can wait for it
tracker.addImage(tempimage, 0);
try { tracker.waitForID(0); }
catch ( InterruptedException err) { System.err.println(err); }
return tempimage;
}
// This class/method uses a global variable that MUST be set before calling/using
// note: You can not call the paint routine directly, it is called when frame/window is shown
// look up the repaint() routine in the book
// Review Listings 8.5 and 8.6
//
public static class MyPanel extends JPanel {
public void paintComponent (Graphics g) {
JPanel panel= new JPanel();
int xpos,ypos;
super.paintComponent(g);
// set the xpos and ypos before you display the image
xpos = 300; // you pick the position
ypos = 200; // you pick the position
if (theimage != null) {
g.drawImage(theimage,xpos,ypos,this);
// note: theimage global variable must be set BEFORE paint is called
}
}
}
public static void showWindow( String filename ) {
// create, size and show a GUI window frame, you may need to click on taskbar to see window
//display the filename in the title of the window frame, otherwise the window will be blank (for now)
JFrame frame1= new JFrame();
theimage = theobject.load_picture("picture1.gif", frame1);
//"picture1.gif" is hardcoded, I want to call this using a method
frame1.setTitle(filename);
frame1.setSize(440,302);
frame1.setLocation(400,302);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
}
Any help is appreciated. Thanks
The value that is returned by the load_picture method can be sent directly to the showWindow method, or you can assign it to a variable:
String filename = "your/filename";
JFrame theFrame = new JFrame();
Project3 project = new Project3();
MyPanel.showWindow(project.load_picture(filename, theFrame);
From within the showWindow method, just call the load_picture method as follows:
Image tempImage = load_picture(filename, frame1);
From here you can do anything you like with the tempImage object.
This code runs correctly on windows XP. But at home on my Windows 7 machine I can't see the icons because getResource returns null. I've tried an absolute path and it's not working either. I don't know what to do, I'm running Eclipse in Admin mode:
private static JButton createToolButton(String imgName, String altText, String toolTipText) {
String imagePath = IMG_URL + "/" + imgName;
URL imageUrl = SwingUtility.class.getResource(imagePath);
JButton button = new JButton();
button.setToolTipText(toolTipText);
if(imageUrl != null) //Image trouvé
button.setIcon(new ImageIcon(imageUrl, altText));
else
button.setText(altText);
return button;
}
The getResource() method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource. So after all these, if it returns null, the problem is with imagepath ergo IMG_URL. Also note that it returns null if the resource could not be found or the invoker doesn't have adequate privileges to get the resource.
Here's my solution, not ideal but it works. After many tests I just feel like using the dot notation to go up and into the current directory not work exactly as expected using the basic java utilities. Ended up just getting the project path and splitting it where I wanted, hasn't been tested on other machines yet.
private static JButton createToolButton(String imgName, String altText, String toolTipText)
{
String imagePath = IMG_FOLDER_NAME + "\\" + imgName;
BufferedImage img = null;
JButton button = new JButton();
try
{
img = ImageIO.read(new File(projectPath() + imagePath));
}
catch (IOException e)
{
e.printStackTrace();
}
button.setToolTipText(toolTipText);
if(img != null)
button.setIcon(new ImageIcon(img, altText));
else
button.setText(altText);
return button;
}
private static String projectPath()
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("");
String pathArr[] = url.getPath().split(PATH_SEPARATOR);
return pathArr[0];
}
I have tried several methods to add an Icon to a JFrame. Every method work perfectly when I run it using the source code.
for example:
jframe.setIconImage(Toolkit.getDefaultToolkit().getImage("iconimages/icon.png"));
But none of them work when I run it using the jar file. I know the problem is with the path of the image file. How can I solve this?
Edit:
public Ui() {
initComponents();
setLocationRelativeTo(null);
this.setIconImage(getImageIcon("icon.png").getImage());
}
private ImageIcon getImageIcon(String fileName) {
String imageDirectory = "iconimages/";
imgURL = getClass().getResource(imageDirectory + fileName);
return new ImageIcon(imgURL);
}
I tried this but now I get a null pointer exception.
--------------------------------------------------------------------------------
Edit [Solution] : I found the solution.
I added ../ to the path additionally and it works perfectly!!! :D
ImageIcon imageIcon = new ImageIcon("../imageicons/icon.png");
this.setIconImage(imageIcon.getImage());
Thanks all for try to help me. :)
You should use a URL. Like this:
/**
* Loads and returns an {#link Image} resource.
* #param fileName name of the image resource.
* #return Image as resource.
*/
public Image getResourceImage(String fileName) {
String imageDirectory = "images/";
URL imgURL = getClass().getResource(imageDirectory + fileName);
Image image = null;
try {
image = ImageIO.read(imgURL);
} catch (IOException e) {}
return image;
}