Search code examples
javaswingjframeembedded-resourceimageicon

How do I set the icon for my jframe without having to put the icon on my desktop when exporting the jar?


I want to set the icon for my java game to an icon called lgico.png, but when I use:

static ImageIcon icon = new ImageIcon("lgico.png");
public Window(int width, int height, String title, Game game) {
    frame.setIconImage(icon.getImage());
}

My jar file does not have the icon when I create it and put it on my desktop.

Here is my window class in it's entirety:

package com.teto.main;
import java.awt.Canvas;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class Window extends Canvas {
    private static final long serialVersionUID = 5486926782194361510L;
    static ImageIcon icon = new ImageIcon("lgico.png");
    Cursor csr = new Cursor(Cursor.CROSSHAIR_CURSOR);
    public Window(int width, int height, String title, Game game) {
        JFrame frame = new JFrame(title);
        frame.setPreferredSize(new Dimension(width, height));
        frame.setMaximumSize(new Dimension(width, height));
        frame.setMinimumSize(new Dimension(width, height));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.add(game);
        frame.setVisible(true);
        frame.setIconImage(icon.getImage());
        frame.setCursor(csr);
        game.start();
    }
}

I've attempted to find solutions on this site multiple times only to be met with a NullPointerException and my program being a white screen with nothing on it.

I apologize if what I am trying to express doesn't seem very clear as my native language isn't English.


Solution

    1. Don't extend Canvas. You are not adding functionality to the Canvas class so there is not reason to extend it.

    2. Don't call your class Window. The is an AWT class with that name. Class names should be descriptive.

    3. If you are using a jar file, then you probably need to load the image as a resource:

    Here is a basic example:

    import javax.swing.*;
    import java.net.*;
    
    class FrameIconFromMain
    {
        public static void main(String[] args)
        {
            Runnable r = new Runnable()
            {
                public void run()
                {
                    JFrame f = new JFrame("Frame with icon");
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
                    String imageName = "dukewavered.gif";
                    URL imageUrl = f.getClass().getResource(imageName);
    
                    if (imageUrl == null)
                    {
                        System.out.println("imageUrl not found using default classloader!");
                        imageUrl = Thread.currentThread().getContextClassLoader().getResource(imageName);
                    }
    
                    ImageIcon icon = new ImageIcon( imageUrl );
                    f.setIconImage( icon.getImage() );
                    f.setSize(400,300);
                    f.setLocationRelativeTo( null );
                    f.setVisible( true );
                }
            };
    
            SwingUtilities.invokeLater(r);
        }
    }