Java Swingでset(Preferred | Maximum | Minimum)Sizeメソッドの使用を避けるべきですか?


481

私は次の方法の使用を提案したと何度も批判されました。

  1. setPreferredSize
  2. setMinimumSize
  3. setMaximumSize

上のSwingコンポーネント。表示されたコンポーネント間の比率を定義したい場合、それらの使用に代わるものはありません。私はこれを言われました:

レイアウトでは答えは常に同じです:適切なLayoutManagerを使用します

私はウェブを少し検索しましたが、主題の包括的な分析は見つかりませんでした。だから私は次の質問があります:

  1. それらの方法の使用を完全に避けるべきですか?
  2. メソッドは理由のために定義されています。それで、いつそれらを使うべきですか?どの文脈で?何のために?
  3. これらの方法を使用することの悪影響は、正確には何ですか?(私は、異なる画面解像度のシステム間で移植性を追加することしか考えられません)。
  4. どのLayoutManagerでも、必要なすべてのレイアウトニーズを正確に満たすことができるとは思いません。レイアウトの小さなバリエーションごとに新しいLayoutManagerを実装する必要がありますか?
  5. 4の答えが「はい」の場合、これは、維持が困難になるLayoutManagerクラスの急増につながるのではないですか?
  6. Componentの子間の比率を定義する必要がある状況(たとえば、child1は10%のスペースを使用し、child2 40%、child3 50%を使用する必要があります)で、カスタムLayoutManagerを実装せずにそれを達成できますか?

回答:


236
  1. それらの方法の使用を完全に避けるべきですか?

    はい、アプリケーションコードについては。

  2. メソッドは理由のために定義されています。それで、いつそれらを使うべきですか?どの文脈で?何のために?

    個人的にはAPIデザインの事故だと思います。子供のサイズについて特別な考えを持つ複合コンポーネントによってわずかに強制されます。「わずかに」、カスタムLayoutManagerを使用してニーズを実装する必要があるため。

  3. これらの方法を使用することの悪影響は、正確には何ですか?(私は、異なる画面解像度のシステム間で移植性を追加することしか考えられません。)

    いくつかの(SwingLabsのjava.netへの移行が原因で不完全であり、残念ながらリンクが壊れている)技術的な理由は、たとえばルール(hehe)または私の回答への彼/彼女のコメントにあるリンク @bendicottで言及されています。社会的には、コードを保守しなければならず、壊れたレイアウトを追跡しなければならない不運な仲間に大量の作業を課します。

  4. どのLayoutManagerも、必要なすべてのレイアウトニーズを正確に満たすことができるとは思いません。レイアウトの小さなバリエーションごとに新しいLayoutManagerを実装する必要がありますか?

    はい、「すべてのレイアウトニーズ」の非常に優れた概算を満たすのに十分強力なLayoutManagerがあります。大きな3つは、JGoodies FormLayout、MigLayout、DesignGridLayoutです。したがって、実際には、単純な高度に専門化された環境を除き、LayoutManagerを作成することはほとんどありません。

  5. 4の答えが「はい」の場合、これは、維持が困難になるLayoutManagerクラスの急増につながるのではないですか?

    (4の答えは「いいえ」です。)

  6. コンポーネントの子の間の比率を定義する必要がある状況(たとえば、子1は10%のスペースを使用し、子2は40%、子3は50%を使用する必要がある)で、カスタムLayoutManagerを実装せずにそれを達成できますか?

    Big-Threeのどれでも、GridBagでさえもできません(実際に習得する必要はありません。電力が少なすぎると、トラブルが多すぎます)。


4
少なくとも2つの状況でこのアドバイスに同意するかどうかは、完全にはわかりません。1)カスタムレンダリングされたコンポーネント2)JEditorPaneそれ自体が幅を示唆しないHTMLでの使用。OTOH何か逃したかどうかはわかりません。スレッドでの返信を注意深く確認しますが、特に後者のケースについて、コメントがあるかどうか興味を持っていました。
Andrew Thompson

