複数のJFrameの使用:良いまたは悪い習慣?[閉まっている]


531

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

複数のJFrameウィンドウを使用するのが良い方法かどうか疑問に思っていますか?


11
マルチモニター設定を対象にしている場合のみ!
DNA

17
また、これは言語に依存せず、特にJavaよりもユーザーインターフェイスに関係していると主張します
wchargin 2013年

6
@WCharginに同意します。この質問は、私が思った以上に貴重なものになりました。
ペドラー2013年

1
初心者(私など)は通常、複数のJFrameを使用していることに気づきました。おそらくCardLayoutを利用するよりメインJFrame内から呼び出す方が簡単だからです。ただし、場合によっては使用しないことをお勧めします。
Hoodlum 2013年

デバッグはサボテンを食べるようなものです。これはお勧めできません。
Taslim Oseni

回答:


447

複数のJFrameを使用するのが良い方法かどうか疑問に思っていますか?

悪い(悪い、悪い)習慣。

  • ユーザーに不便:1つしか表示されないはずのタスクバーに複数のアイコンが表示される。さらに、コーディングの問題の副作用。
  • コード化と保守の悪夢:
    • モーダルダイアログは、そのダイアログの内容に申し出フォーカス関心に簡単に機会を-選択/修正/これをキャンセルし、その後、続行。複数のフレームにはありません。
    • 親がクリックされたときに、親を持つダイアログ(またはフローティングツールバー)が前面に表示されます。これが目的の動作である場合は、フレームに実装する必要があります。

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

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

ただし、これらの戦略が特定のユースケースで機能しない場合は、以下を試してください。単一のメインを確立しJFrame、その後、持っているJDialogJOptionPaneのインスタンスは、ダイアログの親としてフレームを使用して、自由に浮動要素の残りのために表示されます。

多くの画像

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

  1. JLabelユーザーがその時点で興味のある画像を表示する単一(スクロールペインの中央)。に見られるようにImageViewer
  2. 単一行JListこの答えに見られるように。それらの「単一行」部分は、それらがすべて同じ次元である場合にのみ機能します。あるいは、その場で画像を拡大縮小する準備ができており、それらがすべて同じアスペクト比(例、4:3または16:9)である場合。


4
@AndrewThompson説明をありがとう、私はJFrame以前に複数のが必要な状況に遭遇したことはなく、それらの問題を考慮したこともありませんでした。
ジェフリー

4
@ user417896 「ただ依存する」 いいえ、ありません。私はGimpを使用しました。それは恐ろしいことであり、MDIである必要があります。
Andrew Thompson

4
@ryvantage 「(Excel)はMDIである必要がありますか?」 良い質問。両方の方法でユーザーに提供する必要があると思います(確かにMDI形式だけでなく)。次に例を示します。1)現在TextPadを使用していて、選択した構成により、個別のインスタンスが開き、それぞれがリストに表示される複数のドキュメントを提供します。2)通常はFFをタブ付きモードで使用しますが、時々タブを新しいウィンドウにドラッグします。-例の共通要素はユーザーの選択です。アプリを配信します。「しかし、ユーザーはそれを望んでいる」。
Andrew Thompson

12
@AndrewThompson最後のコメントであなた自身の議論に対抗しました。あなたの主な答えでは、これは悪い習慣であり、決してすべきではないと述べていますが、上のコメントでは、SDIが時々好きであり、ユーザーに選択肢を提供する必要があると述べています。確かに、これはまさにuser417896が上で言っていたものです。場合によります。これは、開発者仲間に対する私の最大のペット嫌いの1つです。それらの多くがいわゆる「ベストプラクティス」について宗教的に狂信的になるという事実。私たち全員が「ベストプラクティス」に固執し、広場の外で考えなければ、今日のような革新的なUIはありません。
DuncanKinnear 2013

4
巨大な一般化!ユーザーがウィンドウを個別に制御して、タスクバーから個別にアクセスできるようにすることは、必ずしも悪いことではありません。すべてのオプションを認識し、適切に選択することをお勧めします。複数のJFrameが非常に有効である場合は確かにあります。
Dawood ibnカリーム

203

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

