こんにちは。ハンドルネーム「Javaを復習する初心者」です。このサイトはプログラミング言語Javaの復習・学習をするブログです。プログラムの開発・実行はEclipseで行ってます。
スポンサーリンク
お知らせ
  • 参考文献のページ作りました。
  • Amazon.co.jpアソシエイトに参加していますが、参考文献の紹介はもしもアフィリエイトに統一しました。
  • 2016年10月9日からは投稿ペースを落とします。週1回くらいにする予定です。
スポンサーリンク

SwingのLayoutManager

こんにちは。「Javaを復習する初心者」です。Swingでラベルを配置するプログラムを確認しました。

JavaにはSwingと呼ばれるGUIライブラリが用意されています。今回はJFrameクラスにJLabelクラスのインスタンスを設置するということをやりました。基本的にコンポーネントの配置は自動で決まります。LayoutManagerというインターフェースがあり、この実装クラスがコンポーネントの配置を管理します。JLabelというクラスは、短いテキスト文字列やイメージの表示領域を扱うことができます。このクラスのインスタンスを生成して、JFrameに追加していきます。

今回はLayoutManagerをいくつか紹介します。

雛形

今回は以下のプログラムを雛形として使います。

import javax.swing.JFrame;

public class Test extends JFrame {

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

    public Test() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(350, 250);

        init();

        setVisible(true);

    }

    private void init() {
        // 設置処理
    }

}

setVisibleメソッドでフレームを表示する前に、自前のinitメソッドを呼び出しています。実験した結果、描画処理が上手くいかなかったのでこの順序にしました。

BorderLayout

JFrameに設定されているLayoutManagerの初期値のクラスはBorderLayoutです。

BorderLayoutはコンポーネントを以下の5つの領域に収まるように大きさを自動的に調節して配置します。

  • center (中央)
  • east (右端)
  • north (上端)
  • south (下端)
  • west (左端)

BorderLayoutクラスには上記に対応するstaticフィールドCENTER、EAST、NORTH、SOUTH、WESTが定義されています。

実際の配置には、add(Component comp, Object constraints)メソッドを使います。第2引数で配置先の位置を上記のフィールドで指定します。add(Component comp)の場合、自動的に中央に配置されます。

例えば、initメソッドの内容を以下のようにします。

    private void init() {
        // 設置処理
        Border border = new LineBorder(Color.RED);

        JLabel label1 = new JLabel("ラベル1");
        label1.setBorder(border);
        add(label1);

        JLabel label2 = new JLabel("ラベル2");
        label2.setBorder(border);
        add(label2, BorderLayout.NORTH);

        JLabel label3 = new JLabel("ラベル3");
        label3.setBorder(border);
        add(label3, BorderLayout.SOUTH);

        JLabel label4 = new JLabel("ラベル4");
        label4.setBorder(border);
        add(label4, BorderLayout.EAST);

        JLabel label5 = new JLabel("ラベル5");
        label5.setBorder(border);
        add(label5, BorderLayout.WEST);
    }

setBorderメソッドを使っているのは境界線の描画のためです。詳しくは述べません。

以下が表示結果です。自動的に大きさが調節されて配置されています。

swing_day003001_borderlayout_1

注意として、画面の大きさを変えても、配置は変化しません。大きさが変化します。

調べた結果、初期状態ではコンポーネント間の水平方向の間隔、垂直方向の間隔は0でした。この間隔を調節するためには2つの方法があります。

  • コンストラクタBorderLayout(int hgap, int vgap)を使う。
  • setHgapメソッド、setVgapメソッドを使う。

例えば、initメソッドの先頭に以下のように記述します。

        setLayout(new BorderLayout(10, 20));

swing_day003001_borderlayout_2

上記のようにコンストラクタは以下の2つです。

  • BorderLayout()
  • BorderLayout(int hgap, int vgap)

BorderLayout()ではコンポーネント間の間隔が0であることが注意点です。

FlowLayout

FlowLayoutはコンポーネントでは右端で折り返して配置されます。初期状態では中央寄せで配置されます。また、addメソッドはadd(Component comp)メソッドを使います。

JFrameで使う場合はsetLayoutでFlowLayoutオブジェクトを指定します。例えば、以下のように記述します。

    private void init() {
        setLayout(new FlowLayout());
        // 設置処理
        Border border = new LineBorder(Color.RED);

        JLabel label1 = new JLabel("ラベル1A");
        label1.setBorder(border);
        add(label1);

        JLabel label2 = new JLabel("ラベル2AB");
        label2.setBorder(border);
        add(label2);

        JLabel label3 = new JLabel("ラベル3ABC");
        label3.setBorder(border);
        add(label3);

        JLabel label4 = new JLabel("ラベル4ABCD");
        label4.setBorder(border);
        add(label4);

        JLabel label5 = new JLabel("ラベル5ABCDE");
        label5.setBorder(border);
        add(label5);
    }

