Oracle Database 11g R2インストール

WebAppエンジニアであるにも関わらず、ここまでDBにあまり触れていないので、勉強がてらOracleをインストールしてみた。


タイトル通り、バージョンは「11g Release2」
VirtualBox上に構成したCentOS6に入れました。


インストールに際しては以下のサイトを参考にさせていただきました。
http://www.asami.asia/tech/oracle/11g-install.html
・・・・・が、途中で、このサイトで述べられている内容は「11g Release1」であったことに気付く。
(最初から気付け!)

Release1と2じゃあ結構違うのね・・・・。

R2の解説サイトもあったけど、上記のサイトで一通りインストールすることにしました。
手順はそれなりに同じなのではまったところだけ書いて行こうと思います。

ハマリ1 文字化け


インストーラを開いたところでいきなり文字化けしました。
日本語がよかったけど、どうにもならないので、
「export LANG=C」コマンドで環境変数を設定して英語にしてからインストール開始しました。

ハマリ2 性能要件不足

物理メモリとスワップサイズが要件を満たしていないようです。


仮想化してるので物理メモリはVirtualBoxの設定で割り振る量を調整できます。
ホストPCは4GBあるので、1.5GBをCentOSに振るように設定しました。


スワップサイズの調整はよくわからなかったので調べました。
以下のサイトを参考にスワップ領域を追加。
http://piro791.blog.so-net.ne.jp/2009-03-05


ハマリ3 カーネル設定不足

上記ハマリ2のスクリーンショットのOS Kernel Parametersってところです。
11g Relaease1用にカーネルの設定したのですが、Release2だとここもかなり違うようですね。
言われたとおりに設定し直して設定完了


ハマリ4 パッケージ不足

上記ハマリ2のスクリーンショットのPackagesってところです。
ん?
インストールしたはずなんだけど・・・・。
言われたとおりにyum installコマンドでインストールしてインストール完了
ただ、pdkshだけは、「そんなものは存在しない」と言われてしまったので、無視して先に進みました。


あとは言われたとおりにインストール作業を進めていき、何とか完了することができました。

別ウインドウを開く

アプリから別ウインドウを開く場合の方法。
画面にボタンがあり、ボタン押下で別ウインドウを開く場合を想定します。


最初わからなかったから、JavaDoc見回すとWindowってクラスがあったので、
このクラスを作ってインスタンス生成するのかと思ってたらどうやら違ったようで・・・・。
こんなしょうもないことで散々悩んでしまった。


惜しかったけど、正解はそのWindowクラスの子クラスのStageクラスのインスタンスを生成すればいいみたい。


ソースコードを抜粋します。
下記でbuttonRegistはButtonクラスのインスタンス。登録ボタンのことですね。
primaryStageはstartメソッドの引数のStageクラスのインスタンスのことです。

// ボタンにイベントハンドラを設定。ここではクリックしたときの動作を記述します。
buttonRegist.addEventHandler(MouseEvent.MOUSE_CLICKED
    new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {
            // 新しいウインドウを生成
            Stage newStage = new Stage();
            // モーダルウインドウに設定
            newStage.initModality(Modality.APPLICATION_MODAL);
            // オーナーを設定
            newStage.initOwner(primaryStage);
            
            // 新しいウインドウ内に配置するコンテンツを生成           
            HBox hbox = new HBox();
            Label label = new Label("登録画面");
            label.setFont(new Font(20d));
            hbox.getChildren().add(label);
                       
            newStage.setScene(new Scene(hbox));

            // 新しいウインドウを表示
            newStage.show();
        }
    });


ただこれだけのことだった・・・・。
1点注意で、initModalityでModality.APPLICATION_MODALにしとかないと、
ウインドウを開いた後、元のウインドウを操作できる。
元のウインドウで登録ボタンを押下すると別のウインドウを開くことができてしまう。


動かしてみよう

開いたウインドウがしょぼいけど、ここはこれから追加していこう。

列数が可変なTableView実装

本日はTableViewを使った実装。

月間の労働時間を記録する表を作ることを例にします。
縦軸にメンバーを、横軸に日付を取ることにします。
縦軸を可変にすることはできるけど、横軸を可変にするってのがよくわからない・・・・。

以下のような画面を出すための実装方法を検討してみました。



まず、データ構造ですが、日ごとの作業量を持つAmountPropertyクラス、作業者名を持つUserPropertyクラスを作成します。
UserPropertyは1ヶ月分のAmountPropertyを保持しており、ここでAmountPropertyはMapで構成し、キーは日付の情報とします。