2
@Andrew Thompson 1)カスタムコンプ:有用なレイアウトヒントを返すのは、コンプ自体です。インプリメントにバグがある場合、2)コアコンプでさえバグがあります;-) 3)空白を気にしません今回は意図的に、感謝します:-)
kleopatra '30 / 08/30

8
受け入れられた答えがsetXXX()メソッドの使用を避けるように言っているものであるとは信じられません。場合によっては、単にレイアウトマネージャにヒントを提供するためにそれらを必要とすることがあります。パネルをレイアウトする場合は、必要に応じてこれらのメソッドを自由に使用してください。適切なレイアウトマネージャーを使用すれば、これらのメソッドをあまり必要としないことがわかると思いますが、場合によっては単にそれらを必要とするだけです。JComboBoxまたはJSpinnerをX_AXIS BoxLayoutに入れて使用しないでください。そこにsetMaximumSize()が必要であることがわかります。
マイケル

5
@マイケルいいえ、私は絶対にそれを必要としません-答えは常にまともなLayoutManagerを使用して、マネージャーレベル(コンポーネントレベルに対して)で微調整を行うことです
kleopatra

5
「まともなLayoutManagerを使用し、必要なサイズを伝える」とStackoverflow全体で言い続けますが、「まともな」LayoutManagerの具体的な例を示すことはありません。また、標準の管理者は、サイズを直接制御することを許可していません。
Ti Strga 2014年

100

いくつかのヒューリスティック:

  • ここに示すように、独自のコンポーネントを作成するときに行われるように、set[Preferred|Maximum|Minimum]Size()本当にオーバーライドするつもりの場合は使用しないでください。get[Preferred|Maximum|Minimum]Size()

  • ここと以下に示すようset[Preferred|Maximum|Minimum]Size()に、コンポーネントの慎重にオーバーライドされたを信頼できる場合は使用しないでください。getPreferred|Maximum|Minimum]Size

  • 以下とここに示されているように、を使用set[Preferred|Maximum|Minimum]Size()してポストvalidate()ジオメトリを導出してください。

  • たとえば、コンポーネントにJDesktopPane適切なサイズがない場合、コンテナのサイズを指定する必要があるかもしれませんが、そのような選択は任意です。コメントは意図を明確にするのに役立ちます。

  • これらのコメントに記載されているように、派生サイズを取得するために多くのコンポーネントをループする必要がある場合は、代替レイアウトまたはカスタムレイアウトを検討してください。

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

import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * @see /programming/7229226
 * @see /programming/7228843
 */
public class DesignTest {

    private List<JTextField> list = new ArrayList<JTextField>();
    private JPanel panel = new JPanel();
    private JScrollPane sp = new JScrollPane(panel);

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                DesignTest id = new DesignTest();
                id.create("My Project");
            }
        });
    }

    private void addField(String name) {
        JTextField jtf = new JTextField(16);
        panel.add(new JLabel(name, JLabel.LEFT));
        panel.add(jtf);
        list.add(jtf);
    }

    private void create(String strProjectName) {
        panel.setLayout(new GridLayout(0, 1));
        addField("First Name:");
        addField("Last Name:");
        addField("Address:");
        addField("City:");
        addField("Zip Code:");
        addField("Phone:");
        addField("Email Id:");
        KeyboardFocusManager.getCurrentKeyboardFocusManager()
            .addPropertyChangeListener("permanentFocusOwner",
            new FocusDrivenScroller(panel));
        // Show half the fields
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sp.validate();
        Dimension d = sp.getPreferredSize();
        d.setSize(d.width, d.height / 2);
        sp.setPreferredSize(d);

        JInternalFrame internaFrame = new JInternalFrame();
        internaFrame.add(sp);
        internaFrame.pack();
        internaFrame.setVisible(true);

        JDesktopPane desktopPane = new JDesktopPane();
        desktopPane.add(internaFrame);

        JFrame frmtest = new JFrame();
        frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmtest.add(desktopPane);
        frmtest.pack();
        // User's preference should be read from java.util.prefs.Preferences
        frmtest.setSize(400, 300);
        frmtest.setLocationRelativeTo(null);
        frmtest.setVisible(true);
        list.get(0).requestFocusInWindow();
    }

    private static class FocusDrivenScroller implements PropertyChangeListener {

        private JComponent parent;

        public FocusDrivenScroller(JComponent parent) {
            this.parent = parent;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Component focused = (Component) evt.getNewValue();
            if (focused != null
                && SwingUtilities.isDescendingFrom(focused, parent)) {
                parent.scrollRectToVisible(focused.getBounds());
            }
        }
    }
}

