トップ » 技術記事 » Java の MiGLayout で超簡単にGUIアプリを作る方法

Java の MiGLayout で超簡単にGUIアプリを作る方法

タグ: GUI Java MigLayout Swing

歴史的な経緯もあり Java で GUI のアプリを作るとデザインがいまいちというイメージがあります。しかし、最近の Swing はそこそこ頑張っているという話を聞きました。そこで、以前より気になっていた、MigLayout というレイアウトマネージャを使って、Java の Swing + MiGLayout で簡単な顧客データの入力フォームを作ってみます。

Swing について

Java に詳しい人で、Swing を知らない人はいないと思います。Swing は、Java の開発環境 JDK に標準で付属するGUIコンポーネントライブラリです。実行環境に依存しない統一されたデザインを実現できます。また、見た目(look and feel)を切り替えることもできます。

MiGLayout について

今回、Swing と共に挑戦するのは、Swing のコンポーネントを手軽で綺麗に配置できるレイアウトマネージャー「MigLayout」です。MiGLayout は Swing/SWT のために開発されたレイアウトマネージャーです。BSDライセンスで公開されているので自由に扱うことができます。

上記のページでは、チュートリアルの他、クリックしてすぐ実行できる Java Web Start(JNLP)も用意されています。

http://aoikujira.com/demo/hakkaku/rc/20090715hzzeD-mig-demo.png

コンポーネントをかなり複雑にレイアウトしているデモも多く、ソースコードも同時に見ることができるようになっています。

MiGLayout のダウンロード

デモを一通り見て楽しんだら、MiGLayout の jar ファイルをダウンロードしておきましょう。筆者は原稿執筆時点で最新の 3.7 の miglayout-3.7.jar をダウンロードしてみました。(Swing からしか使わない場合は、miglayout-3.7-swing.jar でも良さそうです。というのは、ダウンロードしてみると miglayout-3.7.jar よりもファイルサイズが小さくなっていました。)

MiGLayoutをプロジェクトに追加する

Eclipse で開発を行っている場合、プロジェクトを作成し、プロジェクトのプロパティにある「Java Build Path」のタブ「Libraries」を開きます。そして、[Add External JARs…]のボタンをクリックして、miglayout-3.7.jar を追加します。

http://aoikujira.com/demo/hakkaku/rc/20090715FcJBZ-add-jar-file.png

以上の手順で、MiGLayout が使える環境が整いました。

Swing の基礎を学ぶ

ところで、いくら MiGLayout が簡単に使えるからと言って、Swing のことを全く知らなければ、MiGLayout のサイトの説明を読んでも使い方が分からないと思います。ここでは簡単に、Swing の基礎を紹介しておきます。

真っ白なウィンドウを表示する

Swing でウィンドウを表示するには、javax.swing.JFrame を継承してクラスを作ります。そして、メインメソッドで JFrame を継承したクラス(自身)を生成します。その後で、閉じるボタンが押された時の動作、ウィンドウのサイズなどを設定しています。

file:Test01.java

package com.kujirahand.test;
import javax.swing.JFrame;
public class JFrameTest1 extends JFrame {
	private static final long serialVersionUID = 1L;
	// メインメソッド
	public static void main(String[] args) {
		// 真っ白のウィンドウを表示するだけ
		JFrameTest1 mainFrame = new JFrameTest1();
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setSize(360, 240);
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setVisible(true);
	}

}
http://aoikujira.com/demo/hakkaku/rc/20090715GsiWjs-swing-jframe.png

JFrame を使うことで、ウィンドウを作ることができました。

とりあえず MiGLayout でボタンを配置してみる

次に、MiGLayout を使っていきます。真っ白なウィンドウを表示するプログラムをひな形として、MiGLayout を利用してコンポーネントをウィンドウ上に配置することができます。

以下は、MiGLayout を利用して、ボタンを3つウィンドウ上(のパネル上)に表示する例です。

http://aoikujira.com/demo/hakkaku/rc/20090715gat00-mig01.png

