SystemTray icon on Mac OSX problem

Challenge

I want to have an icon in the SystemTray of Mac in order to sync some calendar stuff.

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package nl.ivonet.systemtray;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class SystemTrayApp extends JFrame {


public SystemTrayApp() throws Exception {
final SystemTray systemTray = SystemTray.getSystemTray();
final PopupMenu popupMenu = new PopupMenu();

// final Image image = Toolkit.getDefaultToolkit()
// .getImage(this.getClass()
// .getResource("/myicon.png"));

Dimension size = systemTray.getTrayIconSize();
BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.GREEN);
graphics.fillRect(0, 0, size.width, size.height);


final TrayIcon trayIcon = new TrayIcon(image, "Tooltip", popupMenu);
trayIcon.setImageAutoSize(true);

final MenuItem menuItem = new MenuItem("Menu Item");
menuItem.addActionListener(e -> System.out.println("Let me do some real work!"));

final MenuItem quit = new MenuItem("Quit");
quit.addActionListener(e -> System.exit(0));

popupMenu.add(menuItem);
popupMenu.add(quit);


systemTray.add(trayIcon);

setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(false);
}

public static void main(final String[] args) throws Exception {
new SystemTrayApp();
}
}

Solution

Extra information

I came to this solution via this code snippet Before finding this snippet I have tried a variety of options, namely: ScalaFx, JavaFx, Swt, com.dorkbox.SystemTray.

ScalaFx/JavaFx can handle native menu’s via the menuBar.setUseSystemMenuBar(true);. This only puts the menubar on the left side, and disappears when I switch between applications.

When using Swt or com.dorkbox.SystemTray I do manage to have an icon in the systemtray, but the look and feel is not the same as any native app does.

In this example you will get a green square in the screen because then the code is independent from external images. I have included a comment for getting an image from disk.

Remove Doc Icon and from cmd+tab

If you want to remove the cmd+tap java item still visible just add -Dapple.awt.UIElement="true" to your startup script as a VM argument, or you can set a property in the Info.plist as:

1
2
3
4
5
<key>Properties</key>
<dict>
<key>apple.awt.UIElement</key>
<string>true</string>
</dict>

Also you can use System.setProperty("apple.awt.UIElement", "true"); in your code but strangely it does not seem to work for me. If you do know how to make that work please leave a comment below.