2
(あなたが推測したかもしれないように)「外部要因」による推論に同意しない:XXSizeプロパティは内部のみのニーズを表すことを意図しています。外部からそれらを微調整することは誤用であり、別名ハッキングです。(内部またはJ-)フレームが必要な場合は、相対的な特定のサイズをお勧めします。コンテンツではなく、フレームのサイズを指定してください
kleopatra

2
@kleopatra:少ししつこいのですが、外部からsetXXSizeメソッドを使用してはならない場合、なぜプライベートまたは保護と宣言されていないのですか?これはデザインの欠如ではないですか?public修飾子は、それらのメソッドを使用できることを暗黙的にユーザーに伝えませんか?
ハイゼンバグ

2
@kleopatraに同意する必要setPreferredSize()があります。常にコンポーネントの計算を任意の選択に置き換えます。
trashgod '08 / 08/29

1
@trashgod +100あなたにこれらのメソッドをオーバーライドしても問題はないと思います(もちろん、これはカスタムコンポーネントがあることを意味するため、オーバーライドした方が良いでしょう)
David Kroukamp

5
@DavidKroukamp:ありがとう。私はクレオパトラのより大きな経験に固執しますが、反対の見方を批判的に検討することには価値があると思います。
trashgod

47

それらの方法の使用を完全に避けるべきですか?

いいえ、これらのメソッドの呼び出しまたはオーバーライドが許可されていないことを示唆する正式な証拠はありません。実際、オラクルはこれらのメソッドはサイズのヒントを与えるために使用されると言っています:http : //docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment

また、Swingコンポーネントを拡張するとき(カスタムコンポーネントインスタンスでメソッドを呼び出すのではなく)オーバーライドされる場合もあります(これはSwingのベストプラクティスです)。

最も重要なのは、コンポーネントのサイズを指定する方法に関係なく、コンポーネントのコンテナーが、コンポーネントの要求されたサイズを尊重するレイアウトマネージャーを使用していることを確認してください。

メソッドは理由のために定義されています。それで、いつそれらを使うべきですか?どの文脈で?何のために?

コンポーネントが適切にレイアウトされるように、コンテナーのレイアウトマネージャーにカスタマイズされたサイズのヒントを提供する必要がある場合

これらの方法を使用することの悪影響は、正確には何ですか?(私は、異なる画面解像度のシステム間での移植性を追加することしか考えられません)。

  • 多くのレイアウトマネージャーは、コンポーネントの要求された最大サイズに注意を払いません。しかし、BoxLayoutおよびSpringLayout行います。さらに、GroupLayoutコンポーネントに触れることなく、最小、優先、または最大サイズを明示的に設定する機能を提供します。

  • コンポーネントの正確なサイズを設定する必要があることを確認してください。各Swingコンポーネントには、使用するフォントとルックアンドフィールに応じて、異なる推奨サイズがあります。したがって、サイズを設定すると、さまざまなシステムでUIの外観が変化する可能性があります

  • GridBagLayoutとのテキストフィールドで問題が発生することがあります。コンテナのサイズが推奨サイズよりも小さい場合、最小サイズが使用され、テキストフィールドが大幅に縮小する可能性があります。

  • JFrameオーバーライドを強制せず、その作業をgetMinimumSize()呼び出すだけsetMinimumSize(..)

どのLayoutManagerも、必要なすべてのレイアウトニーズを正確に満たすことができるとは思いません。レイアウトの小さなバリエーションごとに新しいLayoutManagerを実装する必要がありますか?

実装することで使用する場合は、はい。1つでLayoutMangerすべてを処理できるわけではなく、それぞれLayoutManagerに長所と短所があり、それぞれを組み合わせて最終的なレイアウトを作成できます。