このサンプルは特に面白いものではありませんが、MiGLayout の使い方のひな形となるものです。注目したいのは、(*1)の部分です。JPanel を生成し、そのパネル内の配置を MiGLayout で行うように指定しています。

file: JFrameTest1 .java

package com.kujirahand.test;

import javax.swing.*;
import net.miginfocom.swing.MigLayout;

public class JFrameTest1 extends JFrame {
	private static final long serialVersionUID = 1L;
	// メインメソッド
	public static void main(String[] args) {
		// ウィンドウを表示
		JFrameTest1 mainFrame = new JFrameTest1();
		mainFrame.setTitle("JFrameTest1");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setSize(360, 240);
		mainFrame.setLocationRelativeTo(null);
		// ----------------------------------------------
		// パネル上に適当にコンポーネントを配置 --- (*1)
		// ----------------------------------------------
		JPanel p = new JPanel(new MigLayout());
		p.add(createButton("Button1"), "");
		p.add(createButton("Button2"), "");
		p.add(createButton("Button3"), "");
		// ----------------------------------------
		// パネルをウィンドウに追加
		mainFrame.add(p);
		mainFrame.setVisible(true);
	}
	public static JButton createButton(String caption) {
		JButton btn = new JButton(caption);
		return btn;
	}
}

複数段にコンポーネント配置する(改行の方法)

基本的な使い方が分かったので、次に、MiGLayout の特徴を示すサンプルを作ってみます。コンポーネントを追加する時に第二引数へ "wrap" という文字列を指定するとそこで改行するのです。

JFrameTest1.java の (*1) の部分を以下に書き換えます。

// ----------------------------------------
JPanel p = new JPanel(new MigLayout());
p.add(createButton("Button1"), "");
p.add(createButton("Button2"), "");
p.add(createButton("Button3"), "wrap");
p.add(createButton("Button4"), "");
p.add(createButton("Button5"), "wrap");
p.add(createButton("Button6"), "");
// ----------------------------------------
http://aoikujira.com/demo/hakkaku/rc/20090715WOyzs9-mig02.png

MiGLayout の配置は HTMLのテーブルとよく似ている(!)

次に、ボタンの大きさを変えて配置してみます。ここでは、ボタンのラベルの文字数を少なくしてみました。雰囲気が掴めるでしょうか。ちょうど、HTMLの table タグのように大きなサイズのコンポーネントに合わせて綺麗に配置されました。

// ----------------------------------------
JPanel p = new JPanel(new MigLayout());
p.add(createButton("Button1"), "");
p.add(createButton("Button2"), "");
p.add(createButton("Button3"), "wrap");
p.add(createButton("A"), "");
p.add(createButton("B"), "");
p.add(createButton("C"), "");
// ----------------------------------------
http://aoikujira.com/demo/hakkaku/rc/20090715JHGzj-mig03.png

コンポーネントをセルのサイズいっぱいに表示する(grow)

そして、コンポーネントのサイズをセルのサイズいっぱいに大きくするには、"grow" を指定します。"grow" を指定したボタンと、指定のないボタンを見比べてみて下さい。

// ----------------------------------------
JPanel p = new JPanel(new MigLayout());
p.add(createButton("Button1***"), "");
p.add(createButton("Button2***"), "");
p.add(createButton("Button3***"), "wrap");
p.add(createButton("4"), "");
p.add(createButton("5"), "");
p.add(createButton("6"), "wrap,grow");
p.add(createButton("7"), "");
p.add(createButton("8"), "grow");
p.add(createButton("9"), "grow");
// ----------------------------------------
http://aoikujira.com/demo/hakkaku/rc/20090715MSAXl-mig04.png

グリッドレイアウトで手軽で綺麗にレイアウトを行うことができるので気持ちが良いですね。

さて、ここまでの簡単なまとめです。コンポーネントをパネルに追加する際に「wrap」を指定すると改行し、「grow」を指定すると、配置するコンポーネントをセルめいっぱいの大きさで配置します。他にも、セルを結合して配置する「span」や、余白を挿入する「gap」もあります。