以下の2つのPropertyクラスのソースを示します。

  • UserProperty
package net.atlabo.costcalc.property;

import java.util.HashMap;
import java.util.Map;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

/**
 * ユーザ情報を保持するプロパティ
 * @author Atsushi Nakamoto
 */
public class UserProperty {
    /** ユーザ名称 */
    private StringProperty name = new SimpleStringProperty();
    /** 
     * AmountPropetyクラスをMapにして保持するPropertyクラスのインスタンス 
     * Mapのキー名は日付を表す文字列となる
     */
    private ObjectProperty<Map<String, AmountProperty>> amount = new SimpleObjectProperty<Map<String, AmountProperty>>();
    
    /**
     * ユーザ名称を取得する
     * @return 
     */
    public String getName() {
        return name.get();
    }
    
    /**
     * ユーザ名称を設定する
     * @param name
     * @return 
     */
    public UserProperty setName(String name) {
        this.name.set(name);
        return this;
    }
    
    /**
     * AmountProprtyを格納したマップクラスを設定する
     * @param amountMap
     * @return 
     */
    public UserProperty setAmount(Map<String, AmountProperty> amountMap) {
        this.amount.set(amountMap);
        return this;
    }
    
    /**
     * AmountPropertyクラスを取得する
     * @param key マップのキー名(キー名は日付情報文字列となる)
     * @return 
     */
    public AmountProperty getAmountProperty(String key) {
        // 設定作業を行わない場合、amount.getでNULLが返却されるため、空マップを作成する
        if (amount.get() == null) {
            amount.set(new HashMap<String, AmountProperty>());
        }
        
        // キー名が含まれていない場合、空のAmountPropertyクラスインスタンスを生成してマップに設定
        if (!amount.get().containsKey(key)) {
            amount.get().put(key, new AmountProperty(0d));
        }
        
        return amount.get().get(key);
    }
}
  • AmountProperty
package net.atlabo.costcalc.property;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

/**
 * 量を保持するプロパティ
 * @author Atsushi Nakamoto
 */
public class AmountProperty {
    /***/
    private DoubleProperty amount = new SimpleDoubleProperty();
    
    /**
     * コンストラクタ
     * @param amount 
     */
    public AmountProperty(double amount) {
        this.amount.set(amount);
    }
    
    /**
     * 量をDoublePropertyのまま取得する
     * @return 
     */
    public DoubleProperty amountProperty() {
        return amount;
    }
}


次にTableViewを表示するためのメインクラスを示します。

package net.atlabo.costcalc;

import java.text.SimpleDateFormat;
import java.util.*;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;
import net.atlabo.costcalc.property.AmountProperty;
import net.atlabo.costcalc.property.UserProperty;

/**
 * @author Atsushi Nakamoto
 */
public class Main extends Application {
    private SimpleDateFormat df = new SimpleDateFormat("d日(EEE)");
    
    /**
     * メインメソッド
     */
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) {
        // カラム(列)リストを生成
        List<TableColumn> columnList = new ArrayList<TableColumn>();
        
        // TableColumnを生成してカラムリストに追加
        TableColumn dateCol = new TableColumn("Member");
        dateCol.setCellValueFactory(new PropertyValueFactory("name"));
        columnList.add(dateCol);
        
        // ダミー用データ生成
        ObservableList<UserProperty> data = createDummyData();
        
        // 今月1日を取得する
        final Calendar cal = new GregorianCalendar();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        
        // 今月末日を取得する
        Calendar end = new GregorianCalendar();
        end.add(Calendar.MONTH, 1);
        end.set(Calendar.DAY_OF_MONTH, 1);
        end.add(Calendar.DAY_OF_MONTH, -1);
        
        
        // 今月1日から末日までループしてカラムを生成、カラムリストに追加する
        TableColumn tableColumn = null;
        for (; !cal.after(end); cal.add(Calendar.DAY_OF_MONTH, 1)) {
            // 日付を取得する(マップのキーとしても使用する)
            final String theDay = df.format(cal.getTime());
            // テーブルカラムを生成
            tableColumn = new TableColumn(theDay);
            // ボディ部に設定する値を設定する
            tableColumn.setCellValueFactory(
                new Callback<CellDataFeatures<UserProperty, String>, ObservableValue>() {
                    public ObservableValue call(CellDataFeatures<UserProperty, String> p) {
                        return p.getValue().getAmountProperty(theDay).amountProperty();
                    }
                }
            );
            // カラムリストにカラムを追加
            columnList.add(tableColumn);   
        }
        
        // TableViewを生成
        TableView table = new TableView();
        // 生成したカラムリストを追加する
        table.getColumns().addAll(columnList);
        // データをテーブルの中に突っ込む
        table.setItems(data);

        Scene scene = new Scene(table);
        stage.setTitle("Table View Sample");
        stage.setWidth(800d);
        stage.setHeight(640d);
        stage.setScene(scene);
        stage.show();
    }
    
    /**
     * ダミーデータを生成する
     * この部分は本来DBから取得するなりファイルから取得するなり・・・・
     * @return 
     */ 
    private ObservableList<UserProperty> createDummyData() {
        // 今月1日に7.75設定する
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Map<String, AmountProperty> map = new HashMap<String, AmountProperty>();
        map.put(df.format(cal.getTime()), new AmountProperty(7.75d));
        
        return FXCollections.observableArrayList(
                new UserProperty().setName("Andrew"),
                new UserProperty().setName("Jack").setAmount(map),
                new UserProperty().setName("Peter"),
                new UserProperty().setName("George"),
                new UserProperty().setName("Ema"),
                new UserProperty().setName("Michael"),
                new UserProperty().setName("Hudson"),
                new UserProperty().setName("Lee"));
    }
}