参照:


3
それ自体が矛盾するカスタマイズされたサイズのヒントを提供します。サイズ変更のヒント(pxで!)を提供することは、コンポーネントの唯一のタスクです。それは、自分以外の誰も知ることができない(または追跡できない)内部状態の詳細に基づいてそれらを計算します。クライアントの観点から見ると、カスタマイズの手段は、コンポーネントの適切なLayoutManagerおよび/または特殊化APIであり、これにより、「セマンティック」サイズ関連のプロパティ、テキストコンポーネントの行/列のfi数の観点からサイズ要件を構成できます
kleopatra

3
@kleopatra私は、オラクルがこれらのメソッドの使用方法と正しい使用方法を教えてくれる理由を知りたいと思っています。私たちは独自の好みを持っているかもしれませんが、これを示唆する証拠がない場合、デザイナーがそれを使用しないとメンターすることはできません。しかし、だからこそ、オラクルがこれらのメソッドをまったく使用しないと明言している信頼できるソースから情報を提供できる他の人を引き付けることができるかどうか、賞金を上げます(したがって、たとえば、setMinimumSizeをJSplitPaneなどを呼び出すと、分割ペインのOracleチュートリアルで確認できます
David Kroukamp

4
@David:たとえドキュメントがそれを示唆しているときでも、setXxxSize私はここに巻き込まれるかもしれないという赤い旗としてメソッドを見るようになりました。私はほとんど常に上書きされている必要がありますgetXxxSize1が必要なジオメトリへのアクセスを有する場合、。そして、短い例でさえ、私が考えたい以上にリサイクルされています。+1は、レイアウトマネージャー間のバリエーションについて言及し、チュートリアルを引用します。
trashgod

1
ドー、上の私のコメントで、私はここで答えを引用するつもりでした。
ゴミ箱神

13
+1「いいえ、これらのメソッドの呼び出しやオーバーライドが許可されていないことを示唆する正式な証拠はありません。」スポット。回答のタグが付けられた投稿はプレーンBSです。
TT。

25

ここには良い答えがたくさんありますが、通常はこれらを避けなければならない理由についてもう少し追加したいと思います(質問は重複したトピックで再び出てきました):

いくつかの例外はありますが、これらの方法を使用している場合は、GUIを微調整して、特定のルックアンドフィール(およびシステム固有の設定(好みのデスクトップフォントなど)で見栄えをよくする)にする必要があります。メソッド自体は本質的に悪ではありませんが、それらを使用する一般的な理由です。レイアウトでピクセルの位置とサイズの調整を始めるとすぐに、他のプラットフォームでGUIが壊れる(少なくとも、見た目が悪い)リスクがあります。

この例として、アプリケーションのデフォルトのルックアンドフィールを変更してみてください。お使いのプラットフォームで利用可能なオプションを使用していても、結果のレンダリングがどれほど不十分であるかに驚くかもしれません。

したがって、すべてのプラットフォームでGUIを機能的で見栄えのよい状態に保つことを念頭に置いて(Javaの主要な利点の1つはそのクロスプラットフォームであることを忘れないでください)、自動的にサイズを調整するためにレイアウトマネージャーなどに依存する必要があります。コンポーネントを特定の開発環境の外で正しくレンダリングできるようにします。

そうは言っても、これらの方法が正当化される状況は確かに想像できます。繰り返しますが、それらは本質的に悪ではありませんが、その使用法は通常、潜在的なGUIの問題を示す大きな赤い旗です。使用する場合は、合併症の可能性が高いことを認識していることを確認し、問題に別のルックアンドフィールに依存しない解決策があるかどうかを常に考えて考えてください。メソッドは必要ありません。

ちなみに、標準のレイアウトマネージャーに不満を感じている場合は、JGoodiesFormLayoutやなど、無料のオープンソースのサードパーティ製のものがたくさんありMigLayoutます。一部のGUIビルダーは、サードパーティのレイアウトマネージャーの組み込みサポートさえ備えています。たとえば、EclipseのWindowBuilder GUIエディターは、FormLayoutおよびのサポートが同梱されていMigLayoutます。


2
思いやりのある回答を+1- それらに同意するだけで、単にそうであるという理由だけで本質的に悪ではありません :-)通常、外部のクライアントは推測する機会がまったくありません。コンポーネント自体には、有用な情報を返すためのすべての情報が常に含まれています。そして、部外者が干渉する瞬間から、それらのヒントを最新の状態に保つことはできません。
kleopatra 2014年

