JOptionPaneの憂鬱
javax.swing.JOptionPaneは.NETでいう所のSystem.Windows.Forms.MessageBoxと同等の機能を実現するためのクラスだ。
使い方として一番簡単なのはスタティックなメソッドを使ってダイアログを表示することだ。
JOptionPane.showMessageDialog(null, "メッセージ", "タイトル", JOptionPane.INFORMATION_MESSAGE);
- 実行結果
この段階では非常に気に入らない。(というか悪いが使い物にならない)
- 日本語フォントのレンダリングが汚い
英語フォントはまだ我慢できるが、Javaのデフォルトの日本語フォントのレンダリングははっきり言って酷過ぎる。これはJ2SE6であれば起動オプションでアンチエイリアスを有効にできるらしいので、試してみる。
-Dawt.useSystemAAFontSettings=on
- 実行結果
これで見た目はかなりきれいになった。(今回はJ2SE6で実行しているが、O/SのClearTypeによるサブピクセルのアンチエイリアスまで有効になることを確認できた。J2SE5ではどう表示されるのかの検証は行っていない)
しかし正直な所、起動オプションでしかこのオプションをオンにできないのは困る。アプリケーション内部から変更できないものだろうか
- アイコンやボタンがO/S標準のものではない
Javaは標準ではO/Sに依らないテーマ"Metal"を使用するため、JOptionPaneで使用されるアイコンやボタンもMetal独自のものである。(私自身はMetalは嫌いではないが)これをWindowsの標準のものにしたい場合は以下のようにコードの冒頭にルックアンドフィールを交換するコードを追加する。
try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); JOptionPane.showMessageDialog(null, "メッセージ", "タイトル", JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { e.printStackTrace(); }
- 実行結果
- トップ階層に表示されない
メッセージダイアログといえばインタフェースを操作するユーザに対して何かを促すための表示される訳で、まずはデスクトップの一番上の階層に表示されて欲しいのだが、JOptionPaineのスタティックなメソッドにはそのようなオプションは無い。従っていわゆる"TopMost"には表示されない。実はこれが一番嫌だったりする。
この点は昔から言われていたことであり実はJ2SE5からのSwingにおけるコンテナ階層にはそのためのメソッドが追加されているのだ。
java.awt.Window#setAlwaysOnTop (Java Platform SE 6)
なのに、JOptionPaneではこのメソッドを使っておらず、従ってJOptionPaneはそのままではTopMost表示ができない。しかし、幸いなことにJOptionPaneクラスは内部でJDialogクラスを生成するメソッドがあり、そこでsetAlwaysOnTopを適用することでTopMostに表示するJOptionPaneを実現できる。
try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); JOptionPane opane = new JOptionPane("メッセージ", JOptionPane.INFORMATION_MESSAGE); JDialog dialog = opane.createDialog("タイトル"); dialog.setAlwaysOnTop(true); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); } catch (Exception e) { e.printStackTrace(); }
- 実行結果
Javaのアイコンが付いてしまったが、これでやっと期待通りのメッセージダイアログとなった。
とまあ、一般的に利用頻度が最も高いと思われる仕様のメッセージダイアログを表示するまでにここまで手を入れなければならないってのが憂鬱なのだった。
サポートされる全てのO/S上で共通のGUIを、という壮大な目的を持つツールキットなので仕方が無い所はあるが、プラットホーム縛りをする代わりにいろいろなルールをO/Sに合致させるという仕組みが欲しいと思った。