3

複数のパネルを持つアプリケーションがあります。パネルごとに異なるレイアウトマネージャーを自由に使用できるようにしたいのですが、ユーザーがウィンドウのサイズを変更しても同じように動作するようにしたいと思います。

    package example;

    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;

    import javax.swing.BoxLayout;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTabbedPane;
    import javax.swing.JTextField;

    public class TP1 extends JFrame
    {
        public static void main(String[] args)
        {
            TP1 tp1 = new TP1();
            tp1.go();
        }

        public void go()
        {
            setDefaultCloseOperation(EXIT_ON_CLOSE);

            // create a panel with some labels on it
            JPanel innerFirst = new JPanel();
            innerFirst.setLayout(new BoxLayout(innerFirst, BoxLayout.PAGE_AXIS));
            innerFirst.add(new JLabel("one"));
            innerFirst.add(new JLabel("two"));
            innerFirst.add(new JLabel("three"));
            innerFirst.add(new JLabel("four"));

            // put that panel in a scroll pane
            JScrollPane firstSP = new JScrollPane(innerFirst);

            // make another panel and put our scrolled panel in it
            JPanel outerFirst = new JPanel(); 
            outerFirst.setLayout(new BoxLayout(outerFirst, BoxLayout.PAGE_AXIS));
            outerFirst.add(firstSP); 

            // create a GridBagLayout panel with some text fields on it
            JPanel innerSecond = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = .25;
            gbc.anchor = GridBagConstraints.LINE_START;
            innerSecond.add(new JTextField(8), gbc);
            gbc.gridx = 0;
            gbc.gridy = 1;
            innerSecond.add(new JTextField(10), gbc);
            gbc.gridx =0;
            gbc.gridy = 2;
            innerSecond.add(new JTextField(12), gbc);

            // put that panel in a scroll pane
            JScrollPane secondSP = new JScrollPane(innerSecond);

            // make another panel and put our second scrolled panel in it
            JPanel outerSecond = new JPanel(); 
            outerSecond.setLayout(new BoxLayout(outerSecond, BoxLayout.LINE_AXIS));
            outerSecond.add(secondSP); 

            JPanel innerThird = new JPanel(new GridBagLayout());
            GridBagConstraints gbc3 = new GridBagConstraints();
            gbc3.anchor = GridBagConstraints.LINE_END;
            gbc.weightx = .25;
            gbc3.gridx = 0;
            gbc3.gridy = 0;
            innerThird.add(new JLabel("1st label"), gbc3);
            gbc3.gridy = 1;
            innerThird.add(new JLabel("second label"), gbc3);
            gbc3.gridy = 2;
            innerThird.add(new JLabel("IIIrd label"), gbc3);

            gbc3.anchor = GridBagConstraints.LINE_START;
            gbc3.gridx = 1;
            gbc3.gridy = 0;
            innerThird.add(new JTextField(8), gbc3);
            gbc3.gridy = 1;
            innerThird.add(new JTextField(12), gbc3);
            gbc3.gridy = 2;
            innerThird.add(new JTextField(14), gbc3);

            JScrollPane thirdSP = new JScrollPane(innerThird);
            JPanel outerThird = new JPanel();
            outerThird.setLayout(new BoxLayout(outerThird, BoxLayout.LINE_AXIS));
            outerThird.add(thirdSP);

            // put the scrolled panes onto a tabbed pane
            JTabbedPane tp = new JTabbedPane();
            tp.add("text fields", outerSecond);
            tp.add("labels", outerFirst);
            tp.add("mixed", outerThird);

            // add the tabbed pane to the frame
            this.add(tp);

            // pack it and ship it.
            pack();
            setVisible(true);
        }
    }

上記のコードを実行すると、3つのタブがあるタブ付きペインのあるウィンドウが表示されます。ウィンドウを小さくすると、意図したとおり、すべてのウィンドウにスクロールバーが表示されます。大きくすると、3つの動作が異なります。ラベルのあるタブではウィンドウの左上にのみ表示され、フィールドのあるタブでは左端の垂直方向にのみ中央揃えになり、ラベルとフィールドが混在するグリッドバッグのあるタブでは動作が異なります。拡大されたウィンドウで、それらを水平方向と垂直方向の両方の中央に配置します。

これはアプリケーションには受け入れられません。どういうわけか、すべてのパネルをこのように同じように動作させる必要があります。それらすべてにスクロールバーが必要です。ウィンドウが内部パネルよりも大きくなった場合は、それらすべてを左上に保持してほしいと思います。

もう1つの要件:私のタブはJPanelを拡張するもので占められています。JScrollPaneをタブに直接配置する前に言われましたが、私のアプリケーションではそれもしたくありません。それは、他のものを必要以上に複雑にするだけです。

余分なスペースをすべて右下に配置することに加えて、これら3つの状況が異なる動作をする理由を理解したいと思います。例を左右にコピーして、うまくいくまで試行錯誤するのではなく、自分たちがやっていることの背後にある原則を理解すれば、私たち全員がもっとうまくいくと今でも信じています。

(ちなみに、左上に引き寄せられているように見えるGroupLayoutパネルがありますが、私の質問には必要ないと思いました。これは100行のコードです。)

4

2 に答える 2

2

私たちがしていることの背後にある原則を理解すれば、私たち全員がより良くなると今でも信じています。

さまざまなレイアウトマネージャーの実例と説明については、レイアウトマネージャーのビジュアルガイドを参照してください。特定のレイアウトマネージャーでさまざまな制約がどのように使用されるかを学ぶ必要があります。

于 2012-02-09T04:33:41.087 に答える
2

これがコードで発生する理由を理解するには、特定の用語を理解する必要があるようです。たとえば、PAGE_AXIS、LINE_AXIS、LINE_END、LINE_STARTなどです。それらを制約として提供しているので、これらは、次のように、コンテナに追加されるコンポーネントの方向とその開始点を説明するものです。

innerFirst.setLayout(new BoxLayout(innerFirst, BoxLayout.PAGE_AXIS));

ここでは、ページの先頭を参照するポイントからコンポーネントの追加を開始するようにBoxLayoutに指示します。(メモ帳を起動すると、カーソルは新しいドキュメントのPAGE_AXISに置かれます)。しかし、あなたがこれを書いているとき:

JPanel innerSecond = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = .25;
gbc.anchor = GridBagConstraints.LINE_START;

ここで、アンカーという用語は、コンポーネントがその表示領域よりも小さい場合に使用されます。表示領域内のどこにコンポーネントを配置するかを決定します。しかし、ここであなたがそれがLINE_START意味する価値を持っていると言ったので:

Place the component centered along the edge of its display area where lines of text 
would normally begin for the current ComponentOrientation. Equal to WEST for horizontal,
left-to-right orientations and EAST for horizontal, right-to-left orientations.

そのため、JTextFields作成した3つは、左側の中央に表示されます。

于 2012-02-09T09:45:22.710 に答える