web-dev-qa-db-ja.com

複数のJFrameの使用:良い方法か悪い方法か?

私は、画像を表示し、データベースから音を出すアプリケーションを開発しています。 GUIからデータベースに画像を追加するために別のJFrameを使用するかどうかを決定しようとしています。

私はそれが複数のJFrameウィンドウを使うのが良い習慣であるかどうか疑問に思いますか?

516
Peddler

私はそれが複数のJFrameを使うのが良い習慣であるかどうか疑問に思いますか?

悪い(悪い、悪い)練習。

  • ユーザーに不親切:ユーザーには、タスクバーに複数のアイコンが表示されていることが予想される場合に、複数のアイコンが表示されます。さらに、コーディング問題の副作用があります。
  • コーディングして維持するための悪夢:
    • モーダルダイアログ は、そのダイアログの内容に注意を集中するための簡単な機会を提供します - これを選択/修正/取り消し、、次にに進みます。複数のフレームはしません。
    • 親がクリックされると、親を持つダイアログ(またはフローティングツールバー)が前面に表示されます。それが望ましい動作であれば、フレームで実装する必要があります。

1つのGUIに多数の要素を表示する方法はいくつもあります。

  • CardLayout (短い デモ。 )。良い:
    1. ダイアログのようなウィザードを表示します。
    2. 関連付けられたコンポーネントを持つアイテムのリスト、ツリーなどの選択を表示します。
    3. コンポーネントなしと表示コンポーネント間を反転します。
  • JInternalFrame/JDesktopPane は通常 MDI に使われます。
  • JTabbedPane はコンポーネントのグループを表します。
  • JSplitPane 2つの構成要素を表示する方法で、どちらを使用するかによって重要度(サイズ)が異なります。
  • JLayeredPane はるかに多くの階層化されたコンポーネント。
  • JToolBar は通常、アクションまたはコントロールのグループを含みます。 GUIの周りをドラッグすることも、ユーザーのニーズに応じて完全にオフにすることもできます。上で述べたように、そうすることで、親に従って最小化/元に戻すでしょう。
  • JList 内の項目として(下記の単純な例)。
  • A JTree のノードとして。
  • 入れ子のレイアウト

しかし、これらの戦略が特定のユースケースでうまくいかない場合は、以下を試してください。単一のメインJFrameを設定し、次にフレームを親として使用して、残りの自由浮動要素に対して JDialog または JOptionPane のインスタンスを表示します。ダイアログ.

多くの画像

この場合、複数の要素が画像である場合は、代わりに次のいずれかを使用することをお勧めします。

  1. その時点でユーザーが関心のある画像を表示するための単一のJLabel(スクロール区画の中央)。 ImageViewer に見られるように。
  2. 単一行JListこの答えで見られるように 。その「単一行」部分は、それらがすべて同じディメンションである場合にのみ機能します。あるいは、画像をその場で拡大縮小する準備ができていて、それらがすべて同じ縦横比(4:3または16:9など)の場合です。

435
Andrew Thompson

複数のJFramename__アプローチは、Swingアプリのプログラミングを開始してから実装したものです。ほとんどの場合、私はそれ以上良く知らなかったので、最初にそれをしました。ただし、、開発者としての経験と知識が成熟し、多くの経験豊富なJava開発者の意見を読んで吸収し始めたとき、複数のJFramename__アプローチ(現在のプロジェクトと将来のプロジェクトの両方で)からshift awayを実行しようとしましたが、...これを取得する...クライアントからの抵抗!「子」ウィ​​ンドウと個別のコンポーネントのJInternalFramename__sを制御するためのモーダルダイアログの実装を開始すると、私のクライアントが不満を言い始めました!ベストプラクティスだと思っていたことをやっていたので、私はかなり驚きました!しかし、彼らが言うように、「幸せな妻は幸せな人生です」。クライアントにも同じことが言えます。もちろん、私は請負業者なので、エンドユーザーは開発者である私に直接アクセスできますが、これは明らかに一般的なシナリオではありません。