そこで、複数のJFrameアプローチの利点と、他の人が提示したいくつかの短所を神話で説明するつもりです。

  1. レイアウトの究極の柔軟性 -個別JFrameのを許可することにより、エンドユーザーは自分の画面上にあるものを広げて制御できるようになります。このコンセプトは、「オープン」であり、制限を感じさせません。1つの大きなsのJFrame束に向かうと、これを失いますJInternalFrame
  2. 非常にモジュール化されたアプリケーションに適しています -私の場合、ほとんどのアプリケーションには3〜5個の大きな「モジュール」があり、実際には互いに何の関係もありません。たとえば、1つのモジュールが販売ダッシュボードであり、1つが会計ダッシュボードである場合があります。彼らはお互いに何も話しません。ただし、幹部は両方を開きたい場合があり、それらはタスクバーの別々のフレームであるため、彼の生活が楽になります。
  3. エンドユーザーが外部の資料を簡単に参照できるようにします -以前、次のような状況がありました:私のアプリには「データビューア」があり、そこから「新規追加」をクリックするとデータ入力画面が開きます。最初は、どちらもJFramesでした。しかし、私はデータ入力画面をJDialog親がデータビューアであるようにしたいと考えました。私は変更を加え、すぐに、プログラムの別の部分(またはWebサイト、私は参照しません)を参照している間、ビューアを最小化または閉じ、エディターを開いたままにすることができるという事実に大きく依存するエンドユーザーから電話を受けました覚えていない)。彼はマルチモニターを使用していないので、最初に何か他のことをするための入力ダイアログが必要でした次に、データビューアを完全に非表示にします。これはで不可能でした。JDialog確かにでも不可能JInternalFrameでした。私JFramesは彼の正気のために不本意ながらそれを別のものに戻しましたが、それは私に重要な教訓を教えてくれました。
  4. 神話:コーディングが難しい -これは私の経験では当てはまりません。を作成するJInternalFrameよりもを作成する方が簡単な理由はわかりませんJFrame。実際、私の経験では、JInternalFrames柔軟性がはるかに低くなっています。JFrameアプリでの開閉を処理する体系的な方法を開発しました。フレームのコード自体からフレームをほぼ完全に制御します。新しいフレームの作成、SwingWorkerバックグラウンドスレッドでのデータの取得とEDTでのGUIコードを制御するs、ユーザーがフレームを2回開こうとした場合にフレームを復元/前面に移動するなど。私JFrameのs を開くために必要なのはpublic staticメソッドopen()とopenメソッドを呼び出し、windowClosing() イベントは残りを処理します(フレームはすでに開いていますか?開いていませんが、ロードしていますか?など)このアプローチをテンプレートにしたので、各フレームに実装するのは難しくありません。
  5. 神話/証明されていない:リソースが重い -この投機的なステートメントの背後にあるいくつかの事実を知りたいのですが。おそらく、にJFrame比べてより多くのスペースが必要であると言えますが、JInternalFrame100 JFrame秒開いたとしても、実際にどれだけ多くのリソースを消費するのでしょうか。リソースが原因でメモリリークが懸念される場合:呼び出しdispose()により、フレームでガベージコレクションに使用されたすべてのリソースが解放されます(ここでも、a JInternalFrameはまったく同じ問題を呼び出す必要があります)。

たくさん書いて、もっと書ける気がします。とにかく、私はそれが不人気な意見だからといって、反対票を投じないことを望みます。質問は明らかに貴重なものであり、たとえそれが一般的な意見ではない場合でも、私が貴重な回答を提供できれば幸いです。

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

  • 長方形以外のウィンドウをいくつか持つことができます。そのため、デスクトップや他のウィンドウが他のプロセス(例:Webブラウザー)から隠されません。
  • 2番目のExcelウィンドウで書き込み中に、1つのExcelウィンドウを介して別のプロセスからウィンドウを開くことが可能です。MDIを使用すると、内部ウィンドウの1つに書き込みを行おうとすると、Excelウィンドウ全体にフォーカスが移動し、別のプロセスからウィンドウが非表示になります。
  • 異なる画面に異なるドキュメントを表示することができます。これは、画面の解像度が同じでない場合に特に役立ちます

SDI(単一ドキュメントインターフェイス、つまり、すべてのウィンドウは単一のドキュメントのみを持つことができます):

ここに画像の説明を入力してください

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

ここに画像の説明を入力してください


16
よく考え抜かれた。互いに何の関係もない複数のモジュールがある場合は、別々のアプリケーションを作成してみませんか?また、モーダルダイアログを使用する必要があるという制限はありません。モードレスダイアログを使用して、2番目の「フレーム」として機能させることができます。
ジェフリー

これについては@kleopatraに同意する必要がありますが、非常に良い回答と詳細な回答です。以前は、ユーザーが複数の画面/同じ画面の出力データをさまざまな入力で比較したい100を超える画面を持つアプリケーションがありました。それを可能にするカスタムウィンドウシステムを構築しました。ユーザーは、2つのJFrameを隣同士にしておくことで、より快適になりました;)
javatarz

