1

I read a lot of answers to change the default java coffee icon shown in image (OS: MacOS) (like using JFrame.setIconImage()), but not able to do it.

If someone was successfully able to change it. Could you give step-by-step solution on how you were able to do it, possibly with explanation?

enter image description here

Arjun Chaudhary
  • 2,373
  • 2
  • 19
  • 36
  • 1
    You use to be able to use `com.apple.eawt.Application`, but since Apple Java 6, I think you now have to use the `-Xdock:icon=/path/myIcon.png` command line argument [all shown here](https://stackoverflow.com/questions/6006173/how-do-you-change-the-dock-icon-of-a-java-program) and [here](https://alvinalexander.com/apple/mac/java-mac-native-look/dock_icon.shtml). The only other choice to build a app bundle – MadProgrammer May 18 '18 at 04:21

2 Answers2

1

So, I did a really quick test using...

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JLabel;
import com.apple.eawt.Application;

public class Test {

    public static void main(String[] args) {
        try {
            Application application = Application.getApplication();
            application.setDockIconImage(ImageIO.read(Test.class.getResource("/javaapplication163/bunny.jpg")));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        public TestPane() {
            add(new JLabel("Hello"));
        }

    }

}

And it showed...

Hello Bunny

Neat ... however, this will only compile and run on a Mac.

A "typical" solution to this would be to use reflection to try and load the com.apple.eawt.Application at run time, something like...

try {
    Class appClass = Class.forName("com.apple.eawt.Application");
    Class params[] = new Class[]{Image.class};

    Method getApplication = appClass.getMethod("getApplication");
    Object application = getApplication.invoke(appClass);
    Method setDockIconImage = appClass.getMethod("setDockIconImage", params);
    setDockIconImage.invoke(application, ImageIO.read(Test.class.getResource("/javaapplication163/bunny.jpg")));

} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException | IOException ex) {
    ex.printStackTrace();
}

But this is some what error prone and messy, not to mention a complete pain in the ... code to maintain.

So, then I thought I might try using the command line parameters, as demonstrated at The dock icon...

-Xdock:name="Hello bunny" -Xdock:icon=/path/to/bunny.jpg

which also worked.

While I kind of prefer this solution, it does mean that the icon needs to be externalised from Jar, which is kind of a pain, and you'll probably need to supply a full working path.

If I was to generate a App bundle for my project, I'd probably follow this, but if I was just deploying a Jar, I might be tempted to use one of the previous methods

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I did the first and tested with Java 1.7 and 1.8 and it worked. But, just wondering what will happen with client's running lower java versions (whose rt.jar doesn't contain com.apple.eawt.Application), would it throw error like Application class not found or what? – Arjun Chaudhary May 18 '18 at 06:37
  • 2
    They should upgrade ;) - `com.apple.eawt.Application` has been provided by Apple, I certainly know it was available in Java 6 – MadProgrammer May 18 '18 at 06:38
0

This solution works with Java 10 where com.apple.eawt.Application no longer works. It doesn't require the command line.

import java.awt.Taskbar;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

Taskbar taskbar=Taskbar.getTaskbar();
BufferedImage image = ImageIO.read(getClass().getResource("/path/icon.png"));
taskbar.setIconImage(image);

If you supply the relative path to icon.png then this will be included in the jar file. The icon will also appear in dialog boxes.

You will also want to use code for the About, Preferences and Quit menu items previously supplied by com.apple.eawt.Application and you can find that in Alvin Alexander's page at Java 10: How to implement About, Preferences, and Quit menu items on MacOS

stevem
  • 111
  • 1