1
ええと、あなたが知っているように、私は「銃は人を殺さない、人は人を殺す」このような種類の見方を持っています。:) 誰かがこれらのメソッドを使用する場合、レイアウトヒントの予測できない使用法についてあなたが提起する優れた点などに注意する必要があります(これが、これらのメソッドが適切な状況が実際にまれである理由です)。
Jason C

推奨サイズを設定することは、大きな問題ではありません。設定しないこと、代わりに大きな赤い旗です。詳しく説明します。レイアウトマネージャーは、どんなに賢くても、GUIウィジェットの論理的な機能については何も知りません。たとえば、レイアウトマネージャは、郵便番号を入力するためのJTextFieldと名前を入力するためのJTextFieldを区別できません。同様に、JTextFieldの隣のツールボタンとフォームの下部にある大きなOKボタンを区別できません。したがって、より優れたウィジェットセット、またはいくつかのサイズ変更のヒントが必要です。
Gee Bee

@GeeBee Nope、それは実際、赤旗の典型的な例です。あなたがすべきことはJTextField.setColumns、列数を設定するために使用され、それに応じて適切なサイズを調整します。その場合setPreferredSize、サイズをハードコーディングしているため、プラットフォームのフォントサイズに応じてレイアウトが壊れます。適切に呼び出されたグリッドバッグレイアウトのいくつかのテキストフィールドを次に示しsetColumnsます。ボタンについては、適切なレイアウト/グリッドの重みを使用してサイズを制御します。
Jason C

@GeeBeeそして、これが正しく行われたところで、フォントサイズを小さくすると、テキストフィールドの幅がどのように減少するかに注意してください:i.snag.gy/ZULulh.jpg。オンザフライでフォントサイズを変更する場合でも、すべてのテキストフィールドの幅を再計算して明示的に再度setPreferredSizeを呼び出す必要がなく、自動的に機能するようになりました。レイアウトを無効にしてサイズを調整するだけです。
Jason C

20

Java Swingのレイアウトに問題がある場合はFormLayout、Karsten Lentzschがここで提供しているFormsフリーウェアライブラリの一部として自由に提供されているJGoodiesを強くお勧めします

この非常に人気のあるレイアウトマネージャーは非常に柔軟性が高く、非常に洗練されたJava UIを開発できます。

Karstenのドキュメントはここにあり、Eclipseのかなり良いドキュメントはここにあります


16

これらの方法は、ほとんどの人によく理解されていません。これらの方法は絶対に無視しないでください。これらのメソッドを尊重するかどうかは、レイアウトマネージャ次第です。このページには、どのレイアウトマネージャがこれらのメソッドのどれを使用するかを示す表があります。

http://thebadprogrammer.com/swing-layout-manager-sizing/

私は8年以上Swingコードを作成しており、JDKに含まれているレイアウトマネージャーは常に私のニーズに応えてくれました。私のレイアウトを実現するために、サードパーティのレイアウトマネージャーは必要ありませんでした。

必要なことが確実になるまで、これらのメソッドを使ってレイアウトマネージャにヒントを与えないでください。サイズ変更のヒントを与えずにレイアウトを実行し(つまり、レイアウトマネージャーにその仕事を任せます)、必要に応じて小さな修正を加えることができます。


1
(私の部分の)わずかな(あなたの部分に)誤解や誤解があります、あなたの選択を取るのいずれか:-)あなたは(BoxLayoutに関連したあなたの答えでは、あなたのブログに、ここに)繰り返し続けるセット XXSize重要であるとして-実際にLayoutManagerであること、XXSizeに興味を持っている(またはしない)サイズヒントそれはおよそ来た方法についての独立した(コンポーネントまたは手動でアプリケーションコードによって強制による内部計算)
クレオパトラ