Mainクラスのソースを追っていきます。


startメソッドが実質メインスレッドとなっています。


まずは、ArrayListインスタンスを生成します。
ArrayListはTableColumnの型指定をしておきます。
このオブジェクトは最後にまとめて登録するので、カラム内容は適宜このArrayListオブジェクトにaddしていくことになります。


まず最初に1番左の要素であるMember列を作成するため、TableColumnクラスのインスタンスを生成します。
コンストラクタはヘッダのラベルを示します。

更に、TableColumn#setCellValueFactoryメソッドを呼び出して、この列に表示する値を設定します。
ここのnew PropertyValueFactory("name")はUserProperty#getNameメソッドで取得できる値となりますが、
ここではまだデータとなるUserPropertyクラスのCollectionオブジェクトの設定は行っていません。


ここまでくるとArrayListインスタンスにTableColumnインスタンスを設定して1列目の設定が完了します。


ここから先が可変な列の生成になります。
今回のソースコードではシステム日付の月の1ヶ月分を可変な列とします。


ループ開始点である、今月1日とループの終端である今月末をそれぞれ保持し、
開始点から、1日ずつ日付をずらしながらforループをかけて月末までのカラムを設定します。


for文の中の説明です。
まずはTableColumnのインスタンスを生成します。
コンストラクタには日付と曜日を設定し、ヘッダのラベルを出力することにします。


次が重要ですが、実際のデータ部を設定するには、先ほどのTableColumn#setCellValueFactoryを呼び出すのですが、
引数にはCallBackの無名クラスを作り、callメソッドを実装します。
callメソッドのp.getValue()で、UserPropertyのインスタンスが取得できます。


ここではUserProperty内のMapクラスにアクセスするために日付をキーにしてAmountPropertyクラスのインスタンスを取得しています。
AmountProperty#amountPropertyで設定したDoublePropertyを返却することで、これをcallメソッドの戻り値とします。
そして、TableColumnの1件1件をArrayListインスタンスにaddしていきます。


最後にTableViewクラスのインスタンスを生成します。
ここまでで生成したArrayListインスタンスを設定し、更にTableView#setItemsでデータを突っ込むことができます。
ソースコードはサンプルなので、ここではcreateDummyData()でサンプルデータを生成するようになっています。
サンプルデータ生成のソースコードが長くなっても見難いだけなので、
Jackさんの1日分に7.75を設定しているだけです。
サンプルデータはObservableList型にする必要があります。


ここまでで上記の表示ができることになります。
ああ、めちゃくちゃ読みにくい・・・・。
装飾もない見出しもないでかなり読みにくいですが、ポイントは、Callbackクラスの無名クラスを実装するする箇所かな。

JavaFX 2.0インストールしてみた

つい先日Betaをインストールしたのですが、タイミング悪く正式リリースしたようで・・・・。
とりあえずインストールしてみました。

正式リリースに伴い、NetBeansは「7.1 Beta」になったようです。

こちらからダウンロードします。
http://netbeans.org/kb/docs/java/javafx-setup.html


