java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

SwingのLayoutManager

投稿日:

最終更新日:2016年11月20日

アイキャッチ

こんにちは。

今回は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メソッドの内容を以下のようにします。

ソース

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Test2 extends JFrame {

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

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

        init();

        setVisible(true);

    }

    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(Component comp)メソッドを使います。

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

ソース

import java.awt.Color;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Test4 extends JFrame {

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

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

        init();

        setVisible(true);

    }

    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でした。この間隔を調節するには、例えば、以下のように記述します。(「setLayout(new FlowLayout());」の代わりに。)

ソース

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());」の代わりに。)

ソース

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()を使った例のみを紹介します。

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

ソース

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Test7 extends JFrame {

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

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

        init();

        setVisible(true);

    }

    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行のレイアウトを作成します。

ソース

import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class Test8 extends JFrame {

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

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

        init();

        setVisible(true);

    }

    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());」の代わりに。)

ソース

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の等しいサイズのコンポーネントが配置されます。

以上、参考になれば幸いです。