1
あなたがここで何をしているのか理解できません。XXSize()メソッドは単なるヒントであると前述しました。必要に応じて、レイアウトマネージャーに少しヒントを与えることには何の問題もありません。私のSwingコードでは、時々setXXSize()メソッドが見つかります。多くはありませんが、たまに必要なものだと思います。JComboBoxとJSpinnerは頻繁にヒントを必要とします。特に、実現後に移植されるJComboBox。あなたはこれらの方法のありとあらゆる使用に反対しているようで、私にはその理由がわかりません。(たぶん私はこれでボートを失った人かもしれません)。
マイケル

5
メソッドはヒントではなく、プロパティは次のとおりです。コンポーネントはすべてのヒントに対して妥当なものを報告する必要があり、一部(fi JComboBoxのように)はmaxIntegerを返さないなど、そうではありません。これはバグであり、コンボで修正する必要があります。あなたの習慣について:メンテナの同僚がそれを片付ける必要があるときは、遠くに離れてください:)ハードコードされたヒントは、わずかな変更でレイアウトを壊す傾向があり、レイアウトが壊れた理由として検出するのが困難です。
クレオパトラ2013

15

コンポーネントの子の間の比率を定義する必要がある状況(子1は10%のスペースを使用し、子2は40%、子3は50%を使用する必要があります)で、カスタムレイアウトマネージャーを実装せずにそれを達成できますか?

多分GridBagLayoutあなたのニーズを満たすでしょう。その上、ウェブ上にはたくさんのレイアウトマネージャーがあり、私はあなたの要件に合うものがあると思います。


答えてくれてありがとう。「setPreferredSizeをまったく使用しないでください」という意味もあると思いますが、そうですか。
ハイゼンバグ

1
GridBagLayoutは制約を使用します。この場合、特定のコンポーネントのXとYの両方で「重み」を指定できるため、LayoutManagerはサイズ変更時に追加のスペースをどうするかを決定できます。しかし、あなたはまだ決定しsetPreferredSizeを使用することができます/必要な推奨サイズ各コンポーネントの、「好ましい」というノートを、常に光栄になるだろうという意味ではありません。特別なケースでは、とにかくsetMinimumSizeとsetMaximumSizeも必要になる場合があります。彼らは邪悪ではない、それを購入しないでください。docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
ちゃんだよ

5

受け入れられた回答とは異なるように見えます。

1)それらの方法の使用を完全に避けるべきですか?

絶対に避けないでください!これらは、コンポーネントのサイズ制限をレイアウトマネージャーに伝えるためにあります。レイアウトマネージャーを使用していない場合は、これらを使用せずに、視覚的なレイアウトを自分で管理することができます。

残念ながら、Swingには適切なデフォルトの寸法がありません。ただし、コンポーネントのディメンションを設定する代わりに、妥当なデフォルトで独自のコンポーネントを継承する方がOOPの方が適しています。(その場合、子孫クラスでsetXXXを呼び出します。)あるいは、同じ効果を得るためにgetXXXメソッドをオーバーライドできます。

2)メソッドは理由のために定義されています。それで、いつそれらを使うべきですか?どの文脈で?何のために?

常に。コンポーネントを作成するときは、そのコンポーネントの用途に応じて、現実的な最小/推奨/最大サイズを設定します。たとえば、UKなどの国の記号を入力するためのJTextFieldがある場合、その推奨サイズは2文字(現在のフォントなど)に合わせてできるだけ広くなりますが、おそらくそれ以上大きくしても意味がありません。結局のところ、国の記号は2文字です。反対に、たとえば顧客名を入力するためのJTextFieldがある場合、20文字のピクセルサイズのように適切なサイズにすることができますが、レイアウトのサイズを変更すると大きくなる可能性があるため、最大サイズをさらに大きく設定します。同時に、幅が0pxのJTextFieldは無意味なので、現実的な最小サイズを設定します(ピクセルサイズは2文字です)。

3)これらの方法を使用すると、どのような悪影響がありますか?

