レイアウトについて(HBox/VBox/FlowPane)

今回はJavaFXで作成するアプリケーションの画面を構成するレイアウトについて説明していきます。
とは言っても、AWT、Swing、SWTと使い方は同じのため、大した参考にはならないかも。

2.0からFXMLという、Flash、SilverlightAndroidと同じくXMLでのマークアップもできるようになったようですが、それはまたいつか。
Javaのコード内で完結できるように書きます。

まずは簡単なものからということで、
今回は、以下のクラスを使った画面レイアウトの説明をします。

HBox
VBox
FlowPane

HBox

Hは水平を意味するHorizontalの頭文字です。
子要素を水平に配置するために使用するレイアウトです。
まずはサンプルコードを書いてみます。
簡単すぎますが、画面上にLabel1〜Label8の文字を横に並べただけのサンプル。

package sample.pane;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * HBoxクラスのサンプル
 * @author Atsushi Nakamoto
 */
public class HBoxSample extends Application {

    /**
     * メインメソッド
     */
    public static void main(String[] args) {
        Application.launch(HBoxSample.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("HBoxSample");
        
        // HBoxオブジェクトを生成。引数は子要素の間隔
        HBox hbox = new HBox(20d);
        // 配置位置を設定
        hbox.setAlignment(Pos.CENTER);
        
        // 出力用のラベルを生成
        List<Label> labelList = createLabel();
        
        // 生成したラベルをHBoxに設定
        hbox.getChildren().addAll(labelList);

        // ウインドウを生成
        Scene scene = new Scene(hbox, 480, 240, Color.WHITE);
        // ウインドウを設定
        primaryStage.setScene(scene);
        // 画面表示
        primaryStage.show();
    }
    
    /**
     * 画面表示のためのラベル「Label1」〜「Label8」を生成してリストにして返却。
     * 見やすいように赤、青交互にして設定する。
     * @return 
     */
    private List<Label> createLabel() {
        List<Label> list = new ArrayList<Label>();
        
        // ラベルの色の配列
        Color[] colors = new Color[]{Color.BLUE, Color.RED};
        
        Label label = null;
        for (int i=1; i<=8; i++) {
            // ラベル生成。引数は出力文字列
            label = new Label("Label" + i);
            // ラベルの色を設定
            label.setTextFill(colors[i%colors.length]);
            
            // リストに設定
            list.add(label);
        }   
        return list;
    }
}

実行結果は以下のようになります。

VBox

Vは垂直を意味するVerticalの頭文字です。
子要素を垂直に配置するために使用するレイアウトです。
上記のHBoxを縦に並べただけのサンプルを示します。

package sample.pane;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * VBoxクラスのサンプル
 * @author Atsushi Nakamoto
 */
public class VBoxSample extends Application {
    /**
     * メインメソッド
     * @param args 
     */
    public static void main(String[] args) {
        Application.launch(VBoxSample.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("VBoxSample");

        // VBoxオブジェクトを生成。引数は子要素の間隔
        VBox vbox = new VBox(20d);
        // 配置位置を設定
        vbox.setAlignment(Pos.CENTER);
        
        // 出力用のラベルを生成
        List<Label> labelList = createLabel();
        
        // 生成したラベルをVBoxに設定
        vbox.getChildren().addAll(labelList);

        Scene scene = new Scene(vbox, 240, 480, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    /**
     * 画面表示のためのラベル「Label1」〜「Label8」を生成してリストにして返却。
     * 見やすいように赤、青交互にして設定する。
     * @return 
     */
    private List<Label> createLabel() {
        List<Label> list = new ArrayList<Label>();
        
        // ラベルの色の配列
        Color[] colors = new Color[]{Color.BLUE, Color.RED};
        
        Label label = null;
        for (int i=1; i<=8; i++) {
            // ラベル生成。引数は出力文字列
            label = new Label("Label" + i);
            // ラベルの色を設定
            label.setTextFill(colors[i%colors.length]);
            
            // リストに設定
            list.add(label);
        }   
        return list;
    }
}

実行結果は以下のようになります。

FlowPane

子要素を縦方向、または横方向に一列に配置するために使用するレイアウトです。
縦方向に配置するか横方向に配置するかはパラメータにより設定することができるため、
上記のHBoxとVBoxでできることはFlowPaneでも同様に実装することができます。

上記と同様にLabel1〜Label8を順に出力するサンプルコードを示します。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sample.pane;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * FlowPaneクラスのサンプル
 * @author Atsushi Nakamoto
 */
public class FlowPaneSample extends Application {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Application.launch(FlowPaneSample.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("FlowPaneSample");
        
        // FlowPaneを生成する。引数は縦の間隔と横の間隔
        FlowPane flowPane = new FlowPane(20, 20);
        // 方向を設定する(Orientation.VERTICAL : 垂直/Orientation.HORIZONTAL : 水平)
        flowPane.setOrientation(Orientation.VERTICAL);
        // 配置位置を設定
        flowPane.setAlignment(Pos.CENTER);
        
        // 出力用のラベルを生成
        List<Label> labelList = createLabel();
        
        // 生成したラベルをFlowPaneに設定
        flowPane.getChildren().addAll(labelList);

        Scene scene = new Scene(flowPane, 360, 360, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
        /**
     * 画面表示のためのラベル「Label1」〜「Label8」を生成してリストにして返却。
     * 見やすいように赤、青交互にして設定する。
     * @return 
     */
    private List<Label> createLabel() {
        List<Label> list = new ArrayList<Label>();
        
        // ラベルの色の配列
        Color[] colors = new Color[]{Color.BLUE, Color.RED};
        
        Label label = null;
        for (int i=1; i<=8; i++) {
            // ラベル生成。引数は出力文字列
            label = new Label("Label" + i);
            // ラベルの色を設定
            label.setTextFill(colors[i%colors.length]);
            
            // リストに設定
            list.add(label);
        }   
        return list;
    }
}

実行結果は以下のようになります。

上記は縦方向に配置した場合のサンプルです。
配置の方向はsetOrientationメソッドで設定することができます。
横方向にしたい場合は、Orientation.HORIZONTALを指定します。
横方向にした場合の実行結果は以下のようになります。

横幅に収まりきらずに、収まりきらなかった分は折り返されて表示されます。
画面のサイズを変更すると収まるようになりますが、この挙動はHBox、VBoxと異なります。


同様のことをHBoxでやってみます。
HBoxの実行結果は以下の通り。

HBox、VBoxの場合は収まりきらない分は切れてしまいます。

VBox、HBoxはFlowPaneで代用できるけど、
画面サイズが変更されても折り返して全量が表示されるように作る場合はFlowPane、
画面サイズを変更した時に切れるように実装した場合はVBoxまたはHBoxを使うってことなんでしょうか。
FlowPaneのプロパティでHBoxやVBoxのような挙動にできるのかもしれないけど、よく調べませんでした。

今日はここまで。
次回は別のレイアウトの話でも・・・・。