技術文献: テクニカルノート
Search
高度な検索
ログイン | ご入会
目次
Macintosh クライアントの検出
Cocoa-Java の使用
ピュア JAVA で互換性を保つためのヒント
Mac OS X、Swing、Aqua
JDesktopPanes とマルチドキュメントインタフェース
Swing のメニューとメニュー項目
コンテキストメニュー
コンポーネントの配置と描画
スクロールバー付きのウィンドウ(JScrollPanes を使用)
Aqua のファイルダイアログ
Macintosh 固有の仕立て
Macintosh のメニューバーの使用
ウィンドウメニュー
アプリケーションメニュー
アプリケーションメニューのカスタマイズ
追加の MRJ ハンドラ
Java アプリケーションの起動
Dock アイコンの設定
要約
ダウンロード
ADC連絡先
このテクニカルノートは、Mac OS X 上の
Java アプリケーションにおいて「完全な
Macintosh 体験」を提供するために Mac OS
X の Java 開発者が利用できる技術と方法につ
いて説明します。 また、既存のアプリケー
ションをほかのプラットフォームからできる
だけスムーズに Mac OS X に移植しようとし
ている Java 開発者も対象としています。
以下では、Java アプリケーションがより良き
「Mac OS X 市民」になるよう、Java 環境特
有の外観と動作を変更するために開発者がで
きることを取り上げます。 プロパティファイ
ルに簡単な変更を加えれば済む場合もあれ
ば、より適切な Java API を選択したり、UI
に対してプログラム上で明示的に変更を加え
なければならない場合もあります。これらの
変更のほとんどは、ほかのプラットフォーム
でもアプリケーションの動作に悪い影響を及
ぼさずに行えるので、Java が提供する移植性
を維持できます。
本書で説明する内容は、Mac OS X 10.1.3 で
Java 1.3.1 アップデート以降、および現在の
開発ツールを使っている場合に適用されま
す。
[2002 年 5 月 23 日]
Macintosh クライアントの検出
本テクニカルノートのいくつかの推奨事項の中では、条件に応じて、API 呼び出しまたは UI コンポーネントの配置を行うことを推奨しています。ア
プリケーションを実行している OS を知る最も一般的で直観的な方法は、System プロパティである os.name を調べることです。しかし、この方
法では、String ベースの結果を正しく解析する必要があるため、アップルがこのプロパティの設定方法を変更した場合は特に、エラーが生じやす
くなります。Java クライアントが Macintosh かどうかを知るより信頼性の高い、より簡単な方法は、mrj.version プロパティを調べることで
す。
System.getProperty("mrj.version");
このプロパティは、どの Mac OS X システムでも Java 仮想マシンによって自動的に設定されます。テスト方法は簡単です。返される
String がヌ
ルでなければ、Macintosh 上で動作していることになります。これは、Macintosh 上で動作していることを確認する必要がある場合に推奨される方法
です。
また、以降で取り上げる推奨事項の多くは、アップルの Aqua インタフェースに関するものです。つまり、Swing の Java(Metal)または Motif の
ルックアンドフィールには、有効または無効にしたくないかもしれないものも含まれています。Aqua が現在アクティブなルックアンドフィールであ
ることを確認する一番良い方法は、
UIManager.getSystemLookAndFeelClassName()
を呼び出して、その結果を次の結果と比較することです。
UIManager.getLookAndFeel().getClass().getName()
これを、mrj.version のチェックと組み合わせることで、現在 Aqua を使っているかどうかを抽象的かつ適切な方法で調べることができます
(最初に Macintosh 上で動作しているかどうかを調べ、次にシステムのルックアンドフィールが現在のルックアンドフィールと同じかどうかを調べ
ます)。この方法なら、アップルが Aqua のルックアンドフィールに使っているクラスの名前を知っている必要がないので、アップルがルックアンド
フィールのクラスの名前またはパッケージを変更したとしても、ロジックが必ず正しく動作することが保証されます。
先頭に戻る
Cocoa-Java の使用
Java アプリケーションを可能な限り Mac 風にする最も速くて最も明白な方法は、Cocoa-Java を使ってアプリケーションを作成することです。これ
により、コンポーネントの推奨の配置やサイズにいたるまで、Interface Builder を使って、WYSIWYG により UI を手早く設計できるようになりま
す。 Cocoa-Java のコントロールは、ムービーの簡単な埋め込みや真のフローティングツールバーウィンドウなど、Swing や AWT が提供していない
機能を提供します。
もちろん、Cocoa-Java を使えば、移植性が高いという Java アプリケーションの特性は失われてしまいます。 このテクニカルノート では、ピュア
Java アプリケーションに重点を置いていますが、 Cocoa-Java は言及するに値します。なぜなら、Cocoa-Java をユーザインタフェースに使用する
場合、アプリケーションにおいて Cocoa ベースのコンポーネントと Carbon ベースのコンポーネントを混在させないことが重要だからです。Java に
関係するものとしては、次のものがあります。
Java イベントを含む、Swing / AWT のコンポーネント
QuickTime for Java のコンポーネント
JDirect 呼び出し
一緒に使用できない主な理由は、Carbon と Cocoa では異なる実行ループを使っており、同じアプリケーションで使用すると衝突が生じるからで
す。QuickTime for Java が含まれているのが残念なようにも思えますが、Macintosh アプリケーションが必要とする簡単な QuickTime 機能(各種メ
ディアファイルを開く、再生するなど)のほとんどは
com.apple.cocoa.application.NSMovie クラスにより利用できます。
以上をふまえた上で、本文書の残りの部分では、Swing ベースおよび AWT ベースのピュア Java アプリケーションについて説明します。
先頭に戻る
ピュア JAVA で互換性を保つためのヒント
このテクニカルノートの前半では、ピュア Java アプリケーションにおいて可能な簡単な変更または選択について説明します。これらの変更は、Mac
固有の API とプロパティに関係するというより、1つのコードベースで Mac OS X とほかのプラットフォームを同じようにサポートするために頭に入
れておかなければならない事柄です。
先頭に戻る
Mac OS X、Swing、Aqua
Mac OS X の Aqua ユーザインタフェースは、Java 自身のユーザインタフェースやほかのプラットフォームのユーザインタフェースとは大きく異な
ります。 Swing に対応した Aqua のプラガブルなルックアンドフィールが提供されていることは明らかに、Swing アプリケーションをより Mac 風に
する上での強力な手段です。また、利用するために何の努力も要りません。つまり、コードを明示的な変更をしなくても、Mac OS X は、Swing アプ
リケーションに対して、起動時にデフォルトで Aqua のルックアンドフィールを採用します。
ルックアンドフィールとして Aqua が提供されていることから導き出される 1 つめの簡単な指針は、「Java アプリケーションの UI には Swing を使
う」です。 Swing にはそのままで、AWT にまさる多数の基本的なメリットがあります。 そして、Aqua を利用することによって、AWT が提供する
唯一ともいえるメリットもなくなります。 また、軽量と重量のコンポーネントを混在させると、パフォーマンスの上で、また描画の際に、アプリケー
ションに望ましくない影響を及ぼす可能性があります。
一番良いのは、Swing を使ってアプリケーションを設計するだけでなく、Java コードの中で明示的にルックアンドフィールの設定をしないようにす
ることです。 そして、別のプラットフォーム用にアプリケーションの ルックアンドフィールを変更する必要がある場合
は、swing.defaultlaf という Java プロパティをオーバーライドするのが よりエレガントでより簡単な方法です。Mac OS X で Swing ア
プリケーションのルックアンドフィールを設定する方法の詳細については、Technical Q&A 1059 を参照してください。
Aqua の外観は自動的に採用されますが、 完全な Macintosh 体験を提供するために、依然として開発者に委ねられる領域および作業があります。 こ
のテクニカルノートにおける指針の多くは、アップル開発者のための Web サイトにある Aqua Human Interface Guidelines (PDF) に準拠していま
す。次に、このガイドラインで取り上げられているいくつかの細かいながらも重要な指針の例をいくつか示します。
スクロールバーを常に表示されている状態にする (以下を参照)
ポップアップメニューの項目選択と設計(JComboBox )
メニュー項目をグレー表示にする(無効にする)
メニュー項目用予約済みキーボードショートカット
Macintosh におけるユーザインタフェースの設計に関する詳細についてはこの文書を参照するよう強くお勧めします。我々も参照しています。
先頭に戻る
JDesktopPanes とマルチドキュメントインタフェース
ほとんどの Macintosh アプリケーションは、多数の、独立したフローティングウィンドウで構成されます。これらのウィンドウは、同じアプリケー
ションのコンテキストにはありますが、スクリーン上でアプリケーションウィンドウの境界として機能する親ウィンドウには含まれません。これは、
Macintosh がほかのプラットフォームと異なっている点でもあり、また、複数のウィンドウを持つアプリケーションを設計するときに考慮すべき点で
もあります。
このため、絶対に必要という場合を除き、アプリケーションのメインの UI に、制約のある、親ウィンドウを持つ MDI モデルを採用する
javax.swing.JDesktopPane クラスの使用は推奨しません。 例外は、フォーカスの有無に関わらず、常にアプリケーション内のほかの
すべてのウィンドウよりも前面に表示される、フローティングツールバーのような要素(Swing では、「内部ユーティリティウィンドウ」と呼ばれて
います)を必要とする Java アプリケーションです。現在 Java には、JDesktopPane を使う以外にこれを提供する方法はありません。JBuilder
または LimeWire のような Java アプリケーションが利用しているのと同じような、単一の動的コンテナを持つ、よりプラットフォームに依存しない
UI の設計を考えるのもよいかもしれません。
MDI ベースのアプリケーションをほかのプラットフォームから Macintosh に 移植するときに、 階層ペイン構造なしに、既存のユーザ体験を提供する
のが不可能だとわかる場合があります。その場合は、UI をそのままにしておく方がよいかもしれません。決めるのは開発者です。
付言として、Cocoa-Java を使って、ツールバー形式とパレット形式のコントロールを実装できます。ただし、Cocoa-Java を使用すれば、移植性は
失われてしまい、Swing または AWT のコンポーネントは使えなくなります。
一般的には、アプリケーションにおいて JDesktopPane を使うことが、(独立した複数のフローティングウィンドウを持つ Mac OS の典型的
な)アプリケーションに、複数のウィンドウを制御できる単一のメニューバーを提供する唯一の方法であること、また、これが、MDI ベースの UI を
選択する主な理由になりえることもわかっています。以下の節では、MDI に代わる方法、および Swing のマルチフレームに関する問題の解決方法に
ついて説明します。
先頭に戻る
Swing のメニューとメニュー項目
クロスプラットフォーム対応の Java UI の開発においてもう 1 つ厄介なのは、メニュー項目のショートカットと外観がプラットフォームによって異な
ることです。残念ながら Java プログラマの多くは、開発時点で対象となっているプラットフォームだけを念頭に置いてアプリケーションを記述し、
コードの中で明示的に修飾子またはトリガを指定します。そのため、プラットフォームに対応した正しいトリガが誤って解釈される危険が生まれるだ
けでなく、アプリケーションをほかのプラットフォームに移植するのが難しくなります。
幸い、任意のプラットフォームで、これらのアクションを作成するより洗練された解決方法があります。しかもこの方法なら移植性があります。
メニューショートカット: メニューショートカットは多くの場合、開発者が
java.awt.KeyStroke を使って明示的に指定することによって
設定されます。この方法では、異なるショートカット修飾子を持つ別のプラットフォームに移植するときに、新しいクライアントプラットフォームで
条件に応じて新たな
KeyStroke を作成する必要があるので複雑になります。これを解決するには、次の AWT メソッドを使います。
java.awt.Toolkit.getMenuShortcutKeyMask()
このメソッドを呼び出すと、現在のプラットフォームの Toolkit の実装が適切なマスクを返します。この呼び出し 1 つで、現在のプラットフォームを
調べ、その後、どれが正しいキーかを判断してくれます。リスト 1 にこれを示します。
リスト 1 getMenuShortcutKeyMask() を使用したメニューショートカットの簡素化
JMenuItem jmi = new JMenuItem("Copy");
/*
// TN2042 で紹介する方法を知る前に、自分が実行できたのはこれだけ
String vers = System.getProperty("os.name").toLowerCase();
if (s.indexOf("windows") != -1) {
jmi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.CTRL_MASK));
} else if (s.indexOf("mac") != -1) {
jmi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.META_MASK));
}
*/
// この 1 行は、C がコピーのショートカットであるすべてのプラットフォームで有効
jmi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
Macintosh 上で行われる一般的なアクションのほとんどに、Command キーを唯一の修飾子としてではないにしろ少なくとも修飾子の 1 つとして使
う、対応するキーボードショートカットがあります。残念ながら、ほかのプラットフォームにはこれほどの一貫性はなく、たとえば、Alt キーを使う
キーボードショートカットもあるでしょう。上記の呼び出しは、一般的なマスクを 1 つ返すだけなので、ホストのプラットフォームを基準にした条件
に基づいてショートカットキーを設定する必要があるかもしれません。Macintosh で対応するキーボードショートカットのほとんどは Command
キーを使っているため、アプリケーションを Windows に移植しようとしていて、Windows 上でアクションを正しく再現できるかを心配している場
合は、移植は少し楽でしょう。最も一般的な予約済みのショートカットの信頼できるリストについては、Aqua Human Interface Guidelines の
keyboard equivalents の節を参照してください。
ALT_MASK 修飾子は、Macintosh 上では Option キーと解釈されるので、ALT_MASK を getMenuShortcutKeyMask() と組み合わ
せて使えば、Windows 用に設定した Ctrl + Alt のマスクはそのまま Cmd + Opt のマスクになります。
メニューアクセスキー: ほかのプラットフォームとは異なり、Mac OS X (Aqua)は、メニューアクセスキー、つまり メニュー(Alt キーを使用)
とメニュー項目(親メニューを開いているときに表示される)のための単一キーによるショートカットを提供しません。 アクセスキーは通常、メ
ニュー(またはメニュー項目)の名前の中で 1 文字にだけ下線が付いて表示されます。 これまで Macintosh アプリケーションでメニューアクセス
キーが使用されたことはありませんが、可能ならばGUI を構築するときに、コードの中で条件に応じて setMnemonics() メソッドを呼び出す
など、プラットフォームに応じてアクセスキーを利用することを推奨します。
メニュー項目のアイコン: アクセスキーと同様、Swing によりメニュー項目でアイコンも利用できます(Mac OS X 上で機能します)が、Aqua's
Human Interface Guidelines の標準には含まれていません。Macintosh の Java アプリケーションを、Carbon アプリケーションまたは Cocoa アプ
リケーションのような外観にするためには、これらのアイコンをプラットフォームに応じて適用するとよいでしょう。
アプリケーションがどのプラットフォーム上で動作しているかを調べる方法の詳細については、Macintosh クライアントの検出 の節を参照してくだ
さい。
先頭に戻る
コンテキストメニュー
ほとんどのプラットフォームは、なんらかの形でコンテキストメニューをサポートしているので、Java アプリケーションにコンテキストメニューを
含めることには何の問題もありません(Java ではこの種のメニューを PopupMenu と呼び、Aqua ではこの用語を、Java で JComboBox と呼
んでいるものに対して使います)。しかし、コンテキストメニューが、どのプラットフォームでも同じ方法で同じタイミングで、明示的にトリガされ
ると考えているとすれば、プラットフォーム間での移植は、実際には複雑かもしれません。たとえば、Windows においては、右のマウスボタンがコ
ンテキストメニューの標準のトリガです。標準の Macintoshのマウス(1 つボタンのマウス)では、コンテキストメニューは Control + クリックで表
示されます。
注意:
サードパーティ製の Macintosh 用マルチボタンマウスが問題になることはないでしょう。そのようなマウスの右ボタン
は通常、ドライバにより Control + クリックに対応付けられているからです。
これら 2 つは大きく異なるので、上記のメニューのコード例のように、断片的で、条件分岐するコードになるでしょう。 ただし、マウスクリックだ
けは共通です。プログラムに、プラットフォームに関係なく、コンテキストメニューのトリガを正しく解釈させるためには、次のインスタンスメソッ
ドを使って、AWT に解釈をさせます。
java.awt.event.MouseEvent.isPopupTrigger()
このメソッドは、MouseEvent の中で定義します。なぜなら任意のコンポーネントに対する
ネントを対象とする
MouseEvent が検出されたとき、そのコンポー
MouseListener でコンテキストメニューをアクティブにするからです。ここで大事なのは、正しいイベントを検出する方
法とタイミングです。
リスト 2 isPopupTrigger() を使用してコンテキストメニューの起動を検出
JLabel label = new JLabel("I have a popup menu!");
label.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
evaluatePopup(e);
}
public void mouseReleased(MouseEvent e) {
evaluatePopup(e);
}
private void evaluatePopup(MouseEvent e) {
if (e.isPopupTrigger()) {
// ポップアップメニューを表示...
}
}
});
上記のコード例は、MOUSE_PRESSED イベントと MOUSE_RELEASED イベントの両方で
isPopupTrigger() をチェックしていま
す。なぜなら、 Macintosh では、ポップアップトリガは、MOUSE_PRESSED のときに設定され、 Windows では、MOUSE_RELEASED の
ときに設定されるからです。移植性を維持するには両方の場合に対応しなければなりません。
先頭に戻る
コンポーネントの配置と描画
Swing の UI は、ネスト構造になっているコンテナとコンポーネントを組み合わせることによって構築され、多くの場合複雑になります。1 つのプ
ラットフォームを対象に作業していると、開発者は、自分の UI の設計が、ほかのプラットフォーム上ではどのように見えるかという視点を簡単に見
失ってしまいます。言葉自体が示すとおり、ルックアンドフィールが異なるということは、見た目(ルック)と使い心地(フィール)が違うというこ
とです。プラットフォームが異なり、ルックアンドフィールが異なれば、フォントサイズ、ボタンのサイズと形状、背景色と前景色などすべてが変わ
り得ます。コンポーネントの配置、サイズ決めおよび描画に、抽象化されたメソッドや一般化されたメソッドを使うことが極めて重要なのはこのため
です。
レイアウトマネージャ: レイアウトマネージャを利用するのは、多くの開発者にとって、非常に簡単な作業かもしれませんが、多くのプログラマは、
明示的にコントロールの X と Y の座標を設定することによって、アプリケーションを微調整しようとします。 このようにして作成されたアプリケー
ションが、ある時点で、別のルックアンドフィール、別のプラットフォームで動作する場合、コンポーネントが、互いに重なって描画されたり、コン
テナの境界をはみ出したりなどひどい UI になる可能性があります。一般論として、座標を明示的に指定してボタンとコントロールを配置しても移植
性があると仮定するのは危険です。ルックアンドフィールが異なれば、コントロールのサイズの違いから、UI は突然、意図したものとはものとは全く
違って見える可能性があります。AWT のレイアウトマネージャは、抽象化された位置定数(GridLayout による相対的なグリッド座
標、BorderLayout による配置など)を使うことによってこの問題を解決します。これらのコントロールの正確な配置は、レイアウトマネー
ジャが、コンテナにおける各コンポーネントの相対的な配置を維持しながら、各コンポーネントのサイズを考慮して決定されます。
コンポーネントのサイズ: コンポーネントのサイズを明示的に設定するのも場合によっては、危険な習慣です。ルックアンドフィールごとに、フォン
トのスタイルとサイズが異なるかもしれないからです。これらのフォントサイズはほぼ確実に、テキストを含むコンポーネントの必要サイズに影響を
与えるでしょう。明示的にサイズ指定されたコンポーネントを、より大きなフォントサイズを持つ別のルックアンドフィールに移すと大きな問題を引
き起こす可能性があります。UI コンポーネントを、移植性を維持しながら、適正な最小サイズに保つ最も安全な方法は、ただ次のメソッドを呼び出す
ことです。
myComponent.setSize(myComponent.getPreferredSize());
ここで、myComponent は、対象とする UI コンポーネントオブジェクトです。ほとんどのレイアウトマネージャとコンテナは、コンポーネント
の推奨サイズを尊重するので、多くの場合この呼び出しは不要です。しかし、UI がより複雑になるに従い、多数の子コンポーネントを持つコンテナに
とって、この呼び出しは有用です。
コンポーネントの色: どのルックアンドフィールでも、すべてではないにしろ、ほとんどのコントロールで共通の色合いとスタイルを採用しているの
で、開発者は標準の UI クラスのルックアンドフィールに調和するカスタムのコンポーネントを作成しようという気になることもあるでしょう。これ
は完全に正当なことですが、不注意な開発者は、現在のルックアンドフィールに一致すると考える色を明示的に設定してしまうかもしれません。その
場合、ルックアンドフィールを変えると、コンテナのどこかにあるボタンが非常に見苦しくなることがあります。カスタムのコントロールとその他の
標準のコンポーネントとを確実に一致させる一番良い方法は、最適な色またはアイコンを UIManager クラスに問い合わせることです。一番良い
例は、標準の軽量コンポーネントをいくつか含んでいるけれども、露出した背景を、アプリケーションのその他のコンテナやウィンドウの背景に合う
ように描画する必要がある
Window オブジェクトでしょう。そのために、開発者は次のメソッドを呼び出します。
myPanel.setBackground(UIManager.getColor("window"))
これは、現在のルックアンドフィールにふさわしい色を返します。これらの標準メソッドを使うもう 1 つの利点は、これらの標準メソッドが、簡単に
は再現できない特殊な背景とアイコン(Aqua のコンテナとウィンドウに使うしま模様の背景など。これは、上記コードにより返されます)も提供し
ていることです。
先頭に戻る
スクロールバー付きのウィンドウ(JScrollPanes の使用)
Aqua Human Interface Guidelines が推奨する UI 設計の具体例の 1 つに、ウィンドウ内容のナビゲーションにスクロールバーを使うウィンドウがあ
ります。デフォルトでは、JFrame は、どのようにサイズ変更しても、スクロールバーが付きません。 フレームにおいて内容をスクロールできるよ
うにする一番簡単な方法は、フレームのコンポーネントを
JScrollPane の中に入れ、それを親フレームに追加することです。ただ
し、JScrollPane のデフォルトの動作では、縦方向と横方向のスクロールバーは必要な場合にのみ、つまりペインの内容全体が表示されていな
い場合にのみ表示されます。これは、いくつかのプラットフォームでも同じかもしれませんが、スクロール可能なウィンドウは、常にスクロールバー
を表示するよう推奨している Aqua Human Interface Guidelines に反することになります。この規定は、スクロールバーが必要に応じて表示された
り消えたりすることによって、ウィンドウの表示可能な領域が小さくなったり大きくなったりするという錯覚を起こすような、紛らわしい UI をなく
すためです。Java アプリケーションの中で JScrollPane を使う場合は、無効になっているときでも常にスクロールバーを表示するように
JScrollPane のスクロールバーポリシーを設定することを推奨します。リスト 3 は、標準の Java API を使ってこれを行う方法を示します。
リスト 3 Aqua Human Interface Guidelines に適合するように
JScrollBar ポリシーを設定
JScrollPane jsp = new JScrollPane();
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
AS_NEEDED (デフォルト)のポリシーは、ほかのプラットフォームでの動作により近いかもしれないので、ホストプラットフォームに応じてこれ
を行うようにすることはもちろん可能です。 このような変更は、UI の仕様が少ないほかのプラットフォームでは、まったく気付かれない場合もあり
ます。最終的に決めるのは開発者です。常に表示させる場合、JScrollPane の内容全体が表示されているときは、スクロールバーは単色で表示
され、スクローラーがないことに留意してください(身近な例として、Finder でウィンドウの動作を確かめてください)。
先頭に戻る
Aqua のファイルダイアログ
java.awt.FileDialog クラスと javax.swing.JFileChooser クラスは、Java アプリケーションのユーザのために、ファイ
ルシステムへの手早く簡単なアクセス手段を提供する 2 つの主要な機能です。JFileChooser の方が、より新しく、抽象化された、よりカスタ
マイズしやすいクラスで、旧式の、ネイティブ API から派生した AWT の FileDialog の後継にあたります。これらのクラスはそれぞれ他方に
はない利点を持っています。
一般的には、アプリケーションをできるだけネイティブの外観にするために、開発者は、AWT の
FileDialog クラスを使ってユーザにファイル
へのアクセス手段を提供することが推奨されています。これらの 2 つのクラスの違いは、Carbon アプリケーションと Cocoa アプリケーションの
ファイルダイアログでカラム形式のナビゲーションが使用される Mac OS X 上で Aqua を使用した場合には特に顕著です。このナビゲーション方式
は、AWT の
FileDialog により自動的に採用されるのに対し、Swing の JFileChooser は、典型的な Mac OS X アプリケーションのナ
ビゲーション方式とは異なる方式を使います。しかし、JFileChooser が持つ多数の機能上の利点の方が、推奨の方法よりも有用かもしれませ
ん。決めるのは開発者です。ダイアログがモーダルであり、常に、コンポーネントよりも前面に描画されるので、Swing アプリケーションに重量の
FileDialog を使っても、重大な影響が生じることはありません。
.pkg ファイルと .app ファイルの処理: Java アプリケーションの中で Mac OS X のアプリケーションバンドルとインストーラパッケージを扱う方
法にも考慮が必要です。.app ファイルと .pkg ファイルは、厳密にいえばディレクトリであり、JFileChooser または
FileDialog を使
う Java アプリケーションは最初はそのように認識し、不正なナビゲーションを許可します。 アップルでは、これらのクラスの両方に、.pkg インス
トールパッケージと .app バンドル(両方とも実際はディレクトリ)の処理方法を制御するのに使えるプロパティを提供しています。
FileDialog: AWT の FileDialog クラスでは、次のシステムランタイムプロパティを使って、.pkg ファイルと .app ファイルをナビ
ゲーション不可能なものとして処理するように設定できます。
com.apple.macos.use-file-dialog-packages
指定可能な値は、true (.pkg と .app をファイルとして処理)と
false (フォルダとして処理、デフォルトの動作)。このプロパティは、テク
ニカルノート 2031 で説明されているように、システムのランタイムプロパティのための標準の機能を使って設定でき、設定後はすべての
FileDialog インスタンスに適用されます。これにより開発者は、コードを変更することなく AWT ダイアログを Aqua に対応するように変更で
きます。アプリケーションにおいて、インスタンスごとに動作を変える必要がある場合には、実行時に、必要に応じて
System.setProperty() を使って、このプロパティを true または false に設定できます。または、インスタンスごと
にJFileChooser のクライアントプロパティを利用することもできます。
JFileChooser: JFileChooser の使用時、.app ファイルと .pkg ファイルの処理を指示する 2 つのプロパティがあります。どちらもプ
ログラミングによりアプリケーションの中で設定する必要があります(コードに変更を加える必要があります)。.pkg インストーラパッケージと
.app アプリケーションバンドルのプロパティはそれぞれ次のとおりです。
JFileChooser.packageIsTraversable
JFileChooser.appBundleIsTraversable
これらのプロパティに指定可能な値は、always (フォルダとして処理、デフォルトの動作)と
never (ファイルとして処理)です。これらのプ
ロパティをアプリケーションにおける JFileChooser の全インスタンスに対してグローバルに設定するには、UIManager.put() を使
います。または、JComponent から継承した putClientProperty() インスタンスメソッドを使って、インスタンスごとに設定するこ
ともできます。
これらのプロパティの使用に関しては、いくつかの既知の問題があります。
現時点では、
JFileChooser.packageIsTraversable を never に設定すると、.pkg ファイルと .app ファイル
のどちらについてもそのように設定されます。
現時点では、
JFileChooser.appBundleIsTraversable を never に設定すると、packageIsTraversable
が無視され、JFileChooser で動作がデフォルトの動作となり、.pkg ファイルがナビゲーション可能になります。
つまり、現時点では、これらのプロパティを使用した場合、.app ファイルのみ、または .app ファイルと .pkg ファイルの両方をナビゲーション不可
能にできます。
注意:
JFileChooser プロパティは、Swing で Aqua のルックアンドフィールを使う場合にだけ有効です。なぜな
ら、Aqua はアップルが制御する唯一のルックアンドフィールだからです。
先頭に戻る
Macintosh 固有の仕立て
次の数節では、Java アプリケーションを、可能な限り Aqua に対応した Mac OS X アプリケーションに近づけるという具体的な目的のために、Java
アプリケーションに対して行える変更や設計上の決定について説明します。ほかのプラットフォームでは影響のない変更もあれば、アプリケーション
を複数のプラットフォームで動作させる場合には、コードを条件に応じて、パッケージ化または実行する必要がある変更もあります。
先頭に戻る
Macintosh のメニューバーの使用
Java の UI モデルと Macintosh の UI モデルの違いの 1 つは、Swing ではアプリケーションのメニューバーはフレーム(ウィンドウ)ごとに適用さ
れるということです。Windows のモデルと同じように、Swing によるアプリケーションのメニューバーは、フレームのタイトルバーの直下に表示さ
れます。これは、アプリケーションのすべてのウィンドウを制御する「スクリーン」メニューバーが、アプリケーションに 1 つだけある Macintosh の
モデルとは異なります。この問題を簡単に解決するために、次のランタイムプロパティが追加されています。
com.apple.macos.useScreenMenuBar
このプロパティは、
true または false の値を持つことができます。未定義の場合、false の値に対応する標準の Java の動作が適用されま
JFrame の JMenuBar が、Macintosh ユーザが想定す
す。アプリケーションの起動時にJava のランタイムにより読み取られると、指定された
る位置、つまりスクリーンの最上部に配置されます。これは、ホストの仮想マシンが使用しなければならない単純なランタイムプロパティなので、ア
プリケーションで設定しても、ほかのプラットフォームでは、そのチェックすら行われないので、何の影響もありません。
JDialog に関連付けられている JMenuBar は、このプロパティがセットされていても想定位置である最上部ではなく、(プロパティがセット
されていないかのように)ダイアログの内部に表示されることを知っておくことは重要です。 デフォルトでは、メニューバーのない JDialog にフォー
カスがあたると、親の
JFrame のメニューバーは、選択不可で透けて見えます。
ダイアログウィンドウにメニューを付ける必要を感じた場合には、UI を再考した方がよいでしょう。ダイアログは、情報提供するか、ユーザに 1 つ
の簡単な決定を提示するものでなければなりません。メニューバーを必要とする機能を持つウィンドウは、JFrame にしておく方が良いかもしれま
せん。
スクリーンメニューバーを有効にする方法の簡単な要約は、Q&A 1003 からも入手できます。
残念ながら、これにより解決されるのは問題の一部(視覚的な配置)にすぎません。「ウィンドウごとに 1 つのメニューバーを」という根本的な問題
は依然存在します。つまり、メニューは、スクリーンの最上部に表示されますが、メニューが割り当てられている特定のウィンドウにフォーカスがあ
たっているときだけです。アプリケーションに複数のウィンドウがあり、メニューバーを持つウィンドウ以外のウィンドウにフォーカスがあたったと
きには、メニューバーが消えてしまいます。Aqua Human Interface Guidelines では、アプリケーションのメニューバーは常に表示されていなければ
ならないと規定されています。アラートダイアログのような重要でないウィンドウでもメニューバーが表示されなければなりません(このダイアログ
のメニューは無効にした方がよいかもしれませんが)。
この問題に対処する方法はいくつかありますが、最も一般的な方法は、アプリケーションの各独立フレームに同じメニューバーを生成するメニュー
ファクトリを作成し使用することです。こうすることで、フォーカスが各フレームに移っても、フレームには、スクリーンの最上部にメニューバーが
そのまま表示されています。
先頭に戻る
ウィンドウメニュー
Aqua Human Interface Guidelines の指示の 1 つに、Mac OS X アプリケーションはすべて、現在開かれているすべてのウィンドウを常に把握でき
るようにするために、 ウィンドウメニューを提供するべきだとあります。Java の Swing でこの機能を実装するのは不可能ではありませんが、中で
も、このテクニカルノートで示した 2 つの推奨事項、つまりMacintosh のメニューバーと独立したフローティングフレームに関する推奨事項を応用
することが要求されます。 これら 2 つの要件を満たさなくても、ウィンドウメニューは実装できるものの、これらは、Java アプリケーションを可能
な限り Mac 風にするために相乗的に機能します。メニューバーをすべてに表示するという問題と同様、Swing の現在のアーキテクチャでは、アプリ
ケーションの現在の状態に合わせて、常に更新され同期化される複数のメニューとメニュー項目を持たせるのは困難です。 しかし、Action と
PropertyChangeListener を利用すれば、ウィンドウメニューの機能のほとんどは、現在利用できる機能で実現できます。
ウィンドウメニューには、現在アクティブな(可視)ウィンドウのリストが、現在選択され最前面に表示されているウィンドウがあればそれに対応す
るメニュー項目にチェックマークが付いた状態で、表示されていなければなりません。また、特定のウィンドウのメニュー項目を選択することで、対
応するウィンドウが最前面に来なければなりません。 新しく開かれたウィンドウはメニューに追加され、閉じられたウィンドウはメニューから取り除
かれなければなりません。メニュー項目の順序は通常、ウィンドウが表示された順序です(詳細な説明については Aqua Human Interface Guidelines
を参照)。
先頭に戻る
アプリケーションメニュー
AWT または Swing を使っている Java アプリケーション、およびダブルクリック起動が可能な .app ファイルにパッケージ化されている Java アプ
リケーションはすべて自動的に、Mac OS X のネイティブアプリケーションと同様、アプリケーションメニューを使って起動されます。このアプリ
ケーションメニューには、デフォルトでは、タイトルとしてメインクラスの完全な名前が含まれています。この名前は、
com.apple.mrj.application.apple.menu.about.name というアプリケーションプロパティを使って、または Xdock:name コマンドラインプロパティを使って変更できます。Mac OS X の Aqua Human Interface Guidelines によれば、アプリケーション
メニューに指定する名前は 16 文字を超えてはいけません。詳細は、Java Runtime Properties for Mac OS X(Mac OS X の Java ランタイムプロパ
ティ) に関するテクニカルノートおよび Aqua Human Interface Guidelines を参照してください。
アプリケーションメニューをカスタマイズするための次の手順は、アプリケーションメニューの項目が選択されたときに、独自に作成した処理コード
が実際に呼び出されるようにすることです。アップルでは、このために、com.apple.mrj パッケージの特別な Java インタフェースを使った
手段を提供しています。各インタフェースにはそれぞれ、適切なアプリケーションメニューが選択されたときに呼び出される特別なコールバックメ
ソッドがあります。Java 1.3.1 Update 1 for Mac OS X 以降では、アプリケーションメニューのために次のコールバックインタフェースが利用でき
ます。
MRJAboutHandler - プログラムが、[<アプリケーションの名前> について...]メニュー項目の選択に対応できるようにします。
MRJPrefsHandler - [環境設定...]メニュー項目に対応します。
MRJQuitHandler - [<アプリケーションの名前> を終了 ]メニュー項目が選択されたときの最後のクリーンアップ処理を行います。
Java Application Menu
図 1 Mac OS X 上の Java アプリケーションのアプリケーションメニュー
特定のアプリケーションメニュー項目を処理するには、次の手順で行います。
1. 適切なハンドラインタフェースを実装します。
2. 実装の中で適切なハンドラメソッド ( handleAbout() 、handlePrefs() 、handleQuit() )を定義します。
3.
com.apple.mrj.MRJApplicationUtils クラスの適切なスタティックメソッド
(registerAboutHandler() 、registerPrefsHandler() 、registerQuitHandler() )を使ってハンド
ラを登録します。
これらの実装例は、Project Builder で新しい Java Swing アプリケーションを開くだけで見ることができます。 Mac OS X 10.1 と 10.2
(Jaguar)における、MRJQuitHandler の正しい使い方を示す Technical Q&A も参考にしてください。
先頭に戻る
アプリケーションメニューのカスタマイズ
Mac OS X 上の Java アプリケーションへのアプリケーションメニューの追加について、またそれらのメニュー項目の利用方法についてはすでに説明
しました 。ほかのプラットフォームにアプリケーションを配備する予定があり、メニューバー内のほかの場所([ファイル]メニュー、[編集]メ
ニューなど)に、[環境設定]、[終了]、または[...について]の各項目を配置する必要がある場合は、条件に応じてこの配置を行なった方がよい
でしょう。たとえば、2 つの異なる[環境設定]メニュー項目があったり、MRJ の[終了]項目と同時に[終了]メニュー項目があったりしても害は
ありませんが、Mac ユーザにとっては、アプリケーションメニューにおなじみの項目がアプリケーションメニューにだけあって、ほかのどこにもない
方が紛らわしくないでしょう。これは小さな変更ですが、Mac OS X の Java アプリケーションのルックアンドフィールでは大きな違いを生むかもし
れません。
先頭に戻る
追加の MRJ ハンドラ
アプリケーションメニューを扱うために提供されているインタフェースのほかに、現在の Mac OS X に対応した Java のリリースでは、2 つの機能的
な MRJ ハンドラがサポートされています。
MRJOpenApplicationHandler - アプリケーションを開くというアップルイベントに対応
MRJOpenDocumentHandler - サポートされているドキュメントのダブルクリックまたはアプリケーションアイコンへのドラッグ
に対応
これらのハンドラインタフェースは、Mac OS X の Finder における Java アプリケーションの動作の強化を目的とするもので、上記のアプリケーショ
ンメニューインタフェースと同じように使用します。アプリケーションが Finder から MRJOpenDocumentHandler を使って開けるファイル形式の登
録は、アプリケーションバンドルの Info.plist ファイルの最上位レベルで追加のキーを使って、Cocoa アプリケーションまたは Carbon アプリケー
ションの場合と同じように行います。詳細については、『Bundle Keys』の CFBundleDocumentTypes の節を参照してください。
先頭に戻る
Java アプリケーションの起動
Macintosh 体験の最も身近なそして顕著な特徴はおそらく、アプリケーションがダブルクリック起動が可能なアイコンまたはパッケージにより起動さ
れることでしょう。Java アプリケーションが、「良き Mac OS X 市民」になるためには、起動のためにコマンドラインの使用を要求するべきではあ
りません。エンドユーザのために、Java アプリケーションをダブルクリック起動可能にする方法がいくつかあります。
Project Builder: ダブルクリック起動が可能な Java アプリケーションを作成する最も簡単な方法は、最初から Project Builder でプロジェ
クトを開始することです。ビルド時に、作成した Java ライブラリの回りに .app パッケージが自動的に構築されます。Project Builder
は、Mac OS X Developer Tools と一緒にインストールされます。
MRJAppBuilder: これは、ほかのツールを使って、ほかのプラットフォーム向けにすでに作成されたアプリケーションにとっては、おそら
く最も魅力的な方法です。MRJAppBuilder は、必要なすべての JAR ファイルと引数に基づいて、Mac OS X 用に .app パッケージを構築し
ます。 これは、Mac OS X Developer Tools と一緒にインストールされます。
Java Web Start: Mac OS X 10.1 から提供が開始された Java Web Start は、システムと一緒にインストールされます。Web Start
は、Web リンクをクリックするだけで簡単に Web 上にアプリケーションを配置できる素晴らしい手段です。 現在の実装では、JNLP ファイ
ルは、ユーザの downloads ディレクトリに保存され、これをダブルクリックすると、Web Start によってアプリケーションが起動されま
す。より新しいバージョンが元の URL で入手可能になれば、そのダウンロードまで行います。Web Start の詳細については、Sun の Web
サイトを参照するか、Java Web Start( /Applications/Utilities/ )を開いて、サンプルアプリケーションを実際に使って
試してください。
マニフェストファイル: アプリケーションが完全に単独の JAR ファイルに含まれていて、メインクラスを定義する適切なマニフェストファ
イルがある場合は、Mac OS X の Finder の中で JAR そのものをダブルクリックするだけでアプリケーションを起動できます。
もちろん .app による方法が、Java アプリケーションをパッケージ化する最も Mac 風な方法です。
Dock アイコンの設定
Mac OS X で起動されるアプリケーションにはすべて、Finder の Dock の中に対応するアイコンがあります。これは、Mac OS X のグラフィカルな
Java アプリケーションだけでなく、.app バンドルでパッケージ化されている非グラフィカルなアプリケーションの場合も同様です。デフォルトの
Java アイコンが、Dock に入れるひな形として提供されていますが、開発者は、次の 2 つのどちらかの方法を使って Java アプリケーションのカス
タムアイコンを指定することができます。
1. Terminal: 起動引数、-XDock:icon を使います。
2. Bundle (.app): バンドルの
Contents/Resources/ ディレクトリに .icns ファイルを含めます。
このことは、ダブルクリック起動が可能な JAR ファイルを使って配備されるアプリケーションは、Dock アイコンをカスタマイズできないことを意味
します。したがって、上に挙げたほかの配備方法を検討するようお勧めします。残念ながら、Java Web Start がアプリケーションを起動する方法に
起因して、現時点では、Java Web Start でも Dock アイコンのカスタマイズは不可能です。
-XDock 引数の詳細については、Java Runtime Properties for Mac OS X(Mac OS X の Java ランタイムプロパティ) に関するテクニカルノート
を参照してください。
先頭に戻る
要約
このテクニカルノートでは、開発者が、Mac OS X で動作する Java アプリケーションに、Mac OS X のユーザ体験の利点をもたらすことができる領
域について簡単に見てきました。Mac OS X 上の Java アプリケーションを、できるだけネイティブアプリケーションらしい外観にするために、開発
者の方々が、ランタイムプロパティから、互換性を保つためのベストプラクティス、Mac 固有の微調整に至るまで、利用できる手段を最大限に活用で
きるよう願っています。
先頭に戻る
ダウンロード
このテクニカルノートの PDF 版
ダウンロード
先頭に戻る
連絡先|プライバシーポリシー
製品のご購入・ご購入相談は、お気軽にアップルストアまで。
0120-APPLE-1(0120-27753-1)
Copyright © 2004 Apple Computer, Inc. All rights reserved.
© Copyright 2026 Paperzz