そこで、複数のJFramename__アプローチの利点と、他の人が提示したいくつかの短所についての神話を破ります。

  1. レイアウトの究極の柔軟性-個別のJFramename__sを許可することにより、エンドユーザーが画面の内容を広げて制御できるようになります。コンセプトは、「オープン」で非制限的だと感じます。 1つの大きなJFramename__とたくさんのJInternalFramename__sに向かうと、これを失います。
  2. 非常にモジュール化されたアプリケーションに適しています-私の場合、ほとんどのアプリケーションには3〜5個の大きな「モジュール」があり、これらは互いにまったく関係ありません。たとえば、1つのモジュールが販売ダッシュボードで、もう1つのモジュールが会計ダッシュボードである場合があります。彼らは互いに何も話しません。ただし、幹部は両方を開きたい場合があり、タスクバー上の別々のフレームであるため、仕事が楽になります。
  3. エンドユーザーが外部の資料を簡単に参照できるようにします-かつてこの状況に陥りました。アプリに「データビューア」があり、そこから「新規追加」をクリックできます「データ入力画面が開きます。最初は、両方ともJFramename__sでした。ただし、データ入力画面を、親がデータビューアーであるJDialogname__にしたかったのです。変更を加えた後、すぐにエンドユーザーから電話があり、エンドユーザーはviewerを最小化または閉じることができ、editorプログラムの別の部分(またはWebサイト、私は覚えていない)を参照しているときに開きます。彼はマルチモニターでnotであるため、入力ダイアログを最初に、他の何かを2番目に、データビューアーは完全に非表示です。これはJDialogname__では不可能でしたし、JInternalFramename__でも同様に不可能でした。残念ながら彼の正気さのために別のJFramesname__に変更しましたが、重要な教訓を教えてくれました。
  4. 神話:コーディングが難しい-これは私の経験では正しくありません。 JInternalFramename__よりもJFramename__を作成する方が簡単な理由はわかりません。実際、私の経験では、JInternalFramesname__の柔軟性ははるかに低くなっています。アプリでJFramename__sの開閉を処理する体系的な方法を開発しましたが、これは本当にうまく機能します。私は、フレームのコード自体の中からフレームをほぼ完全に制御します。新しいフレームの作成、バックグラウンドスレッド上のデータの取得とEDT上のGUIコードを制御するSwingWorkername__s、ユーザーがフレームを2回開こうとした場合のフレームの復元/前面への移動など。JFramename__sはパブリック静的メソッドopen()を呼び出し、windowClosing()イベントと組み合わせたopenメソッドが残りを処理します(フレームは既に開いていますか?それは開いていませんが、読み込みですか?)。このアプローチをテンプレートにしたため、各フレーム。
  5. Myth/Unproven:Resource Heavy-この投機的な声明の背後にあるいくつかの事実を見たい。おそらく、JFramename__にはJInternalFramename__よりも多くのスペースが必要であると言えますが、100個のJFramename__sを開いたとしても、実際にどれだけのリソースを消費しますか?リソースが原因でメモリリークが懸念される場合:dispose()を呼び出すと、フレームでガベージコレクションに使用されているすべてのリソースが解放されます(また、JInternalFramename__でもまったく同じ懸念が呼び出されます).

私はたくさん書きましたが、もっと書きたいと思っています。とにかく、私はそれが不評な意見だからといって、私が落選しないように願っています。この質問は明らかに価値のあるものであり、たとえそれが一般的な意見でなくても、価値のある答えを提供してくれればと思います。

複数のフレーム/フレームごとの単一ドキュメント( SDI )と1つのフレーム/フレームごとの複数ドキュメント( MDI )の優れた例はMicrosoft Excelです。 MDIの利点のいくつか:

  • 長方形以外の形状のいくつかのウィンドウを持つことが可能です-そのため、デスクトップや他のウィンドウを別のプロセス(Webブラウザーなど)から隠しません
  • 1つのExcelウィンドウで別のプロセスからウィンドウを開き、2番目のExcelウィンドウに書き込むことができます。MDIでは、内部ウィンドウの1つに書き込むと、Excelウィンドウ全体にフォーカスが与えられるため、ウィンドウが別のプロセスから非表示になります
  • 異なる画面に異なるドキュメントを配置することができます。これは、画面の解像度が同じでない場合に特に便利です

SDI(シングルドキュメントインターフェイス、つまり、すべてのウィンドウに1つのドキュメントのみを含めることができます):

enter image description here

MDI(マルチドキュメントインターフェイス、つまり、すべてのウィンドウに複数のドキュメントを含めることができます):

enter image description here

198
ryvantage

私が関わったばかりの例で、「ユーザーフレンドリーではない」という議論に対抗したいと思います。

私たちのアプリケーションでは、ユーザーが別々のタブとしてさまざまな 'プログラム'を実行するメインウィンドウがあります。可能な限り私たちはこの単一のウィンドウに私たちのアプリケーションを保とうとしました。

彼らが実行する 'プログラム'の一つはシステムによって生成されたレポートのリストを提示します、そしてユーザーはレポートビューアダイアログを開くために各行のアイコンをクリックすることができます。このビューアはレポートの縦長/横長のA4ページに相当するものを表示しているので、ユーザーはこのウィンドウを非常に大きくして、ほぼ自分の画面いっぱいに表示することを好みます。

