Java Swing JButton getResource not working well - java

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];
}

Related

unable to get the path(url) of image with createIcon() method

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);

Get the file path from jcombobox

I am trying to select my file from the jcombobox and display the data in a text area. Currently, I have list out the file name but now once i select the filename from the dropdown its showing me this error:
SEVERE: null
This is my current code:
private void jCmboxActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//JComboBox jCmbox = (JComboBox)evt.getSource();
String stateName = (String)jCmbox.getSelectedItem();
updateData(stateName);
}
public void updateData(String path){
String csvFilename = "";
URL url;
try {
url = new URL(csvFilename);
} catch (MalformedURLException ex) {
Logger.getLogger(VisualizationPanel.class.getName()).log(Level.SEVERE, null, ex);
}
url = VisualizationPanel.class.getResource(path);
CSVData data = CSVData.loadFromFile(url.toString()); //loads the csv data
VisualizationPanel visPanel = new VisualizationPanel(this, data); //draws the vis panel and adds the data to it
}
I am new to java can someone pls help me on this. Thank you.
In updateData() you are creating a new URL from an empty string. This is what is throwing your exception.
You can see that on the first line of updateData() you define csvFilename to be an empty string. You never reassign a value to that variable so when you come to use it in the URL constructor it is still empty.
We can see from the URL constructor spec that a the exception you are seeing will be thrown if something is wrong with the spec.
What you could do is change the line String csvFilename = ""; to String csvFilename = path;, and see if that fixes your issue.
In fact, though, since you are rewriting your URL variable straight after the try catch you should just be able to remove that block and avoid the issue completely. Try this:
public void updateData(String path){
String csvFilename = "";
URL url = VisualizationPanel.class.getResource(path);
CSVData data = CSVData.loadFromFile(url.toString()); //loads the csv data
VisualizationPanel visPanel = new VisualizationPanel(this, data); //draws the vis panel and adds the data to it
}

How can I get a variable from a method in java without invoking said method?

I'm coding a small audio player and need help here; the method fopen() is called by a button press in another class (not the issue here); the problem is that I cannot get the file's path as a string without calling the method.
The playsound() method needs the filepath variable from fopen(), and if I use the String 'path' (initialized after fopen()) it calls the method again.
I ONLY need the 'filepath' variable, but I cannot access it outside of fopen(), or at least not that I know of. Assistance on how I can access filepath without invoking fopen()?
EDIT: Fixed fopen() being set up to return a 'File' instead of a string. Also made some changes to the code; the issue of having fopen() called when it's not supposed to be is fixed, but now it gives me a java.io.FileNotFoundException: when I call playsound() (which, from what I understand, means that the file's path and/or name wasn't even recorded). What else is going on here?
Edit 2: I'm just going to ask another question, seeing as the problem at hand seems to have been answered, and I have an entirely different one on my hands.
package mediaz;
import javazoom.jl.player.*;
import javax.swing.filechooser.*;
import java.io.*;
import javax.swing.JFileChooser;
public class audio {
private String lastfilepath = "";
public String fopen(){
JFileChooser fc= new JFileChooser();
FileNameExtensionFilter filtermp3 = new FileNameExtensionFilter("MPEG-2
Audio Layer III", "mp3");
fc.setFileFilter(filtermp3);
int ret = fc.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
String filepath = file.getAbsolutePath();
this.lastfilepath = filepath;
return filepath;
}
else
return null;
}
String path = fopen();
void playsound(){
System.out.println("You pressed play.");
try{
FileInputStream fis = new FileInputStream(this.lastfilepath);
Player playMP3 = new Player(fis);
playMP3.play();
}
catch(Exception e){
System.out.println("Error: '" + e +"'");
}
}
// IGNORE WHAT'S BELOW HERE //
void rewsound(){
System.out.println("You pressed rewind.");
}
void pausesound(){
System.out.println("You pressed pause.");
}
/* void forwardsound(){
System.out.println("You pressed fast forward.");
}
*/
}
Create a String instance variable in audio, and then when you call fopen() store the currently selected file's path in that string.
See code below. Untested, but the idea is here. Also, the formatting of this code is pretty bad, it's hard to read. This is what it should look like (ish).
Edit: Added some comments in the code on general improvements/coding style
Edit: For more info on the try I updated in the code, see: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
package mediaz;
import javazoom.jl.player.*;
import javax.swing.filechooser.*;
import java.io.*;
import javax.swing.JFileChooser;
public class audio {
private String filePath = "";
public File fopen() {
JFileChooser fc = new JFileChooser();
FileNameExtensionFilter filtermp3 = new FileNameExtensionFilter("MPEG-2
Audio Layer III ", "
mp3 ");
fc.setFileFilter(filtermp3); int ret = fc.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
this.filePath = file.getAbsolutePath()
return filepath; // should be file
} else // give me braces please!
return null;
}
// try to stick to camelCase, it is the 'Java' way
void playsound() {
System.out.println("You pressed play.");
// streams implement AutoCloseable, use it
// also, you were not closing fis as it was
try (FileInputStream fis = new FileInputStream(this.filePath)) {
Player playMP3 = new Player(fis);
playMP3.play();
} catch (Exception e) {
System.out.println("Error: '" + e + "'");
}
}
}
Your fopen() method is declared to return a File, yet in the method you return a String. If you returned the file that the user selected, and then stored this reference somewhere, you could ask that file for its path any time you wanted.
Create another method that returns the last filepath determined in fopen(), eg:
private String lastFilepath;
public String fopen() {
// logic for determining filepath
lastFilepath = filepath;
return filepath;
}
public String getLastFilepath() {
return lastFilepath;
}
First of all you should read about scopes in java programming.
What you currently have is a local scope for your variable "filepath". To make it accessible outside its method block you can either return it as the method result or asign it to a instance variable.
In addition please note that your fopen() method currently won't compile cause it is declared to return a File but inside tries to return a String type.
I would recommend the following:
public class foo {
private String filePath;
private void readFile() {
filePath = doReadingHere();
}
private void useFilePath() {
System.out.println(filePath);
// do what ever you like to do with the instance variable filePath
}
}

How to pass a file location as a parameter as a string?

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.

Problem in adding Icon to a JFrame

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;
}

Categories

Resources