Search code examples
javaimageswingembedded-resourceimageicon

Setting JFrame icon - can't get suggested solutions in previous threads working


I am trying to set a JFrame icon. I have tried all the suggested solutions here and here , but have not yet had success.

In my method below you can see all the solutions attempted:

1 and 2 do not set an icon (I still see the coffee cup).

3 and 6 get this error:

The method setIconImage(Image) is undefined for the type Icon 

4 gets this error:

java.lang.NullPointerException

5 get:

Type mismatch: cannot convert from URL to DocFlavor.URL

My calling class is here:

/Users/lawrence/eclipse-workspace/COA_Application/src/main/java/misc/Icon

My image is here:

/Users/lawrence/eclipse-workspace/COA_Application/Logo.png 

(I have also tried COA_Application/src/main/resources/Logo.png)

I am a beginner so apologies if I am being slow. Note also I am using a mac.

package misc;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;

import javax.imageio.ImageIO;
import javax.print.DocFlavor.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.google.api.services.sheets.v4.model.Color;

public class Icon {
    
    static String filepath = "/Logo.png";
    
    public void showFrame() throws IOException {
        
        JFrame frame = new JFrame("Icon frame");
        
        //method 4
    frame.setIconImage(Toolkit.getDefaultToolkit().getImage(this.getClass().getResource(filepath)));
        
         //method 1
        //BufferedImage myPicture = ImageIO.read(new File(filepath));
        //frame.setIconImage(myPicture);
        
        //method 2
        //frame.setIconImage(ImageIO.read(new File(filepath)));
        
        //method 3
        //setIconImage(new ImageIcon(filepath).getImage());
        
        //method 5
        //URL url = getClass().getResource(filepath);
        //frame.setIconImage(imgicon.getImage());
        
        //method 6
        //ImageIcon img = new ImageIcon(getClass().getClassLoader().getResource("./icon.png"));
        //setIconImage(img.getImage());
        
        JPanel panel = new JPanel();
        frame.add(panel);
        
        frame.pack();
        frame.setSize(new Dimension(600,600));
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    public static void main(String[] args) throws Exception {
        
        Icon obj = new Icon();
        obj.showFrame();
    }
}

Image: My icon


Solution

  • Application resources will become embedded resources by the time of deployment, so it is wise to start accessing them as if they were, right now. An must be accessed by URL rather than file. See the info page for embedded resource for how to form the URL.

    Of course, the devil is in the details. The (upper / lower) case used for the path and resource name must be exactly as they are on the file system. The easiest way to make getResource(..) to works is to use a path from the root of the class-path. Specifying 'from the root' is done by prefixing the path with /.

    Example using latest code (loads the icon from URL):

    import java.awt.*;
    import javax.swing.*;
    import java.net.*;
    
    public class Icon {
        
        public void showFrame() throws Exception {
            JFrame frame = new JFrame("Icon frame");
            
            URL url = new URL("https://i.sstatic.net/bQ8fP.png");
            frame.setIconImage(Toolkit.getDefaultToolkit().getImage(url));
            
            frame.pack();
            frame.setSize(new Dimension(400,100));
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        
        public static void main(String[] args) throws Exception {
            Icon obj = new Icon();
            obj.showFrame();
        }
    }
    

    enter image description here

    Edit:

    Given it works perfectly here, I'm starting to think the problem is the particular JRE being used.

    I have just built and installed my application and it has the correct icon!