Java, Mac

Java 6.0 のタスクトレイサポート – Mac では?

Java 6.0 – Mustang では Windows のタスクトレイ制御をサポートするクラスが追加されているらしい。
わんこ日記 – What's cool in AWT on Java SE 6 (Mustang)

API はこちら。
Class SystemTray

先日 PowerPC 向けにも Java 6.0 の Developer Preview が出たので Mac OS X でサポートされるのか確認してみた。
サンプルコードは API リファレンスに載っているので簡単。
できる限りシンプルに書いてみたコードはこんな感じ。

public class SystemTrayTest {
public static void main(String[] args) throws Exception {
java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();
if(tray.isSupported()){
java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(new javax.swing.ImageIcon(SystemTrayTest.class.getResource("images/samurai64.gif")).getImage());
java.awt.PopupMenu popup = new java.awt.PopupMenu();
popup.add("menu1");
popup.add("menu2");
trayIcon.setPopupMenu(popup);
tray.add(trayIcon);
Thread.sleep(100000);
}
}
}

試してみたらちゃんとサポートされているみたい。Dockに表示されるかと思ったけどメニューバーに表示された。

メニューバーに表示されたアイコン。

アイコンが大きすぎてはみ出してしまったけど、
Icon#setImageAutoSize(true);
でフィットしてくれるみたい。

public class SystemTrayTest {
public static void main(String[] args) throws Exception {
java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();
if(tray.isSupported()){
java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(new javax.swing.ImageIcon(SystemTrayTest.class.getResource("images/samurai64.gif")).getImage());
trayIcon.setImageAutoSize(true);
java.awt.PopupMenu popup = new java.awt.PopupMenu();
popup.add("menu1");
popup.add("menu2");
trayIcon.setPopupMenu(popup);
tray.add(trayIcon);
Thread.sleep(100000);
}
}
}


ちゃんと収まったアイコン。

Windows だとカラフルなアイコンがタスクトレイに並ぶのが当たり前だけど、Mac OS X で違和感なく納めるにはモノクロのアイコンを用意しておいた方がよさそう。
Mac かどうかの判定はこんな感じ。

  public final static boolean mac = -1 != System.getProperty("os.name").toLowerCase().indexOf("mac");
public static boolean isMac(){
return mac;
}

SystemTray.isSupported() で仮想マシンがシステムトレイをサポートしているか調べることが出来ますが、Java6.0 以前では isSupported() メソッドを呼び出す前に NoClassDefFoundError が発生してしまいます。
Java 6.0 以前でも動作させる可能性のあるプログラムでは NoClassDefFoundError を防ぐため、SystemTray クラスが存在するか確認してから、SystemTray クラスを操作するクラスを呼び出すような工夫が必要です。
こんな感じ↓

public class SystemTrayTest1 {
public static void main(String args[])throws Exception{
try {
Class.forName("java.awt.SystemTray");
SystemTrayTest.main(args);
} catch (ClassNotFoundException ex) {
// do nothing
}
}
}