Swing ユーザー インターフェイスを備えたクロスプラットフォーム Java アプリケーションがあります。OS X では、アプリケーションはスクリーン メニュー バーを使用して、よりネイティブなユーザー エクスペリエンスを提供します。
通常、アプリケーションはJFrame
ドキュメントごとに 1 つ作成します。画面のメニュー バーは、これらすべてのウィンドウで一貫している必要があります。私はそれを行ういくつかの方法を試しましたが、適切ではあるが完全ではない、一貫したパフォーマンスの高いソリューションを 1 つだけ見つけました。他の誰かがより良いアプローチをしている場合に備えて、この情報が他の人に役立つことを願って、この質問を投稿しています。
うまくいかないいくつかのアプローチ:
複数のウィンドウに同じメニュー バーをアタッチする
JMenuBar
同じものを複数のJFrame
インスタンスに追加しようとしましたが、 Swing は一度に 1 つの JFrame にアタッチされた JMenuBar のみをサポートし、スクリーン メニュー バーとしてもサポートします。
MenuBar
ではなくAWT でもテストしましたJMenuBar
が、同じ現象が発生します。AndMenuBar
に比べて多くの制限がJMenuBar
あります (例: アイコンがない) ので、JMenuBar
.
メニューバーを複製する
JMenuBar
一般的な解決策の 1 つは、 for each newのコピーを作成することJFrame
です。ただし、これには少なくとも 2 つの問題があります。まず、メニュー バーの同期を維持する必要があります。リスナーを使用してそれを行うことはできますが、OS X プラットフォームを処理するためだけに多くの余分なコードが必要になります。ただし、2 番目のより深刻な問題はパフォーマンスです。数百のメニュー項目を含む複雑なメニュー バーがある場合、メニュー バーの複製は非常に遅くなります。このアプローチにより、新しいウィンドウの表示が数秒遅れることがわかりました。
デフォルトのメニュー バーを使用する
OS X v10.6 Update 1 および 10.5 Update 6の Java で、Apple の Java ライブラリに新しいメソッドが追加されましたApplication.setDefaultMenuBar(JMenuBar)
。
このメソッドの目的は、no がアクティブなときにメニュー バーを提供することですが、独自のnoがアクティブなJFrame
ときにデフォルトのメニュー バーも表示します。JFrame
JMenuBar
ただし、setDefaultMenuBar
機能にはいくつかの大きな問題があります。
- アクセラレータが機能しません。すべてのキー押下を自分で処理することで、アプリケーションでこの問題を回避しましたが、それでも残念です。
- 2012 年 12 月の時点で、setDefaultMenuBar は Java7 ではまだ使用できませんでした。非推奨またはサポートされていない API の使用は明らかに避けたいと考えています。
- 最も重要なのは、呼び出し
setDefaultMenuBar
によって JVM が適切にシャットダウンされなくなることです。その後の呼び出しでもsetDefaultMenuBar(null)
、必要なリソースは解放されません。
要するに、setDefaultMenuBar
安全で堅牢な方法とはまったく思えません。
したがって、問題は次のとおりです。一貫した画面を実装するための最も信頼性が高く、パフォーマンスが高く、互換性のある (OS X のバージョン間で) 方法はJMenuBar
何ですか?