数か月前に、これらのレポートビューアウィンドウをモードレスにして、複数のレポートを同時に開くことができるようにするようお客様からリクエストを受け始めました。

私はこれが良い解決策であるとは思わなかったのでしばらくの間私はこの要求に抵抗しました。しかし、私たちのシステムのこの「欠陥」をユーザーがどのように回避しているかを知ったとき、私の考えは変わりました。

レポートをPDFとして特定のディレクトリに保存するために[名前を付けて保存]機能を使用してビューアを開き、Acrobat Readerを使用してPDFファイルを開きます。次のレポートでも同じことをしてください。彼らは彼らが見たがっていたさまざまなレポート出力で走っている複数のAcrobat Readerを持つでしょう。

それで私は辞任し、ビューアをモードレスにしました。つまり、各視聴者にはタスクバーアイコンがあります。

先週彼らに最新版がリリースされた時、彼らからの圧倒的な反応は彼らがそれを愛しているということです。それは私たちの最も人気のある最近のシステムの機能強化のひとつです。

ですから、あなたは先に進んで、欲しいものは悪いとユーザに伝えますが、結局のところそれはあなたに何の恩恵も与えません。

いくつかの注:

  • これらのモードレスウィンドウにJDialogを使用するのがベストプラクティスのようです。
  • ブール値のModalityType引数ではなく、新しいmodalを使用するコンストラクタを使用してください。これがこれらのダイアログにタスクバーアイコンを与えるものです。
  • モードレスダイアログの場合は、コンストラクタにnullの親を渡しますが、それらの親ウィンドウに対して相対的に配置します。
  • Windows上のJavaのバージョン6には バグ があります。これは、メインウィンドウが指示されなくても「常に一番上になる」ことを意味します。これを修正するためにバージョン7にアップグレードしてください
50
DuncanKinnear

JInternalFrameをメインフレームにして非表示にします。それからあなたはさらなるイベントのためにそれを使うことができます。

jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);

私が最後にswingに触れてからしばらく経ちましたが、一般的にはこれを行うのは悪い習慣です。頭に浮かぶ主な短所のいくつか:

  • よりコストがかかります。DialogやJInternalFrameなど、他の種類のウィンドウコンテナであるJFrameを描画するには、さらに多くのリソースを割り当てる必要があります。

  • ユーザーフレンドリーではありません。JFrameをいっしょに立ち往生させるのは簡単ではありません。あなたのアプリケーションは矛盾したアプリケーションのセットではないように見えます。設計。

  • JInternalFrameを使うのは簡単ですこれはちょっとした礼儀ですが、今では私たちがすでに考えているよりもずっと簡単で他の人々は賢くなりますDesktopとJInternalFrameのパターンなので、それを使うことをお勧めします。

18
Necronet

間違いなく悪い習慣です。 1つの理由は、すべてのJFrameが新しいタスクバーアイコンを表示するという事実にとって、それがあまり「ユーザーフレンドリー」ではないということです。複数のJFramesをコントロールすると、髪の毛がリッピングされます。

個人的には、私はあなたのアプリケーションにONE JFrameを使います。複数のものを表示する方法はあなた次第です、たくさんあります。 Canvases、JInternalFrameCardLayout、さらにはJPanels。

複数のJFrameオブジェクト=痛み、問題、そして問題.

10
Matt Dawsey

複数のJframeを使用するのはお勧めできません。

代わりに、同じJPanelの中でJPanelsを複数のJFrameを使用することができます。

また、このJPanelを切り替えることもできます。それで、それは私たちにJFrameの中のもの以上のものを表示する自由を与えます。

JPanelごとに異なるものを設計することができ、このすべてのJPanelを一度に1つのJFrameoneに表示できます。

このJPanelを切り替えるには、各JMenuBarまたは 'JButtonfor eachJPanel`に対してJMenuItemsJPanelを使用します。

複数のJFrameを使用することはお勧めできませんが、複数のJFrameが必要な場合でも問題はありません。

しかし、複数のJFrameを持つのではなく、異なるニーズに合わせて1つのJFrameを変更することをお勧めします。

7
Lijo

フレームが同じサイズになる場合は、フレームを作成してからその参照として代わりにフレームを渡します。

フレームを通過したら、次にそれを移植する方法を決めることができます。一連の数字の平均を計算する方法があるのと同じです。メソッドを何度も作成しますか。

5
Keith Spriggs

これは良い習慣ではありませんが、使いたいとしてもシングルトンパターンをその良いものとして使うことができます。私は自分のプロジェクトのほとんどでシングルトンパターンを使ってきました。

4
arunjoseph