(私は、異なる画面解像度のシステム間で移植性を追加することしか考えられません)。

悪影響はありません。これらは、レイアウトマネージャのヒントです。

4)LayoutManagerが、すべての望ましいレイアウトのニーズを正確に満たすことができるとは思いません。

レイアウトの小さなバリエーションごとに新しいLayoutManagerを実装する必要がありますか?

いいえ、違います。通常のアプローチは、水平レイアウトや垂直レイアウトなど、さまざまな基本的なレイアウトマネージャーをカスケードすることです。

たとえば、次のレイアウト:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

2つの部分があります。左と右のパーツは水平レイアウトです。右は横置きレイアウトにJPanelを追加したもので、このJPanelはボタンを縦に配置する縦置きレイアウトになっています。

もちろん、これは実際のレイアウトでは注意が必要です。したがって、深刻なものを開発しようとしている場合は、MigLayoutなどのグリッドベースのレイアウトマネージャーがはるかに優れています。

5)4の答えが「はい」の場合、LayoutManagerクラスが急増し、保守が困難になることはありませんか?

いいえ、特別なものが必要でない限り、レイアウトマネージャーを開発することは絶対にしないでください。

6)比率を定義する必要がある状況では...

コンポーネントの子の間(たとえば、child1は10%のスペース、child2 40%、child3 50%を使用する必要があります)、カスタムLayoutManagerを実装せずにそれを達成することは可能ですか?

基本的に、推奨サイズが正しく設定されると、パーセンテージで何も実行したくない場合があります。単純に、パーセンテージは無意味です(たとえば、JTextFieldがウィンドウサイズの10%であっても意味がありません。JTextFieldが0px幅になるようにウィンドウを縮小したり、JTextFieldが2つのディスプレイにまたがるようにウィンドウを拡張したりできるためです。マルチディスプレイ設定)。

しかし、パーセンテージを使用して、GUIのより大きなビルディングブロックのサイズを制御する場合があります(たとえば、パネル)。

JSplitPaneを使用して、2つの辺の比率を事前に設定できます。または、MigLayoutを使用して、そのような制約をパーセンテージ、ピクセル、その他の単位で設定できます。


本当に?これは0でしたか?これは、100以上のupsを持つ受け入れられた回答よりも優れています。それは基本的に「ネバーはsetPreferredSizeを使うべきだ!」ひどいです。私の仕事では、「タッチスクリーンのボタンは[X] x [Y]で、[M] x [N]の間隔を空ける必要がある」という安全要件など、特定のサイズ要件のLOTがあります。btnBar.setPreferredSize( dimTouchBtn );それを行う最善の方法です。簡単で、カスタムレイアウトマネージャーは必要ありません。私は主GridBagLayoutにいくつかのBorderLayoutとを使用しBoxLayout、便利なときにネストします。これは強力な組み合わせで使いやすいです。
Loduwijk 2017年

上記のコメントで私は急いでいました。これは、受け入れられた回答の後に私が見た最初の回答でした。SOが投票数でソートされなくなったのはなぜですか?もともと投票数の核心的な理由の一つだと思いました。それでも、私は元のコメントをまだ支持しています。これはより良い答えの1つです。そのポイント#6を除いて-それはそれほど良くありません。サイズを変更する理由はたくさんありますが(マイノリティは依然として多数である可能性があります)、GridBagLayoutは、私が経験したほとんどの場合にそれをサポートしています。
Loduwijk 2017年

私は、サイズを変更することとサイズを変更しないことは、宗教的な決定として扱われるべきではないと思います。たとえば、キオスク用のGUIを開発し、事前に設定された固定解像度で開発する場合など、誰も何もサイズ変更したくない場合があります。工業用HMIディスプレイや「ボタン」のケースなど、さまざまなターゲットがある場合、そうです、タッチスクリーンのボタンには少なくとも1cm x 1cmが必要です。この場合、画面のDPIはサイズ変更の方法を設定します。テキストフィールドなどの他の入力は、垂直方向にサイズ変更されない場合があり、(郵便番号などの)水平方向のサイズ変更も無意味な場合があります。
Gee Bee