wrap 改行する
grow コンポーネントのサイズをセルいっぱいにする
span セルを結合する
gap para 余白を入れる

あらかじめカラム数を指定する方法

また、MigLayout のコンストラクタでカラム数を指定することができます。例えば、「"wrap 3"」などと指定すると、"wrap" を指定しなくても、自動的にコンポーネント3つずつで改行します。

// ----------------------------------------
JPanel p = new JPanel(new MigLayout("wrap 3")); // 明示的に カラム数を指定
for (int i = 1; i <= 18; i++) {
	p.add(createButton("Button"+i),"grow");
}
// ----------------------------------------
http://aoikujira.com/demo/hakkaku/rc/20090715uA2YQ-mig05.png

セルのサイズを細かく指定する方法

もう少し実用的なツールのUIを作ろうと思った時には、コンポーネントサイズをもう少し詳しく指定したい場合があります。その場合「(最小幅):(優先幅):(最大幅)」の方法でサイズを指定することができます。

以下の例は、最小幅と最大幅を指定せず、優先幅を指定してボタンを配置したものです。

JPanel p = new JPanel(new MigLayout("wrap 3"));
p.add(createButton("A"),"width :50:");
p.add(createButton("B"),"width :100:");
p.add(createButton("C"),"width :150:");
p.add(createButton("D"),"");
p.add(createButton("E"),"");
p.add(createButton("F"),"");
http://aoikujira.com/demo/hakkaku/rc/20090715u6GEjS-mig06size.png

セルのサイズに適当な値を指定しても大丈夫(!)

そして、次にボタンCのサイズを、500 という、ウィンドウよりも大きなサイズで指定しました。すると、ウィンドウのサイズにぴったり収まるように、ボタンCのサイズを適当なサイズに抑えてくれました。賢いです。

JPanel p = new JPanel(new MigLayout("wrap 3"));
p.add(createButton("A"),"width :50:");
p.add(createButton("B"),"width :100:");
p.add(createButton("C"),"width :500:");
p.add(createButton("D"),"");
p.add(createButton("E"),"");
p.add(createButton("F"),"");
http://aoikujira.com/demo/hakkaku/rc/20090715ALewPA-mig06sizeMax.png

セルのサイズを省略形で書くことができる

ところで、"width 100:150:200" のように毎回書くのは実に面倒なので、省略した書き方ができるように工夫されています。

JPanel p = new JPanel(new MigLayout("wrap 3"));
p.add(createButton("A"),"w :50:"); // できれば 50px にして欲しい
p.add(createButton("B"),"w 100");  // (省略形)100px にして欲しい
p.add(createButton("C"),"w 250!"); // (省略形)最低250pxは必要!
p.add(createButton("D"),"");
p.add(createButton("E"),"");
p.add(createButton("F"),"");
http://aoikujira.com/demo/hakkaku/rc/20090715eJ3Fa-mig06sizeSave.png

セルのサイズをあらかじめ一括で指定する方法

また、MigLayout のコンストラクタで、これらセルのサイズの指定を一括で行うことができるようになっています。

// セルのサイズをあらかじめ一括で指定する
MigLayout layout = new MigLayout(
    "wrap 3",                   // レイアウトの指示
    "[:50:][:200:][:50:]",      // 列に関する指示
    "[:30:][:60:][:30:]"        // 行に関する指示
);
JPanel p = new JPanel(layout);
for (int i = 1; i <= 9; i++) {
	p.add(createButton("Button"+i),"grow");
}
http://aoikujira.com/demo/hakkaku/rc/20090715EaVpV6-mig07sizeConst.png

セルのレイアウトを指定する方法

それからグリッドレイアウトに必須のもの、セル中のコンポーネントの配置方法に関する指定も可能となっています。

  • 列に関する配置
    • left (l) — 左揃え
    • center (c) — 中央揃え
    • right (r) — 右揃え
  • 行に関する配置
    • top (t) — 上揃え
    • center (c) — 中央揃え
    • bottom (b) — 下揃え