私はあなたの主張を理解していますが、私はすべてを1人JFrameの大親に持つことを望んでいますJTabbedPane。しかし、レイアウトが異なる2番目(またはそれ以上)のウィンドウを開く可能性があるため、SDI愛好家とMDIの両方が幸せなハイブリッド動作が提供されます。すべての場合において、私は常にJInternalFrame両方の世界のすべての不便さを与える恐ろしいパターンとして考えました。彼らが提供する柔軟性はほんのわずかであり、実際の目的ではなく、多くの貴重な画面スペースを食い尽くしてしまいます。
Guillaume Polet 2014

私はSDIが適切な場合があることに同意します(ユーザーはそれを好むことがよくあります)。もう1つ欠点がありますが、これまでのところ回避策は見つかりませんでした。不幸にも、それぞれJFrameに独自のタスクバーアイコンが表示されます。これがあなたの望むものである場合もあれば、そうでない場合もあります。WinAPIではこれを構成するのは簡単ですが、Swingでは実行できないようです。
スマ

その場合の@sumaは私が私が選ぶと思いJDialogオーバーJFrame
ryvantage

51

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

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

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

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

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

彼らはビューアを開き、「名前を付けて保存」機能を使用してレポートをPDFとして特定のディレクトリに保存し、Acrobat Readerを使用してPDFファイルを開き、次のレポートでも同じことを行いました。彼らは、見たいさまざまなレポート出力で複数のAcrobat Readerを実行していました。

それで私は、ビューティーを傾けてモードレスにしました。つまり、各ビューアにはタスクバーアイコンがあります。

先週彼らに最新バージョンがリリースされたとき、彼らからの圧倒的な反応は彼らがそれを愛するということです。これは、システムに対する最近の最も人気のある機能強化の1つです。

だからあなたは先に進んで、彼らが欲しいものが悪いとユーザーに伝えますが、最終的にそれはあなたに何の好意もありません。

注意事項:

  • これらのモードレスウィンドウにJDialogを使用することがベストプラクティスのようです
  • ModalityTypeブールmodal引数ではなく、新しい引数を使用するコンストラクタを使用します。これにより、これらのダイアログにタスクバーアイコンが表示されます。
  • モードレスダイアログの場合は、nullの親をコンストラクターに渡しますが、「親」ウィンドウからの相対位置に配置します。
  • Windows上のJavaのバージョン6にはバグがあります。つまり、メインウィンドウは、ユーザーに通知せずに「常に手前」になることがあります。これを修正するには、バージョン7にアップグレードしてください

6
これもまさに私の経験です。私が確信していることが1つあるとしたら、それは、人々が本当にやりたいことを何でもやろうと、ユーザーフレンドリーを回避しようとするときに、何か間違ったことをしているということです。機能性は王様です。
ryvantage 2013

これを回避する1つの方法は、複数のJFrameを開いて、すべて同じ機能を提供できるようにすることですが、デフォルトではすべてが1つのウィンドウ内で実行されます。これにより、ユーザーは実際にSDIまたはMDIを選択できます。
Guillaume Polet 2014年

ごめんなさい?ソリューションについてもう少し詳しく説明していただけますか?どのようにして単一のウィンドウと複数のウィンドウにすることができますか?メインアプリケーションを実行する1つのメインウィンドウがありますが、ダイアログを開く必要がある場合や、(ユーザーの要件に基づいて)ダイアログをモードレスにする必要がある場合があります。インターフェースがこのようになるべきである、またはそれはあなたのために大きな穴を掘るだけであるというルールを作る。
DuncanKinnear 2014年

1
@GuillaumePolet私はダンカンに同意します、あなたがもう少し何を意味するのか説明できますか?私は彼の混乱を共有します
Ungeheuer

ユーザーがアプリケーション(「JFrame」)の複数のコピーを開始できるというのが彼の意味だと思いますが、それらのそれぞれの内部はSDIです。ただし、クライアントアプリケーションは非常にシックなクライアントであるため、これはリソースを大量に消費するアプローチになります。
DuncanKinnear 2015

20

jInternalFrameをメインフレームにして非表示にします。その後、それを以降のイベントに使用できます。

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

19

前回スイングに触れたのは久しぶりですが、一般的にこれを行うのは悪い習慣です。頭に浮かぶ主な欠点のいくつか:

  • それはより高価です: JFrameを描画するために、DialogやJInternalFrameなどの他の種類のウィンドウコンテナーよりも多くのリソースを割り当てる必要があります。

  • ユーザーフレンドリーではありませんくっついたJFrameの束に移動するのは簡単ではありません。アプリケーションが一貫性のない一連のアプリケーションであり、デザインが不十分であるように見えます。

  • JInternalFrame簡単に使用できますこれは一種の反省事項ですが、デスクトップとJInternalFrameパターンを使用して考えたよりもはるかに簡単で、他の人が(またはより多くの時間をかけて)賢くなっているので、使用することをお勧めします。


