0

I am trying to change the icon of the Java application but nothing seems to work.

I am trying to get image from resources path using:

getClass().getResource("/AppIcon.png")

Sometimes I get an error like URL not found.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
devsimsek
  • 13
  • 1
  • 6

2 Answers2

1

The image that is used for the Form's icon can be any image but must be loaded as an Image type (not of ImageIcon type). The JFrame#setIconImage() method will auto-size the image loaded. Here just a couple ways. These examples assume that the code resides in a class which extends JFrame:

Example #1:

try {
    /* For a Form's title bar icon....
       Don't use this for animated .gif images otherwise your GUI will 
       freeze. I'm not exactly sure why but it seems as though the gif 
       frames continuously cycle as though in an infinite loop. If you 
       want to use an animated .gif image as a Form's title bar icon 
       then don't use Toolkit, use ImageIO.read() instead since it will 
       only utilize the first gif frame as the image.                */
    // Be sure to set the path string to your specific resources directory.
    this.setIconImage(java.awt.Toolkit.getDefaultToolkit()
            .getImage(getClass().getResource("/resources/images/Apple/png").getFile()));
}
catch (java.lang.NullPointerException ex) {
    // Do what you want with caught exception.
    ex.printStackTrace();
}

Example #2:

try {
    /* Can be used to also display an animated gif for the Form's Title 
       bar icon but only the first gif frame is utilized.         */
    // Be sure to set the path string to your specific resources directory.
    File pathToFile = new File(getClass().getResource("/resources/images/Apple.png").getFile());
    Image image = ImageIO.read(pathToFile);
    this.setIconImage(image);
}
catch (IOException ex) {
    // Do what you want with caught exception.
    ex.printStackTrace();
}

UPDATE:

As stated by @AndrewThompson in comments, the two above examples will not work as expected from a JAR file. They will work if run through the IDE however which in reality is no good except for testing. To use the two examples above in a distributive JAR file then also see Example #3 and Example #4:

Example #3:

try {
    /* For a Form's title bar icon.... To be used in a distributive JAR. 
       Don't use this for animated .gif images otherwise your GUI will 
       freeze. I'm not exactly sure why but it seems as though the gif 
       frames continuously cycle as though in an infinite loop. If you 
       want to use an animated .gif image as a Form's title bar icon 
       then don't use Toolkit, use ImageIO.read() instead since it will 
       only utilize the first gif frame as the image.                */
    // Be sure to set the path string to your specific resources directory.
    java.net.URL url = getClass().getResource("/resources/images/Apple.png");
    this.setIconImage(java.awt.Toolkit.getDefaultToolkit().getImage(url));
}
catch (java.lang.NullPointerException ex) {
    // Do what you want with caught exception.
    ex.printStackTrace();
}

Example #4:

try {
    /* For a Form's title bar icon.... To be used in a distributive JAR. 
       Can be used to also display an animated gif for the Form's Title 
       bar icon but only the first gif frame is utilized.         */
    // Be sure to set the path string to your specific resources directory.
    java.net.URL url = getClass().getResource("/resources/images/Apple.png");
    Image image = ImageIO.read(url);
    this.setIconImage(image);
}
catch (IOException ex) {
    // Do what you want with caught exception.
    ex.printStackTrace();
}

Don't even bother with Examples #1 and #2, they now just remain here for reference. Just use either Example #3 or Example #4. Both will work in the IDE or a distributive JAR file.

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
  • I have to say I've already tried similar things. Good work tho. I've found the solution. – devsimsek May 24 '22 at 12:03
  • Both those examples above will fail for a Jar, as resources inside a Jar are no longer `File` objects. The good news is though, that both methods will accept a (much more versatile) URL which `getResource` *does* provide. – Andrew Thompson May 27 '22 at 02:12
0

Solution; Everything works for windows but I am using Mac :D So I started to look around Taskbar class comes with awt package and found the solution (Thanks to flohall)

try {
    var image = new ImageIcon(Objects.requireNonNull(Main.class.getResource("/AppIcon.png")));
    frame.setIconImage(image.getImage());
    if (System.getProperty("os.name").startsWith("Mac") || System.getProperty("os.name").startsWith("Darwin")) {
        Taskbar taskbar = Taskbar.getTaskbar();
        try {
            taskbar.setIconImage(image.getImage());
        } catch (final UnsupportedOperationException e) {
            System.out.println("Can't set taskbar icon.");
        } catch (final SecurityException e) {
            System.out.println("Warning. Can't set taskbar icon due to security exceptions.");
        }
    }
} catch (NullPointerException e) {
    e.printStackTrace();
}

So we are telling the taskbar to change its icon using built-in awt Taskbar class on taskbar.setIconImage(image.getImage());. And that solves most of the things I've needed for.

devsimsek
  • 13
  • 1
  • 6