swing_day003002_flowlayout_1

調べた結果、初期状態ではコンポーネント間の水平方向の間隔、垂直方向の間隔は5でした。この間隔を調節するには、例えば、以下のように記述します。

        FlowLayout flowLayout = new FlowLayout();
        flowLayout.setHgap(10);
        flowLayout.setVgap(20);
        setLayout(flowLayout);

swing_day003002_flowlayout_2

配置は以下のコンストラクタで調節することが可能です。

  • FlowLayout(int align)
  • FlowLayout(int align, int hgap, int vgap)

第1引数にはFlowLayoutクラスに定義されているフィールド、FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING、FlowLayout.TRAILINGのいずれかを指定します。

例えば左寄せにする場合、以下のように記述します。

        setLayout(new FlowLayout(FlowLayout.LEFT, 10, 20));

swing_day003002_flowlayout_3

1段目は左寄せか判断できませんが、2段目のコンポーネントの配置を見ると、左寄せになっていることが分かります。

上記のようにコンストラクタは以下の3つがあります。

  • FlowLayout()
  • FlowLayout(int align)
  • FlowLayout(int align, int hgap, int vgap)

FlowLayout()では中央揃え、水平および垂直方向の間隔が5であることが注意点です。

CardLayout

CardLayoutではカードを重ねるような配置をすることができます。CardLayout#nextメソッドで次のカードを表示することができます。

コンストラクタは以下の2つがあります。

  • CardLayout()
  • CardLayout(int hgap, int vgap)

ここではCardLayout()を使った例のみを紹介します。

以下は、クリックすると表示が変わる例です。

    private void init() {
        CardLayout cardLayout = new CardLayout();
        setLayout(cardLayout);
        // 設置処理
        Border border = new LineBorder(Color.RED);

        JLabel label1 = new JLabel("ラベル1A");
        label1.setBorder(border);
        add(label1);

        JLabel label2 = new JLabel("ラベル2AB");
        label2.setBorder(border);
        add(label2);

        JLabel label3 = new JLabel("ラベル3ABC");
        label3.setBorder(border);
        add(label3);

        JLabel label4 = new JLabel("ラベル4ABCD");
        label4.setBorder(border);
        add(label4);

        JLabel label5 = new JLabel("ラベル5ABCDE");
        label5.setBorder(border);
        add(label5);

        JLabel[] labels = { label1, label2, label3, label4, label5 };
        for (JLabel label : labels) {
            label.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    cardLayout.next(getContentPane());
                }
            });
        }
    }

各ラベルのaddMouseListenerメソッドでMouseAdapterを登録しています。マウスでラベルをクリックすると次のラベルに表示が変わります。

初期表示

swing_day003003_cardlayout_1

クリック後

swing_day003003_cardlayout_2

コンポーネントの大きさは自動で領域全体に広がるようです。

GridLayout

GridLayoutではコンポーネントを格子状に並べることができます。配置されるコンポーネントは等しいサイズになります。

コンストラクタは以下の3つがあります。

  • GridLayout()
  • GridLayout(int rows, int cols)
  • GridLayout(int rows, int cols, int hgap, int vgap)

GridLayout()は1行のレイアウトを作成します。

    private void init() {
        setLayout(new GridLayout());
        // 設置処理
        Border border = new LineBorder(Color.RED);

        JLabel label1 = new JLabel("ラベル1A");
        label1.setBorder(border);
        add(label1);

        JLabel label2 = new JLabel("ラベル2AB");
        label2.setBorder(border);
        add(label2);

        JLabel label3 = new JLabel("ラベル3ABC");
        label3.setBorder(border);
        add(label3);

        JLabel label4 = new JLabel("ラベル4ABCD");
        label4.setBorder(border);
        add(label4);

        JLabel label5 = new JLabel("ラベル5ABCDE");
        label5.setBorder(border);
        add(label5);
    }

swing_day003004_gridlayout_1

GridLayout(int rows, int cols)は指定された行と列でコンポーネントを配置します。

例えば、以下のように指定します。

        setLayout(new GridLayout(2, 3));

swing_day003004_gridlayout_2

GridLayout(int rows, int cols, int hgap, int vgap)では水平方向の間隔と垂直方向の間隔を指定することができます。

例えば次のように指定します。

        setLayout(new GridLayout(2, 3, 10, 20));

swing_day003004_gridlayout_3

水平方向の間隔10、垂直方向の間隔20の等しいサイズのコンポーネントが配置されます。