Setting the default application icon image in Java swing on OS X
Asked Answered
B

6

14

I'm trying to set the icon image for a Jar file:

setIconImage(new ImageIcon(getClass().getResource("logo.png")).getImage());

When running in Mac OS X 10.7.4 I get the following error:

Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextGetCTM: invalid context 0x0
Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextSetBaseCTM: invalid context 0x0
Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextGetCTM: invalid context 0x0
Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextSetBaseCTM: invalid context 0x0
Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextGetCTM: invalid context 0x0
Jun 28 15:21:40 (my dhcp) java[73383] <Error>: CGContextSetBaseCTM: invalid context 0x0
Blossom answered 28/6, 2012 at 22:24 Comment(11)
Where is the image located? Use getResource() to load the image, ie: getClass().getClassLoader().getResource("logo.png")Griffy
The same error appears when I do this.Blossom
Make sure the URL returned by getResource() is not null.Griffy
It seems like it has been broken since java se 6.Bannon
If that functionality is broken, then how can I set the icon image?Blossom
you are trying to set the Dock icon? or the Application menubar Icon?Bannon
The dock icon, which should be the same icon as the file you double click to open the program, and also the same as the icon that appears when you cmd+tab.Blossom
Please edit your question to include these requirements.Infamy
See also Apple's Java Development Guide for Mac.Esbensen
Does this answer your question? How do you change the Dock Icon of a Java program?Circumspection
A better answer that works on JDK 9+ is provided here https://mcmap.net/q/128856/-how-do-you-change-the-dock-icon-of-a-java-programCircumspection
T
31

setIconImage does not set the jar icon. It will set the icon for what the minimized window for that JFrame will look like. The jar icon (which controls the finder icon and the dock application icon) cannot be set in the jar file itself. You just get the default icon provided by the OS. You will need to wrap it using something like JarBundler for OS X or Launch4J for Windows.

You can set the application dock icon while your application is running, see com.apple.eawt.Application.setDockIconImage. It isn't perfect though, because when you double-click on your jar, it starts up in the dock using the generic java icon and only switches to your custom icon after a bounce or two when the java code starts running. Also, I don't think it would set the dock icon for an jar which isn't running (not that you can drag a jar file into the dock anyway - doesn't seem to work for me).

Here's some code that demonstrates the different images you can set:

import com.apple.eawt.Application;
import javax.swing.*;

class SetIcon extends JFrame {

    SetIcon() {
        setIconImage(new ImageIcon("doc.png").getImage());
        Application.getApplication().setDockIconImage(
            new ImageIcon("app.png").getImage());
    }

    public static void main(String args[]) {
        SetIcon s = new SetIcon();
        s.setVisible(true);
    }
}
Trochee answered 1/7, 2012 at 4:22 Comment(8)
Thanks, where can I download the Application class?Blossom
It comes installed on every Mac.Trochee
+1 for com.apple.eawt.Application, which I'd previously overlooked.Infamy
Thanks! This solved my problem. P.S. I needed to do: Application.getApplication().setDockIconImage(new ImageIcon(getClass().getResource("/logo.png")).getImage());Blossom
FWIW, you might need to be able to build your JAR on a non-mac. I got the interfaces for Apple's Java extensions here: developer.apple.com/library/mac/#/legacy/mac/library/samplecode/… at some point in the past. Note that the site says that documentation is out-of-date and I was unable to find a .jar to download. Good thing I have it in svn!Oxendine
com.apple.eawt.Application.setDockIconImage is now a dead link.. any ideas on where to look for this in 2015?Northwestwards
To elaborate here, it appears that in mac, when you run a java app, there are two "icons" at play, as it were. The java process itself, as a whole, by default gets one icon (the java cpu), and then new windows that you create, each new window has "its own icon" that is apparently not even visible until you minimize that window. So be careful which icon you set, this answer describes how to affect the "main" icon, which is apparently always visible. Weird.Edgy
The link for the "com.apple.eawt.Application.setDockIconImage" is gone -> The page you’re looking for can’t be found.Johannessen
P
10

Just to add my final solution for adding a MacOSX Dock icon in a pure-java application:

public boolean exists(String className)
{
    try {
        Class.forName( className, false, null );
        return true;
    }
    catch (ClassNotFoundException exception) {
        return false;
    }
}

public void setIcon( BufferedImage icn )
{
    if ( exists( "com.apple.eawt.Application" ) )
    {
        com.apple.eawt.Application.getApplication().setDockIconImage( icn );
    }
}

This silently ensures the class is available and the executes the setDockIconImage() method. Works very well for me and it does not interfere with other platforms.

Palmetto answered 28/6, 2012 at 22:24 Comment(1)
@Edgy of course that is an option, however this check ensures that setDockIconImage() can be safely executed.Palmetto
I
6

You can place your .icns file in the application bundle's Contents/Resources directory and reference it in your Info.plist file. For example, a file named ApplicationName.icns would be referenced by a <dict> entry of this form:

<key>CFBundleIconFile</key>
<string>ApplicationName.icns</string>

Some related details are mentioned here.

Infamy answered 29/6, 2012 at 0:32 Comment(2)
Is there any way of accomplishing this without bundling it as an .app? We chose to develop this technology on Java so that we could distribute one file to all users regardless of platform.Blossom
You can distribute a JAR-with-manifest or use java-web-start, but you'll get a (different) generic icon for each.Infamy
A
5

java -Xdock:icon=/path/myIcon.png myApp

Adduct answered 3/8, 2016 at 2:5 Comment(1)
This works fantastically, as long as you're on a Mac (other platforms will bomb out, unfortunately).Citadel
Y
1

as i have gone through your error its related to MacOS jdk which has started appearing after upgrade to 10.7.4

go through this if this helps you :

Yen answered 1/7, 2012 at 17:47 Comment(0)
C
1

A Java 9+ solution:

Taskbar.getTaskbar().setIconImage(myImage);

... or for projects that still need to compile against Java 8...

/**
 * Use reflection to attempt to set the taskbar icon using Java 9+
 */
public void setTaskbarIcon(Image image) {
    try {
        Class taskbar = Class.forName("java.awt.Taskbar");
        Method getTaskbar = taskbar.getDeclaredMethod("getTaskbar");
        Object instance = getTaskbar.invoke(taskbar);
        Method setIconImage = instance.getClass().getDeclaredMethod("setIconImage", Image.class);
        setIconImage.invoke(instance, image);
    } catch (Throwable t) {
        t.printStackTrace();
    }
}

This still suffers the limitations explained in other posts (e.g. startup icon is incorrect) as well as the limitation of the icon resolution not using an multidimensional .icns file, but for many cases, this will be better than the generic Java icon. :)

Citadel answered 13/7, 2022 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.