NetBeansJavaFX 2.0 SDKをダウンロードしてインストールします。
動作にはJavaFX 2.0はJava SDK 1.6.0 update 26以上かJava7が必要と書いてありますね。
私の環境は1.6.0 update 20だったので、Java SDKもインストールしなおしました。


インストール後、NetBeansを起動して、まずはプロジェクトを作ってみます。
ファイル > 新規プロジェクトで以下のウインドウが表示されます。

JavaFX Applicationの他に、Preloader、FXML Applicationが選択できます。
どれを選択してもいいですが、せっかくなのでFXML Applicationを選択して「次へ」ボタンを押下します。


プロジェクト情報入力画面に遷移しましたが、画面下部にメッセージが表示されています。
選択したJavaJavaFXサポートされていません。
確かにJDKJavaFXもインストールしたはずですが・・・・・。

公式ページには以下の手順でJavaプラットフォームの追加をしなさいと書いてありました。

まず、この画面でManage Platformsを押下します。


上の画面が表示されるので、画面左下のプラットフォームを追加ボタンを押下します。
SDKの選択ウインドウが開くので、そこでJavaFXではなくJava SDKを選択します。
上述のとおり、Javaは1.6.0 update 26以上、またはJava7である必要があります。


取りこんだJDKにはJavaFXのタブが用意されているので、
ここでJavaFXのディレクトリ情報を入力すればOKです。
今後はJavaFXのプロジェクトを作る時はこっちのプラットフォームを使用しましょう。

できあがったスケルトンクラスを動かしてみました。


これでインストール完了です。



FXMLのコードアシストは未サポートなのね。
今後のNetBeansプラグインのバージョンアップに期待。
CSSもコードアシストつけてほしいし、GUIエディタも欲しい。
NetBeans使うことはまずないので、贅沢言うとEclipseでプラグイン出してほしいトコロ。

レイアウトについて(BorderLayout)

今回はBorderLayoutについて説明します。

BorderLayoutは枠の中を
・TOP
・BOTTOM
・LEFT
・RIGHT
・CENTER
の5つのエリアに分割して画面を構成するレイアウトです。

今回は先に実行結果から見ていきましょう。


画面を上記の5つのエリアに分割して、それぞれ色付けしています。

それではソースを示します。

package sample.pane;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

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

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("BorderPaneSample");
        BorderPane borderPane = new BorderPane();
        Scene scene = new Scene(borderPane, 320, 320, Color.WHITE);
        scene.getStylesheets().add("style.css");

        /* ****************************
         * TOP部分を構成 
         * ****************************/
        HBox topHBox = new HBox();
        topHBox.setAlignment(Pos.CENTER);
        topHBox.getStyleClass().add("background-blue");
        Text textTop = new Text("Top");
        textTop.setFill(Color.WHITE);
        topHBox.getChildren().add(textTop);
        borderPane.setTop(topHBox);
        
        /* ****************************
         * CENTER部分を構成 
         * ****************************/
        HBox centerHBox = new HBox();
        centerHBox.setAlignment(Pos.CENTER);
        centerHBox.setStyle("-fx-background-color: greenyellow;");
        Text textCenter = new Text("Center");
        centerHBox.getChildren().add(textCenter);
        borderPane.setCenter(centerHBox);

        /* ****************************
         * BOTTOM部分を構成 
         * ****************************/
        HBox bottomHBox = new HBox();
        bottomHBox.setAlignment(Pos.CENTER);
        Text textBottom = new Text("Bottom");
        bottomHBox.getStyleClass().add("background-red");
        bottomHBox.getChildren().add(textBottom);
        borderPane.setBottom(bottomHBox);
        
        /* ****************************
         * LEFT部分を構成 
         * ****************************/
        VBox leftVBox = new VBox();
        leftVBox.setAlignment(Pos.CENTER);
        leftVBox.getStyleClass().add("background-purple");
        Text textLeft = new Text("Left");
        textLeft.setFill(Color.WHITE);
        leftVBox.getChildren().add(textLeft);
        borderPane.setLeft(leftVBox);
        
        /* ****************************
         * RIGHT部分を構成 
         * ****************************/
        VBox rightVBox = new VBox();
        rightVBox.setAlignment(Pos.CENTER);
        rightVBox.getStyleClass().add("background-coral");
        Text textRight = new Text("Right");
        textRight.setFill(Color.WHITE);
        rightVBox.getChildren().add(textRight);
        borderPane.setRight(rightVBox);

        
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

