4

ボタン (X)、ラベル (Y)、進行状況バー (Z) で構成されるパネルがあります。理想的には、次のようにレイアウトしたいと思います。

| X-X Y---------------Y Z---Z ============= |  <-- expanded-size panel
                              ^ extra space

| X-X Y------Y Z---Z |                         <-- reduced-size panel

上の図は、次のことを示しています。

  • パネルが拡張されると、ラベルがテキストを完全に表示できるように、余分なスペースをラベル (Y) に配置する必要があります。
  • プログレス バー (Z) は常にラベル (Y) の横にある必要があります。
  • パネルを縮小する場合は、ラベル (Y) のサイズを縮小する必要があります。
  • ボタン (X) とプログレス バー (Z) のサイズは、ラベル (Y) のサイズではなく、一定にする必要があります。

ただし、GroupLayout を使用しようとすると、パネルが展開されると次のようになります。

| X-X Y---------------Y ============= Z---Z |  <-- expanded-size panel (bad)

問題は、パネルに余分なスペースがある場合、ラベル (Y) が必要以上に拡張され、プログレス バー (Z) が右に押し出されることです。プログレス バー (Z) の位置がラベル (Y) の隣にあることをお勧めします。

このレイアウトを実現するにはどうすればよいですか?

コード例 (「Blah.java」):

import java.awt.*;
import javax.swing.*;

public class Blah extends JPanel {
    public Blah() {
        final JButton X = new JButton("X");
        final JLabel Y = new JLabel("yyyyyyyyyyy");
        Y.setOpaque(true);
        Y.setBackground(Color.YELLOW);
        final JProgressBar Z = new JProgressBar();
        Z.setIndeterminate(true);

        final GroupLayout l = new GroupLayout(this);
        super.setLayout(l);

        l.setHorizontalGroup(
                l.createSequentialGroup()
                .addComponent(X, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addComponent(Y, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(Z, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE));

        l.setVerticalGroup(
                l.createParallelGroup()
                .addComponent(X)
                .addComponent(Y)
                .addComponent(Z));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame frame = new JFrame("Blah");
                frame.add(new Blah());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
4

2 に答える 2

4

1 人のレイアウト マネージャーがすべてのニーズを満たすことはほとんどありません。代わりに、複合レイアウト アプローチを使用できます。

つまり、個々のレイアウト要件を個別のコンポーネントに分離し、独自のレイアウト マネージャーを使用します。次に、これらすべてをマスター コンポーネントに追加し、全体的な要件を管理します。

例として

ここに画像の説明を入力ここに画像の説明を入力

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class SimpleGridBagLayout {

    public static void main(String[] args) {
        new SimpleGridBagLayout();
    }

    public SimpleGridBagLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            add(createLabel("XXX-XXX", Color.BLUE), gbc);

            JPanel panel = new JPanel();
            panel.add(createLabel("Y-Y", Color.RED));
            panel.add(createLabel("ZZZZZ---ZZZZZ", Color.GREEN), gbc);

            gbc.gridx++;
            gbc.weightx = 1;
            add(panel, gbc);

        }

        protected JLabel createLabel(String text, Color border) {

            JLabel label = new JLabel(text);
            label.setBorder(new LineBorder(border));
            return label;

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 100);
        }
    }

}

ここには多くの要因が関係しています。子コンポーネントの優先サイズと最小サイズは、使用可能なサイズが小さすぎる場合に、一部のレイアウト マネージャーがコンポーネントをレイアウトする方法に大きな違いをもたらします。

更新しました

public TestPane() {

    setLayout(new GridBagLayout());

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 0;
    add(createLabel("XXX-XXX", Color.BLUE), gbc);

    JPanel panel = new JPanel(new GridBagLayout());
    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    panel.add(createLabel("Y-Y", Color.RED), gbc);
    gbc.gridx = 1;
    panel.add(createLabel("ZZZZZ---ZZZZZ", Color.GREEN), gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 1;
    gbc.weightx = 1;
    add(panel, gbc);

}

更新しました

「縮小しない」プログレスバーが追加されました

public class TestPane extends JPanel {

    public TestPane() {

        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        add(createLabel("XXX-XXX", Color.BLUE), gbc);

        JPanel panel = new JPanel(new GridBagLayout());
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        panel.add(createLabel("Y-Y", Color.RED), gbc);
        gbc.gridx = 1;
        MyProgressBar pb = new MyProgressBar();
        panel.add(pb, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.weightx = 1;
        add(panel, gbc);

    }

    protected JLabel createLabel(String text, Color border) {

        JLabel label = new JLabel(text);
        label.setBorder(new LineBorder(border));
        return label;

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 100);
    }
}

public class MyProgressBar extends JProgressBar {

    @Override
    public Dimension getPreferredSize() {
        Dimension ps = super.getPreferredSize();
        ps.width = 75;
        return ps;
    }

    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }

}
于 2013-07-09T01:05:43.413 に答える
0

あまりにも長い間頭を壁にぶつけた後、私はSpringLayoutのチュートリアル ( http://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html )で、この小さな貴重なドキュメントを発見しました。

コンポーネントのgetMaximumSizegetPreferredSizeメソッドが同じ値を返す場合、SpringLayoutはこれを、コンポーネントを引き延ばしてはならないことを意味すると解釈します。

したがって、との最大サイズSpringLayoutを手動で設定すると、上記の理想的なレイアウトを実現できます。コードは次のとおりです。YZ

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Blah extends JPanel {
    public Blah() {
        final JButton X = new JButton("X");
        final JLabel Y = new JLabel("yyyyyyyyyyy");
        Y.setOpaque(true);
        Y.setBackground(Color.YELLOW);
        final JProgressBar Z = new JProgressBar();
        Z.setIndeterminate(true);

        final SpringLayout l = new SpringLayout();
        super.setLayout(l);

        super.add(X);
        super.add(Y);
        super.add(Z);

        Z.setMaximumSize(Z.getPreferredSize());

        l.putConstraint(SpringLayout.WEST, X, 10, SpringLayout.WEST, this);
        l.putConstraint(SpringLayout.WEST, Y, 10, SpringLayout.EAST, X);
        l.putConstraint(SpringLayout.WEST, Z, 10, SpringLayout.EAST, Y);
        l.putConstraint(SpringLayout.EAST, this, 10, SpringLayout.EAST, Z);

        l.putConstraint(SpringLayout.NORTH, X, 10, SpringLayout.NORTH, this);
        l.putConstraint(SpringLayout.NORTH, Y, 10, SpringLayout.NORTH, this);
        l.putConstraint(SpringLayout.NORTH, Z, 10, SpringLayout.NORTH, this);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame frame = new JFrame("Blah");
                frame.add(new Blah());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
于 2013-07-11T01:41:06.997 に答える