7
複数JInternalFrameのを使用しても、ユーザーに同じ効果がありますか?個人的にはの使用に反対JInternalFrameです!CardLayout本当の祝福です!
Branislav Lazic 2013年

4
@ brano88に同意します。JInternalFrameあなたが言及した3つのケースのいずれにおいても利点はありません(1.どこJInternalFrameよりも軽い証拠はどこにありJFrameますか?2。JInternalFrame sは、JFramesの束と同じように雑然としている、乱雑、くっついている可能性が . JInternalFrame簡単な方法は?同じコードですが、1つはaに含まれ、JDesktopPaneもう1つはナチュラルスクリーン領域に含まれます。これらは私にとっても同じように複雑に聞こえます。)
ryvantage

1
1. JFrameは、軽量であるJInternalFrameと比較して、重いコンポーネントです。2.機能するために同時に多数のウィンドウを含むアプリを見たことがありますか?IDE、ブラウザ、ファイナンスアプリケーションでも、同じスコープに保つことが目標です。3.私は過去にJIFが非常に使いやすく、もちろんシナリオに最も適したコンポーネントを選択することに不満はありませんでした
Necronet 2013

4
1.これの証拠を見たいのですが。どちらもオブジェクトであり、どちらもJComponentsであり、どちらもほぼ同じ構造を持っていますが、JDesktop1つはa でレンダリングされ、1つはレンダリングされません。繰り返しますが、申し訳ありませんが、の「重量」について推測していると思いますJFrame。2.私のアプリケーションはSDIを使用しており、クライアントは非常に満足しています。しかし、あなたは「大量の窓」と言っていましたが、もちろんそれは吸います。しかし、私のポイントはこれです。「1トン」JInternalFrameのsは同じくらいひどいものです。JIFを使用すると、だらしのないUIデザイナーになることができるとしたら、それは恐ろしいことです。乱雑な混乱とは、JFであれJIFであれ、乱雑な混乱です。
ryvantage 2013

2
「もちろん、シナリオに最適なコンポーネントを選択してください」
Necronet 2013

10

悪い練習は間違いなく。1つの理由は、すべてにJFrame新しいタスクバーアイコンが表示されるため、「ユーザーフレンドリー」ではないためです。複数JFrameのを制御すると、髪を引き裂くことができます。

個人的には、ONE JFrameをあなたの種類のアプリケーションに使用します。複数のものを表示する方法はあなた次第です、たくさんあります。CanvasES、 、JInternalFrameCardLayoutでもJPanel多分ね。

複数のJFrameオブジェクト=痛み、トラブル、問題。


9
うーん...受け入れられた答えに比べて新しいものは何もありません、fafaics?
クレオパトラ

5
「すべてのJFrameに新しいタスクバーアイコンが表示されます」-これはWindowsにのみ適用されます。Mac OS Xでは、開いているウィンドウの数に関係なく、すべてのアプリケーションにドックアイコンが1つだけあります。また、アプリケーションに複数のトップレベルウィンドウがあることはよくあります。
ロルフ

8

複数Jframeのを使用することは良い考えではないと思います。

代わりにJPanel、1つ以上JPanelのを同じで使用できますJFrame

また、このを切り替えることもできJPanelます。だから、私たちは、JFrame

それぞれJPanelに異なるものを設計でき、これらすべてをJPanel一度にJFrame1つずつ表示できます。

これを切り替えるには、for each または 'JButton JPanel`をJPanel使用JMenuBarします。JMenuItemsJPanelfor each

2つJFrame以上にすることはお勧めできませんが、1つ以上にする場合は問題ありませんJFrame

ただし、JFrame複数JFrameのを使用するよりも、ニーズに合わせて1つを変更する方が適切です。


5

フレームが同じサイズになる場合は、フレームを作成して、フレームを参照として渡してみてください。

フレームを通過したら、フレームの配置方法を決定できます。これは、一連の数値の平均を計算する方法を持つようなものです。メソッドを何度も作成しますか?


1
これは基本的にはCardlayoutとJTabbedPaneでできることですが、同じことを達成するためのクリーンで簡単な解決策がある一方で、逆に行うとコードが過度に複雑になります。
Guillaume Polet 2014年

4

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


3
シングルトンパターンは悪夢です。スケーリングしたいプロジェクトはすべて、シングルトンパターンを避けようとする必要があります。
Guillaume Polet 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.