前回のエントリで書いたVBox、HBoxにTextオブジェクトを入れて、
BorderPaneに配置しています。
配置の仕方は、生成したBorderPaneクラスのインスタンスに対して、
setXXXするだけです。
配置する位置によって、呼び出すsetterメソッドを切り替えてください。

・setTop:画面上部に配置する
・setBottom:画面下部に配置する
・setLeft:画面左に配置する
・setRight:画面右に配置する
・setCenter:画面中央に配置する

背景色の設定は、HBox、VBoxにそれらしいメソッドがなかったので、スタイルシートを使いました。
JavaFXは、スタイルシートが使えます。
ここで使用するスタイルシートはHTMLに使用するものではありません。
スタイルシートを適用することで、HTMLと同様に、表示を華やかにすることができるみたいです。


以下スタイルシートの説明になります。
今回はstyle.cssという外部ファイルを用意しました。


Sceneオブジェクトに対し、getStylesheets().add("style.css");
スタイルシートの追加を行うことができます。


style.cssの中身は以下のとおりです。

.background-red { 
    -fx-background-color: red;
}

.background-blue {
    -fx-background-color: blue;
}

.background-purple {
    -fx-background-color: purple;
}

.background-coral {
    -fx-background-color: coral;
}


記述方法はHTMLに適用するCSSそのものです。
それぞれ背景色を設定する記述です。


今回はHBoxとVBoxのインスタンスに適用することでBorderPaneの
それぞれのエリアの境界がわかるよう色付けしました。


HBoxまたはVBoxクラスのインスタンスに対して、
getStyleClass().add("background-blue");
のようにすることで任意のスタイルを適用できます。


また、centerHBox.setStyle("-fx-background-color: greenyellow;");
のように、外部ファイルに設定していなくても、
setStyleメソッドを使用してスタイルを直接記述すれば適用することができます。


CSSの説明については以下あたりが参考になるかもしれません。
Redirecting

レイアウトについて(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のような挙動にできるのかもしれないけど、よく調べませんでした。

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

JavaFX 2.0 Betaインストールしてみた

まだまだ時期尚早かもしれませんが、JavaFXが2.0になり、全く別モノになるって聞いて試してみることにしました。
現在β版で、正式版は2011年下半期とのこと。

RIAはFlashやSilverlightで事足りそうなのですが、生憎Javaしか知らないので、
新しく言語習得するよりはJavaFXかなぁ・・・・。

そんなわけでOracleには頑張ってほしいところ。

それでは、インストールとHelloWorldまでをまとめてみたので報告します。

必要要件

執筆時現在(2011/9/19)のところ、JavaFXはWindowsでしか動作しないようです。
また、Eclipseにはプラグインがないので、NetBeansを使って開発することになります。
もちろんNetBeansの使用は必須ではないのですが。
NetBeansのバージョンは7以上のものである必要があります。

インストール

NetBeans

以下からダウンロードしてインストールしてください。
上にも書きましたがバージョンは7以上でなければいけません。
http://ja.netbeans.org/
インストール手順は省略します。

JavaFX

以下からダウンロードしてください。
http://www.oracle.com/technetwork/java/javafx/downloads/index.html
プラグイン同梱版が楽です。

JavaFXプラグイン取り込み

プラグインの取り込みは以下のように行います。
まずはNetBeansを起動してください。


起動したら、メニューバーより「ツール > プラグイン」を選択します。
ウインドウが開くので、更に「ダウンロード済み」タブを選択し、
「プラグインの追加」ボタンを押下します。


先ほどダウンロードしたJavaFXのプラグインファイルを選択してインストールを行ってください。
ファイルは4つあるはずですので全部選択してください。


ここまでで準備は完了です。

プロジェクト作成

それではJavaFXプロジェクトを作成してみましょう。

メニューバーの「ファイル > 新規プロジェクト」を選ぶとウインドウが表示されます。


上記のように、「Java FX Application」を選択してください。



最初なので、適当に「Project Name」のところだけいじって「完了」
そうすると、スケルトンクラスが出来上がりますが・・・・・・。



なんだかコンパイルエラーが出ているようです。
setVisibleなんていうメソッドがないみたいなので、候補の中からそれっぽいのを探す。(いいのかこんなことで・・・・)
showってメソッドがあった!!



コンパイルエラーが取れたので実行してみる。



どうやら動いたようです。
しかし、この背景色のセンス・・・・・。
今回はここまでです。