ドキュメント



JavaFX: FXMLの習得

3 FXMLを使用したアドレス帳の作成

この章では、図3-1に示すように、名前と電子メール・アドレスの表を含むアドレス帳アプリケーションを作成します。このチュートリアルでは、表にデータを移入する方法、アプリケーションの起動時にデータをソートする方法、表のセルでデータの位置を合せる方法および表に行を追加する方法を示します。

このチュートリアルは、FXMLおよびアプリケーション開発についてある程度の知識を持っていることを前提としています。FXML開発の基本については開始シリーズのFXMLチュートリアルで説明されているため、開始する前に、このチュートリアルを完了しておく必要があります。特に、アドレス帳チュートリアルでは、次のような知識が必要となります。

  • FXMLプロジェクト(.java、.fxmlおよびコントローラ・ファイル)の基本構造

  • NetBeans IDEでJavaFX FXMLプロジェクトを作成および実行する方法

  • レイアウトおよびユーザー・インタフェース・コンポーネントの基本

このチュートリアルを開始する前に、使用しているNetBeans IDEのバージョンでJavaFXのバージョンがサポートされていることを確認してください。

図3-1 アドレス帳アプリケーション

図3-1の説明が続きます
「図3-1 アドレス帳アプリケーション」の説明

プロジェクトの設定