0

それらの方法の使用を完全に避けるべきですか? 私はそれらを「避ける」とは言いません。あなたがそれらが必要だと思うなら、あなたはおそらく何か間違ったことをしていると私は言うでしょう。コンポーネントのサイズは状況に応じて決定されます。たとえば、テキストコンポーネントのサイズは、指定した行と列の数と、選択したフォントとの組み合わせによって決まります。ボタンとラベルのサイズは、設定した場合はグラフィックのサイズ、または設定したテキストを表示するために必要なスペースになります。各コンポーネントには自然なサイズがあり、レイアウトマネージャーはそれらを使用して、サイズを指定する必要なくすべてをレイアウトします。主な例外はJScrollPaneで、JScrollPaneには含まれているものとは独立したサイズがあります。それらのために、私は時々を呼び出しsetSize()、そのサイズに次の呼び出しによって初期ウィンドウサイズを決定させますJFrame.pack()。通常は、ウィンドウサイズでJScrollPaneのサイズを決定します。ユーザーがウィンドウのサイズを決定します。多くのレイアウトマネージャは、設定したサイズを無視します。そのため、多くの場合、あまり効果がありません。

メソッドは理由のために定義されています。それで、いつそれらを使うべきですか?どの文脈で?何のために? レイアウトマネージャーにヒントを提供するために追加されたと思います。レイアウトマネージャーは新しいものであり、人々はそれらを完全に信頼していなかったため、歴史的な理由で作成された可能性があります。新しいパラダイムの学習に煩わされたくないという理由だけで、レイアウトマネージャーを避けてすべてを手動で配置した開発者が何人かいます。それはひどい考えです。

これらの方法を使用することの悪影響は、正確には何ですか?(私は、異なる画面解像度のシステム間で移植性を追加することしか考えられません) それらは効果がなく、オブジェクトのレイアウトが不自然になり、オブジェクトが非自然なサイズに圧縮または引き伸ばされます。そして、レイアウトはもろくなります。ウィンドウサイズを変更すると、レイアウトが壊れて、間違った場所に配置されることがあります。

どのLayoutManagerでも、必要なすべてのレイアウトニーズを正確に満たすことができるとは思いません。レイアウトの小さなバリエーションごとに新しいLayoutManagerを実装する必要がありますか?新しいLayoutManagerを「実装」しないでください。既存のものをインスタンス化する必要があります。1つのウィンドウで複数のレイアウトマネージャを使用することがよくあります。各JPanelには独自のレイアウトマネージャーがあります。一部の人々は、維持が難しいため、ネストされたレイアウトに悩んでいます。それらを使用するときは、それぞれに独自の作成方法を与えて、それぞれが何をするのかを簡単に確認できるようにします。しかし、レイアウトマネージャーを「実装」することはありません。それらをインスタンス化するだけです。

4の答えが「はい」の場合、これは、維持が困難になるLayoutManagerクラスの急増につながるのではないですか? レイアウトのわずかなバリエーションに対して新しいレイアウトマネージャークラスを実装している場合、それらを間違って使用しています。新しいレイアウトマネージャを実装しているだけなら、おそらく何かがおかしいでしょう。LayoutManagerクラスを拡張したのは、JScrollPaneにズームスライダーを追加するときだけでした。

コンポーネントの子の間の比率を定義する必要がある状況(たとえば、child1は10%のスペースを使用し、child2 40%、child3 50%を使用する必要があります)で、カスタムLayoutManagerを実装せずにそれを達成できますか? JSplitPaneには、各コンポーネントが取得する必要があるパーセンテージを指定する方法があります。デバイダーはデフォルトで移動可能ですが、必要に応じてオフにできます。その機能はあまり使いません。通常、設定されたサイズを占めるコンポーネントがいくつかあり、残りのスペースはスクロール区画によって占められます。スクロールペインのサイズはウィンドウのサイズに合わせて調整されます。スクロールペインが2つ並んでいる場合は、それらをJSplitPaneに配置し、ユーザーがウィンドウを拡大または縮小するときに、それぞれに割り当てられる新しいスペースの割合を指定できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.