MigLayout layout = new MigLayout(
    "wrap 3",                            // レイアウトの指示
    "[right,100][center,200][left,100]", // 列に関する指示
    "[bottom,50][center,100][top,50]"    // 行に関する指示
);
JPanel p = new JPanel(layout);
for (int i = 1; i <= 9; i++) {
	String opt = (i % 2 == 0) ? "grow" : "";
	p.add(createButton("btn"+i),opt);
}
http://aoikujira.com/demo/hakkaku/rc/20090715sOUsGw-mig08align.png

省略形(l,c,r/t,c,b)で書くと次のように指定できます。上で書いたのと全く同じ意味になります。

MigLayout layout = new MigLayout(
    "wrap 3",                // レイアウトの指示
    "[r,100][c,200][l,100]", // 列に関する指示
    "[b,50][c,100][t,50]"    // 行に関する指示
);

簡単な入力フォームを作ってみる

さて、ここまで解説したことのまとめとして、以下のような、よくある顧客データの入力フォームを作ってみました。

http://aoikujira.com/demo/hakkaku/rc/20090715vQuaGP-mig09-form.png

以下の部分が実際のソースファイルです。サイズや配置の指定などが非常に簡潔に配置できることが分かるのではないでしょうか。

package com.kujirahand.test;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;
public class JFrameTest1 extends JFrame {
	private static final long serialVersionUID = 1L;
	// メインメソッド
	public static void main(String[] args) {
		// ウィンドウを表示
		JFrameTest1 mainFrame = new JFrameTest1();
		mainFrame.setTitle("JFrameTest1");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setSize(360, 180);
		mainFrame.setLocationRelativeTo(null);
		// ----------------------------------------
		// パネル上に適当にコンポーネントを配置
		// ----------------------------------------
		JPanel p = new JPanel(new MigLayout());
		// 入力項目の配置
		p.add(createLabel("名前"), "r");
		p.add(createText("kujirahand"), "w 200");
		p.add(createLabel("性別"), "gap para,r");
		p.add(createText("男"), "w 50!,wrap");
		p.add(createLabel("〒"), "r");
		p.add(createText("xxx-xxxx"), "grow");
		p.add(createLabel("住所"), "gap para");
		p.add(createText("東京都**区**町"), "w 300,wrap");
		p.add(createLabel("備考"), "r");
		p.add(createText("特になし"), "span,grow");
		// ボタンの配置
		JPanel buttons = new JPanel(new MigLayout());
		p.add(buttons, "span, r, w 200");
		buttons.add(createButton("保存"),"w 150");
		buttons.add(createButton("取消"),"w 50");
		// ----------------------------------------
		// パネルをウィンドウに追加
		mainFrame.add(p);
		mainFrame.setVisible(true);
	}
	public static JButton createButton(String caption) {
		JButton btn = new JButton(caption);
		return btn;
	}
	public static JLabel createLabel(String caption) {
		JLabel label = new JLabel(caption);
		return label;
	}
	public static JTextField createText(String text) {
		JTextField txt = new JTextField(text);
		return txt;
	}
}

まとめ

以上、Java のレイアウトマネージャー MiGLayout の使い方について簡単にまとめてみました。サイズの指定や配置の方法を知れば、自由自在にコンポーネントが配置できることが分かると思います。使い方がシンプルながら非常に強力なレイアウトを実現できていることを確認することができました。MiGLayout は、Swing / AWT に対応していますので、Java で GUI アプリを作らなくてはならなくなった時、ぜひ、利用してみたいと思います。


執筆者紹介

クジラ飛行机

クジラ飛行机

くじらはんど(http://kujirahand/)にて、日本語プログラミング言語「なでしこ」(IPA未踏ユース採択)、テキスト音楽「サクラ」(OSPオンラインソフト大賞入賞)など多くのオンラインソフトを開発。著書に「Flexプロフェッショナルガイド」「なでしこ公式バイブル」、「一週間でマスターするActionScript3.0」など。

TrackBack URL :