最初のタスクは、NetBeans IDEでJavaFX FXMLプロジェクトを設定することです。

  1. 「ファイル」メニューから、「新規プロジェクト」を選択します。

  2. 「JavaFX」カテゴリで、「JavaFX FXMLアプリケーション」を選択します。「次」をクリックします。

  3. プロジェクトにFXMLTableViewという名前を付けて、「終了」をクリックします。

    NetBeans IDEで、Hello Worldサンプル・アプリケーションのコードを含むFXMLプロジェクトが開きます。このアプリケーションには、FXMLTableView.javaFXMLDocument.fxmlおよびFXMLDocumentController.javaという3つのファイルが含まれています。

  4. このアプリケーションに意味のある名前になるように、名前をFXMLDocumentController.javaからFXMLTableViewController.javaに変更します。

    1. 「プロジェクト」ウィンドウで、FXMLDocumentController.javaを右クリックして、「リファクタリング」「名前の変更」を選択します。

    2. 「FXMLTableViewController」と入力してから、「リファクタリング」をクリックします。

  5. 名前をFXMLDocument.fxmlからfxml_tableview.fxmlに変更します。

    1. 「FXMLDocument.fxml」を右クリックして、「名前の変更」を選択します。

    2. 「fxml_tableview」と入力して、「OK」をクリックします。

  6. FXMLTableView.javaを開き、例3-1と同様になるようにFXMLTableViewクラスを編集します。

    例3-1 FXMLTableView.java

    public class FXMLTableView extends Application {
        
        @Override
        public void start(Stage primaryStage) throws Exception {
           primaryStage.setTitle("FXML TableView Example");
           Pane myPane = (Pane)FXMLLoader.load(getClass().getResource
        ("fxml_tableview.fxml"));
           Scene myScene = new Scene(myPane);
           primaryStage.setScene(myScene);
           primaryStage.show();
        }
     
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    Javaファイルには、シーンのコードが含まれていないことに注意してください。チュートリアルの次の項「基本的なユーザー・インタフェースの作成」で、FXMLファイルにシーンのコードを追加します。

  7. [Ctrl] (または[Cmd])キーと[Shift]キーを押しながら[I]キーを押して、import文を修正します。

基本的なユーザー・インタフェースの作成

シーンのルート・ノードとしてGridPaneレイアウト・コンテナを作成して、ユーザー・インタフェースを定義します。次に、GridPaneレイアウト・コンテナの子ノードとして、LabelおよびTableViewコンポーネントを追加します。

  1. fxml_tableview.fxmlファイルを編集します。

  2. NetBeans IDEで自動的に生成された<AnchorPane>マークアップを削除します。

  3. 例3-2に示すように、シーンのルート・ノードとしてGridPaneレイアウト・コンテナを追加します。

    例3-2 GridPane

    <GridPane alignment="CENTER" hgap="10.0" vgap="10.0"
        xmlns:fx="http://javafx.com/fxml"
        fx:controller="fxmltableview.FXMLTableViewController">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
        </padding> 
    </GridPane>
    

    出力ウィンドウに「指定したアドレスにファイルが見つかりません: http://javafx.com/fxml」というエラーが表示されても、無視できます。

  4. GridPaneレイアウト・コンテナに、LabelおよびTableViewコンポーネントを追加します。例3-3に、コードを示します。

    例3-3 LabelおよびTableView

    <GridPane alignment="CENTER" hgap="10.0" vgap="10.0"
        xmlns:fx="http://javafx.com/fxml"
        fx:controller="fxmltableview.FXMLTableViewController">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
        </padding>
        <Label style="-fx-font: NORMAL 20 Tahoma;" text="Address Book"                
            GridPane.columnIndex="0" GridPane.rowIndex="0">
        </Label>
        <TableView fx:id="tableView" GridPane.columnIndex="0" 
            GridPane.rowIndex="1">
        </TableView>
    </GridPane>
    
  5. Insetsクラスのimport文を追加します。

    <?import javafx.geometry.Insets?>

  6. プログラムを実行します。図3-2に示すように、「Address Book」というラベルおよび「No columns in table」というテキストを含む表が表示されます。このテキストは、TableView実装で定義されたデフォルトのキャプションです。

    図3-2 列を含まない表

    図3-2の説明が続きます
    「図3-2 列を含まない表」の説明

表への列の追加

TableColumnクラスを使用して、データを表示するための「First Name」、「Last Name」および「Email Address」という3つの列を追加します。例3-4に、コードを示します。

列3-4 表の列

<TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">
     <columns>
          <TableColumn text="First Name">
          </TableColumn>
          <TableColumn text="Last Name">
          </TableColumn>
          <TableColumn text="Email Address">
          </TableColumn>
     </columns>    
</TableView>

ヒント: TableColumnクラスやこのチュートリアルで説明するその他のJavaFXクラスの詳細は、APIのドキュメントを参照してください。

図3-3に、「First Name」、「Last Name」および「Email Address」の列を含む表を示します。

図3-3 3つの列を含むアドレス帳

図3-3の説明が続きます
「図3-3 3つの列を含むアドレス帳」の説明

データ・モデルの定義

JavaFXアプリケーションで表を作成する際のベスト・プラクティスは、データ・モデルを定義し、表をさらに操作するためのメソッドやフィールドを提供するクラスを実装することです。アドレス帳のデータを定義するPersonクラスを作成します。

  1. NetBeans IDEで、「ソース・パッケージ」の下にあるfxmltableviewフォルダを右クリックして、「新規」「Javaクラス」を選択します。

  2. クラスにPersonという名前を付けてから、「終了」をクリックします。

  3. 例3-5に示すように、データを定義するPersonクラスを実装します。

    例3-5 Personクラス

    package fxmltableview;
     
    import javafx.beans.property.SimpleStringProperty;
     
    public class Person {
       private final SimpleStringProperty firstName = new SimpleStringProperty("");
       private final SimpleStringProperty lastName = new SimpleStringProperty("");
       private final SimpleStringProperty email = new SimpleStringProperty("");
    
    public Person() {
            this("", "", "");
        }
     
        public Person(String firstName, String lastName, String email) {
            setFirstName(firstName);
            setLastName(lastName);
            setEmail(email);
        }
    
        public String getFirstName() {
            return firstName.get();
        }
     
        public void setFirstName(String fName) {
            firstName.set(fName);
        }
            
        public String getLastName() {
            return lastName.get();
        }
        
        public void setLastName(String fName) {
            lastName.set(fName);
        }
        
        public String getEmail() {
            return email.get();
        }
        
        public void setEmail(String fName) {
            email.set(fName);
        }
    }
    

表の列とのデータの関連付け

次のタスクは、データの行を定義し、そのデータを表の列に関連付けることです。このコードをFXMLファイルに追加します。

  1. fxml_tableview.fxmlファイルで、ObservableList配列を作成し、表に表示させたい数だけデータの行を定義します。例3-6に、サンプル・コードを示します。</columns>マークアップと</TableView>マークアップの間にコードを追加します。

    例3-6 ObservableList配列

    </columns>
    <items>
        <FXCollections fx:factory="observableArrayList">
            <Person firstName="Jacob" lastName="Smith"  
                 email="jacob.smith@example.com"/>
            <Person firstName="Isabella" lastName="Johnson" 
                 email="isabella.johnson@example.com"/>
            <Person firstName="Ethan" lastName="Williams" 
                 email="ethan.williams@example.com"/>
            <Person firstName="Emma" lastName="Jones"
                 email="emma.jones@example.com"/>
            <Person firstName="Michael" lastName="Brown" 
                 email="michael.brown@example.com"/>
        </FXCollections>
    </items>
    </TableView>
    
  2. 例3-7に示すように、列ごとにセル・ファクトリを指定して、データを列に関連付けます。

    例3-7 セル・ファクトリ

    <columns>
         <TableColumn text="First Name">
            <cellValueFactory><PropertyValueFactory property="firstName" />
            </cellValueFactory>
         </TableColumn>
         <TableColumn text="Last Name">
            <cellValueFactory><PropertyValueFactory property="lastName" />
            </cellValueFactory>
         </TableColumn>
         <TableColumn text="Email Address">
             <cellValueFactory><PropertyValueFactory property="email" />
             </cellValueFactory>
        </TableColumn>
    </columns> 
    

    セル・ファクトリは、PropertyValueFactoryクラスを使用することで実装されます。このクラスでは、Personクラスの対応するメソッドへの参照として、表の列のfirstNamelastNameおよびemailプロパティが使用されます。

  3. 例3-8に示すように、必要なパッケージをインポートします。

    例3-8 import文

    <?import javafx.scene.control.cell.*?> 
    <?import javafx.collections.*?> 
    <?import fxmltableview.*?> 
    

この時点でアプリケーションを実行すると、図3-4に示すように、データが移入された表が表示されます。

図3-4 データを含む表

図3-4の説明が続きます
「図3-4 データを含む表」の説明

ここで、TableViewクラスの組込み機能の一部を試してみることができます。

  • 表ヘッダーの列区切りを左または右にドラッグして、列の幅のサイズを変更します。

  • 列ヘッダーをドラッグして、列を移動します。

  • 列ヘッダーをクリックして、データのソート順序を変更します。1回目のクリックで昇順のソートが有効になり、2回目のクリックで降順のソートが有効になり、3回目のクリックでソートが無効になります。デフォルトでは、ソートは適用されていません。

起動時のソート順序の設定

このタスクでは、アプリケーションの起動時に「First Name」列のエントリがアルファベットの昇順で表示されるように、ソート順序を設定します。これを行うには、表の列を表すIDを作成してから、そのIDへの参照を設定します。

  1. 「First Name」列にIDを追加します。

    <TableColumn fx:id="firstNameColumn" text="First Name">

  2. </items>マークアップと</TableView>マークアップの間に、例3-9のコードを追加して、ソート順序を指定します。

    例3-9 ソート順序

    </items>
         <sortOrder>
              <fx:reference source="firstNameColumn"/>
         </sortOrder> 
    </TableView>
    

この結果は、図3-5で確認できます。

図3-5 起動時にソートされた「First Column」データを含む表

図3-5の説明が続きます
「図3-5 起動時にソートされた「First Column」データを含む表」の説明

列の幅の定義

列の幅を広げるには、例3-10に示すようにprefWidthプロパティを追加します。

例3-10 列の幅

<TableColumn fx:id="firstnameColumn" text="First Name" prefWidth="100">
        <cellValueFactory><PropertyValueFactory property="firstName" />
        </cellValueFactory>
     </TableColumn>
     <TableColumn text="Last Name" prefWidth="100">
        <cellValueFactory><PropertyValueFactory property="lastName" />
        </cellValueFactory>
     </TableColumn>
     <TableColumn text="Email Address" prefWidth="200">
        <cellValueFactory><PropertyValueFactory property="email" />
        </cellValueFactory>
     </TableColumn>

図3-6に、結果を示します。表の各行にすべてのデータを表示できるように、列の幅が広げられました。

図3-6 列の幅が設定された表

図3-6の説明が続きます
「図3-6 列の幅が設定された表」の説明

表のセルでの位置合せの設定

もう1つのカスタマイズは、表のセルでデータの位置合せを設定することです。FormattedTableCellFactoryという名前の新しいクラスでこのロジックを実装してから、FXMLコードの<TableColumn>マークアップに位置合せを設定します。

  1. NetBeans IDEで、「ソース・パッケージ」の下にあるfxmltableviewフォルダを右クリックして、「新規」「Javaクラス」を選択します。

  2. クラスにFormattedTableCellFactoryという名前を付けてから、「終了」をクリックします。

  3. 例3-11に示すように、Callbackクラスを実装し、TextAlignmentおよびFormatクラスのインスタンスを作成して、FormattedTableCellFactoryクラスを変更します。SパラメータのタイプはTableView汎用タイプであり、Tパラメータのタイプはこの表の列内にあるすべてのセルの内容です。

    例3-11 Callbackクラス

    public class FormattedTableCellFactory<S, T> 
        implements Callback<TableColumn<S, T>, TableCell<S, T>> {
        private TextAlignment alignment;
        private Format format;
     
        public TextAlignment getAlignment() {
            return alignment;
        }
     
        public void setAlignment(TextAlignment alignment) {
            this.alignment = alignment;
        }
     
        public Format getFormat() {
            return format;
        }
     
        public void setFormat(Format format) {
            this.format = format;
        }
    
  4. 例3-12のコードを追加して、TableCellおよびTableColumnクラスを実装します。このコードは、TableCellクラスのupdateItemメソッドをオーバーライドし、表のセルに対してsetTextAlignmentメソッドをコールします。

    例3-12 TableCellおよびTableColumnクラス

    @Override
        @SuppressWarnings("unchecked")
        public TableCell<S, T> call(TableColumn<S, T> p) {
            TableCell<S, T> cell = new TableCell<S, T>() {
                @Override
                public void updateItem(Object item, boolean empty) {
                    if (item == getItem()) {
                        return;
                    }
                    super.updateItem((T) item, empty);
                    if (item == null) {
                        super.setText(null);
                        super.setGraphic(null);
                    } else if (format != null) {
                        super.setText(format.format(item));
                    } else if (item instanceof Node) {
                        super.setText(null);
                        super.setGraphic((Node) item);
                    } else {
                        super.setText(item.toString());
                        super.setGraphic(null);
                    }
                }
            };
            cell.setTextAlignment(alignment);
            switch (alignment) {
                case CENTER:
                    cell.setAlignment(Pos.CENTER);
                    break;
                case RIGHT:
                    cell.setAlignment(Pos.CENTER_RIGHT);
                    break;
                default:
                    cell.setAlignment(Pos.CENTER_LEFT);
                    break;
            }
            return cell;
        }
    }
    
  5. import文を修正します。

  6. 例3-13に示すように、fxml_tableview.fxmlファイルで、<cellValueFactory>マークアップの下に次のコードを追加して、「First Name」列の中央に位置合せします。

    例3-13 データ・セルでの位置合せ

    <TableColumn fx:id="firstNameColumn" text="First Name" prefWidth="100">
         <cellValueFactory><PropertyValueFactory property="firstName" />
         </cellValueFactory>
         <cellFactory>
              <FormattedTableCellFactory alignment="center">
              </FormattedTableCellFactory>
         </cellFactory>
    </TableColumn>
    

    left、rightまたはcenterの値を使用すると、残りの列に位置合せを作成できます。

この時点でアプリケーションを実行すると、図3-7に示すように、データが「First Name」列の中央に位置合せされます。

図3-7 「First Name」列の中央に位置合せされたデータ

図3-7の説明が続きます
「図3-7 「First Name」列の中央に位置合せされたデータ」の説明

表への行の追加

ユーザーが表にデータの行を追加する機能を追加できます。FXMLTableViewControllerクラスにこのアプリケーション・ロジックを追加します。次に、データを入力するための3つのテキスト・フィールドと1つのボタンが含まれるように、ユーザー・インタフェースを変更します。

  1. FXMLTableViewController.javaファイルを開きます。

  2. 例3-14のコードと同様になるように、FXMLTableViewControllerクラスを編集します。

    例3-14 FXMLTableViewController.java

    public class FXMLTableViewController {
        @FXML private TableView<Person> tableView;
        @FXML private TextField firstNameField;
        @FXML private TextField lastNameField;
        @FXML private TextField emailField;
        
        @FXML
        protected void addPerson(ActionEvent event) {
            ObservableList<Person> data = tableView.getItems();
            data.add(new Person(firstNameField.getText(),
                lastNameField.getText(),
                emailField.getText()
            ));
            
            firstNameField.setText("");
            lastNameField.setText("");
            emailField.setText("");   
        }
    }
    
  3. 例3-15に示すように、import文を修正します。

    例3-15 FXMLTableViewControllerのimport文

    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;
    
  4. 例3-16に示すように、fxml_tableview.fxmlファイルで、</GridPane>マークアップの前に次のコードを追加します。

    例3-16 行を追加するためのテキスト・フィールドおよびボタン

    </TableView>
         <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="0" 
              GridPane.rowIndex="2">
              <TextField fx:id="firstNameField" promptText="First Name"
                   prefWidth="90"/>
              <TextField fx:id="lastNameField" promptText="Last Name"
                   prefWidth="90"/>
              <TextField fx:id="emailField" promptText="email"
                   prefWidth="150"/>
              <Button text="Add" onAction="#addPerson"/>
         </HBox>
    </GridPane>
    

アプリケーションを実行すると、図3-8に示すように、表の下にテキスト・フィールドおよびボタンが表示されます。テキスト・フィールドにデータを入力し、「Add」をクリックすると、アプリケーションが動作することがわかります。

FXMLTableView.zipファイルをダウンロードして、FXMLTableViewアプリケーションの完全なソース・コードを確認します。

図3-8 データを追加するためのテキスト・フィールドおよびボタン付きの表

図3-8の説明が続きます
「図3-8 データを追加するためのテキスト・フィールドおよびボタン付きの表」の説明

次に実行すること

これでアドレス帳チュートリアルは完了ですが、次に行ういくつかの操作を示します。

  • データが正しい書式で入力されたことを確認するためのフィルタを提供します。

  • 空の行と空以外の行を区別するカスケード・スタイルシートを適用して、表をカスタマイズします。詳細は、「JavaFX UIコントロール」のCSSによるUIコントロールのスタイル設定を参照してください。

  • 表でのデータの編集を有効にします。ポインタの詳細は、「JavaFX UIコントロールの使用」の表内のデータの編集を参照してください。

  • FXML言語を構成する要素の詳細は、「FXMLの概要」ドキュメントを参照してください。このドキュメントは、APIドキュメントjavafx.fxmlパッケージに含まれています。

ウィンドウを閉じる

目次

JavaFX: FXMLの習得

展開 | 縮小