こんにちは。
今回は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メソッドを使っているのは境界線の描画のためです。詳細は省きますが、そこの部分で境界線を設定します。
以下が表示結果です。自動的に大きさが調節されて配置されています。

注意として、画面の大きさを変えても、配置は変化しません。大きさが変化します。
調べた結果、初期状態ではコンポーネント間の水平方向の間隔、垂直方向の間隔は0でした。この間隔を調節するためには2つの方法があります。
- コンストラクタBorderLayout(int hgap, int vgap)を使う。
- setHgapメソッド、setVgapメソッドを使う。
例えば、initメソッドの先頭に以下のように記述します。
ソース
setLayout(new BorderLayout(10, 20));

上記のようにコンストラクタは以下の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);
}
}

調べた結果、初期状態ではコンポーネント間の水平方向の間隔、垂直方向の間隔は5でした。この間隔を調節するには、例えば、以下のように記述します。(「setLayout(new FlowLayout());」の代わりに。)
ソース
FlowLayout flowLayout = new FlowLayout();
flowLayout.setHgap(10);
flowLayout.setVgap(20);
setLayout(flowLayout);

配置は以下のコンストラクタで調節することが可能です。
- 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));

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を登録しています。マウスでラベルをクリックすると次のラベルに表示が変わります。
- 初期表示
-
- クリック後
-
コンポーネントの大きさは自動で領域全体に広がるようです。
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);
}
}

GridLayout(int rows, int cols)は指定された行と列でコンポーネントを配置します。
例えば、以下のように指定します。(「setLayout(new GridLayout());」の代わりに。)
ソース
setLayout(new GridLayout(2, 3));

GridLayout(int rows, int cols, int hgap, int vgap)では水平方向の間隔と垂直方向の間隔を指定することができます。
例えば次のように指定します。
ソース
setLayout(new GridLayout(2, 3, 10, 20));

水平方向の間隔10、垂直方向の間隔20の等しいサイズのコンポーネントが配置されます。
以上、参考になれば幸いです。