ドキュメント



JavaFX: JavaFX UIコンポーネントの操作

27 ページ区切りコントロール

この章では、JavaFXアプリケーションにページ区切りコントロールを追加する方法について説明します。ここでは、アプリケーションにページ区切りコントロールを追加する方法、ページ項目を管理する方法、およびCSSスタイルを使用してコントロール要素のスタイルを設定する方法について説明します。

コンテンツの複数のページ間をナビゲートするために使用されるページ区切りコントロールは、複数の小さい部分に分けられます。一般的な使用例としては、メールボックス内の電子メール・メッセージ間をナビゲートしたり、検索結果を選択する場合などがあります。タッチ・デバイスでは、ページ区切りコントロールを使用して、記事の複数のページ内を参照したり、複数の画面内をナビゲートできます。図27-1に、オペレーティング・システムで使用可能なフォントを表示するページ区切りコントロールを示します。

図27-1 ページ区切りコントロール

図27-1の説明が続きます
「図27-1 ページ区切りコントロール」の説明

ページ区切りコントロールの作成

ページ区切りコントロールは、ページ・コンテンツ領域とページ・ナビゲーション領域で構成されています。ページ・コンテンツ領域では、アプリケーションのロジックに応じてコンテンツがレンダリングされてレイアウトされます。ページ・ナビゲーション領域には、コンテンツの特定の部分をプレビューするために事前に作成されたコントロールが含まれます。図27-2に、ナビゲーション領域の構造と基本要素を示します。

図27-2 ページ区切りコントロールのナビゲーション領域

図27-2の説明が続きます
「図27-2 ページ区切りコントロールのナビゲーション領域」の説明

ページ間をナビゲートするには、特定のページ・インジケータをクリックするか、次のページ・ボタンおよび前のページ・ボタンをクリックします。最初のページを選択すると、前のページ・ボタンが無効になります。同様に、最後のナビゲーション・インジケータを選択すると、次のページ・ボタンが無効になります。

JavaFX SDK APIには、ページ区切りコントロールをJavaFXアプリケーションに追加するためにPaginationクラスが用意されています。例27-1に、Paginationクラスの使用可能なコンストラクタを3つ示します。

例27-1 Paginationクラスの3つのコンストラクタ

//Creates a Pagination control with an INDETERMINATE page count 
//and the current page index equal to zero
Pagination pagination1 = new Pagination();
//Creates a Pagination control with 5 pages
//and the current page index equal to zero
Pagination pagination2 = new Pagination(5);
//Creates a Pagination control with 5 pages
//and the current selected index equal to 2
Pagination pagination3 = new Pagination(5, 2);

例27-1のpagination3コントロールを図27-3に示します。

図27-3 コンテンツがないページ区切りコントロール

図27-3の説明が続きます
「図27-3 コンテンツがないページ区切りコントロール」の説明

ページ索引は0から開始されることに注意してください。したがって、3ページ目を選択して開始するには、currentPageIndexPropertyを2に設定する必要があります。

pagination3コントロールにはコンテンツが追加されていないため、このコントロールのページは空です。

ページ区切りコントロールに項目を直接追加することはできません。これを行うには、ページ・ファクトリを設定する必要があります。ページ・ファクトリを実装してページのコンテンツを定義するには、PaginationクラスのsetPageFactoryメソッドを使用します。

ページ・ファクトリの実装

setPageFactoryを使用して、ページ区切りコントロールのページ・ファクトリを定義します。アプリケーション開発者は、コールバック・メソッドを作成し、このコールバックを使用するためのページ区切りのページ・ファクトリを設定します。コールバック・メソッドは、ページが選択されるときにコールされます。これにより、選択したページのコンテンツがロードされて返されます。選択したページ索引が存在しない場合、null値が返される必要があります。例27-2では、28ページあるページ区切りコントロールを作成し、これらのページに検索結果を移入し、ページごとに8項目を割り当てています。

例27-2 ページ区切りコントロールへのハイパーリンクの追加

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
 
 
public class PaginationSample extends Application {
    private Pagination pagination;
              
    public static void main(String[] args) throws Exception {
        launch(args);
    }
 
    public int itemsPerPage() {
        return 8;
    }
 
    public VBox createPage(int pageIndex) {
        VBox box = new VBox(5);
        int page = pageIndex * itemsPerPage();
        for (int i = page; i < page + itemsPerPage(); i++) {
            VBox element = new VBox();
            Hyperlink link = new Hyperlink("Item " + (i+1));
            link.setVisited(true);
            Label text = new Label("Search results\nfor "+ link.getText());
            element.getChildren().addAll(link, text);
            box.getChildren().add(element);
        }
        return box;
    }
 
    @Override
    public void start(final Stage stage) throws Exception {
        pagination = new Pagination(28, 0);
        pagination.setStyle("-fx-border-color:red;");
        pagination.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
       
        AnchorPane anchor = new AnchorPane();
        AnchorPane.setTopAnchor(pagination, 10.0);
        AnchorPane.setRightAnchor(pagination, 10.0);
        AnchorPane.setBottomAnchor(pagination, 10.0);
        AnchorPane.setLeftAnchor(pagination, 10.0);
        anchor.getChildren().addAll(pagination);
        Scene scene = new Scene(anchor);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        stage.show();
    }
}

ページの数および選択したページは、Paginationクラスのコンストラクタ内に定義されています。また、Paginationコントロールを作成した後、setPageCountおよびsetCurrentPageIndexメソッドを使用して、ページの数および選択したページの索引を設定することもできます。

Paginationコントロールのコンテンツは、ページ・ファクトリとして機能してsetPageFactoryメソッドによってコールされるcreatePageメソッド内で宣言されています。createPageメソッドは、ハイパーリンクと対応するラベルのペアを作成し、これらを縦に配置し、要素間に5ピクセルの間隔を設定しています。

例27-2をコンパイルして実行すると、図27-4に示す出力が表示されます。

図27-4 ページ区切りコントロールを使用した検索結果のプレビュー

図27-4の説明が続きます
「図27-4 ページ区切りコントロールを使用した検索結果のプレビュー」の説明

Paginationコントロールの現在の実装では、ページの数が10を超えた場合にページ・インジケータが10個表示されます。表示されているページ・インジケータの代替値を設定するには、PaginationクラスのsetMaxPageIndicatorCountメソッドを使用します。たとえば、例27-2pagination.setMaxPageIndicatorCount(7);の行を追加すると、ページ・インジケータが7個表示されます。図27-5に、変更を適用した後のPaginationSampleアプリケーションを示します。

図27-5 ページ・インジケータの数の変更

図27-5の説明が続きます
「図27-5 ページ・インジケータの数の変更」の説明

例27-3に、ページ区切りコントロールの別の使用例を示します。このアプリケーションでは、テキスト・フラグメントを1ページずつレンダリングしています。フラグメントの数は5つで、宣言されているページ区切りコントロールのページの数は28です。ArrayIndexOutOfBoundsException条件を回避するには、ページ検索のチェック(例27-3では太字で強調表示されています)を追加し、ページの数が5を超えたときにコールバック・メソッドによってnullが返されるようにします。

例27-3 ページ区切りコントロールへのテキスト・スニペットの追加

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class PaginationSample extends Application {
 
    private Pagination pagination;
    final String[] textPages = new String[]{
        "The apple is the pomaceous fruit of the apple tree, species Malus "
        + "domestica in the rose family (Rosaceae). It is one of the most "
        + "widely cultivated tree fruits, and the most widely known of "
        + "the many members of genus Malus that are used by humans. "
        + "The tree originated in Western Asia, where its wild ancestor, "
        + "the Alma, is still found today.",
        "The hawthorn is a large genus of shrubs and trees in the rose family,"
        + "Rosaceae, native to temperate regions of the Northern Hemisphere "
        + "in Europe, Asia and North America. The name hawthorn was "
        + "originally applied to the species native to northern Europe, "
        + "especially the Common Hawthorn C. monogyna, and the unmodified "
        + "name is often so used in Britain and Ireland.",
        "The ivy is a flowering plant in the grape family (Vitaceae) native to "
        + " eastern Asia in Japan, Korea, and northern and eastern China. "
        + "It is a deciduous woody vine growing to 30 m tall or more given "
        + "suitable support,  attaching itself by means of numerous small "
        + "branched tendrils tipped with sticky disks.",
        "The quince is the sole member of the genus Cydonia and is native to "
        + "warm-temperate southwest Asia in the Caucasus region. The "
        + "immature fruit is green with dense grey-white pubescence, most "
        + "of which rubs off before maturity in late autumn when the fruit "
        + "changes color to yellow with hard, strongly perfumed flesh.",
        "Aster (syn. Diplopappus Cass.) is a genus of flowering plants "
        + "in the family Asteraceae. The genus once contained nearly 600 "
        + "species in Eurasia and North America, but after morphologic "
        + "and molecular research on the genus during the 1990s, it was "
        + "decided that the North American species are better treated in a "
        + "series of other related genera. After this split there are "
        + "roughly 180 species within the genus, all but one being confined "
        + "to Eurasia."
    };
 
    public static void main(String[] args) throws Exception {
        launch(args);
    }
 
    public int itemsPerPage() {
        return 1;
    }
 
    public VBox createPage(int pageIndex) {
        VBox box = new VBox(5);
        int page = pageIndex * itemsPerPage();
        for (int i = page; i < page + itemsPerPage(); i++) {
            TextArea text = new TextArea(textPages[i]);
            text.setWrapText(true);
            box.getChildren().add(text);
        }
        return box;
    }
 
    @Override
    public void start(final Stage stage) throws Exception {
        pagination = new Pagination(28, 0);
        pagination.setStyle("-fx-border-color:red;");
        pagination.setPageFactory((Integer pageIndex) -> {
            if (pageIndex >= textPages.length) {
                return null;
            } else {
                return createPage(pageIndex);
            }
        });
 
        AnchorPane anchor = new AnchorPane();
        AnchorPane.setTopAnchor(pagination, 10.0);
        AnchorPane.setRightAnchor(pagination, 10.0);
        AnchorPane.setBottomAnchor(pagination, 10.0);
        AnchorPane.setLeftAnchor(pagination, 10.0);
        anchor.getChildren().addAll(pagination);
        Scene scene = new Scene(anchor, 400, 250);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        stage.show();
    }
}

例27-3をコンパイルして実行すると、図27-6に示す出力が表示されます。

図27-6 ページ区切りコントロールでのテキスト・フラグメントのレンダリング

図27-6の説明が続きます
「図27-6 ページ区切りコントロールでのテキスト・フラグメントのレンダリング」の説明

場合によっては、レンダリングする項目の正確な数、つまり、ページ区切りコントロール内のページの数を設定できないことがあります。このような場合は、Paginationオブジェクトのコンストラクタ内のページ数を計算するコード行を追加できます。例27-4では、システム・フォントのリストを出力し、フォント配列の長さをページ当たりの項目の数で割った数としてページの数を計算しています。

例27-4 サイズが未確定なコンテンツの追加

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
 
public class Test8 extends Application {
 
    private Pagination pagination;
    String[] fonts = new String[]{};
 
    public static void main(String[] args) throws Exception {
        launch(args);
    }
 
    public int itemsPerPage() {
        return 15;
    }
 
    public VBox createPage(int pageIndex) {        
        VBox box = new VBox(5);
        int page = pageIndex * itemsPerPage();
        for (int i = page; i < page + itemsPerPage(); i++) {
            Label font = new Label(fonts[i]);
            box.getChildren().add(font);
        }
        return box;
    }
 
    @Override
    public void start(final Stage stage) throws Exception {
        fonts = Font.getFamilies().toArray(fonts);
        
        pagination = new Pagination(fonts.length/itemsPerPage(), 0);
        pagination.setStyle("-fx-border-color:red;");
        pagination.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
 
        AnchorPane anchor = new AnchorPane();
        AnchorPane.setTopAnchor(pagination, 10.0);
        AnchorPane.setRightAnchor(pagination, 10.0);
        AnchorPane.setBottomAnchor(pagination, 10.0);
        AnchorPane.setLeftAnchor(pagination, 10.0);
        anchor.getChildren().addAll(pagination);
        Scene scene = new Scene(anchor, 400, 450);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        stage.show();
    }
}

この例をコンパイルして実行すると、図27-7に示すアプリケーション・ウィンドウが生成されます。

図27-7 ページ区切りコントロールを使用したシステム・フォントのレンダリング

図27-7の説明が続きます
「図27-7 ページ区切りコントロールを使用したシステム・フォントのレンダリング」の説明

ページ区切りコントロールのスタイル設定

ページ区切りコントロールをカスタマイズし、スタイル・クラスSTYLE_CLASS_BULLETを設定することにより、数値ページ・インジケータのかわりに箇条書きページ・インジケータを表示できます。また、modenaスタイル・シート内のデフォルトのページ区切りスタイルを変更できます。

例27-5に、例27-4のページ区切りコントロールのビジュアル要素の代替スタイルを示します。

例27-5 ページ区切りコントロールの変更済スタイル

.pagination {
    -fx-border-color:  #0E5D79;
}
 
.pagination .page {
    -fx-background-color: #DDF1F8;
}
 
.pagination .pagination-control {
    -fx-background-color: #C8C6C6;    
}
 
.pagination .pagination-control .bullet-button {
    -fx-background-color: transparent, #DDF1F8, #0E5D79, white, white;
}
 
.pagination .pagination-control .bullet-button:selected {   
    -fx-background-color: transparent, #DDF1F8, #0E5D79, white, #0E5D79;
}
 
.pagination .pagination-control .left-arrow, .right-arrow{
    -fx-background-color: #DDF1F8, #0E5D79;
}

例27-6では、これらのスタイルをページ区切りコントロールに適用し、ページ・インジケータに箇条書きスタイルを設定しています。

例27-6 PaginationSampleアプリケーションでの変更済ページ区切りコントロール・スタイルの有効化

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
 
public class PaginationSample extends Application {
 
    private Pagination pagination;
    String[] fonts = new String[]{};
 
    public static void main(String[] args) throws Exception {
        launch(args);
    }
 
    public int itemsPerPage() {
        return 15;
    }
 
    public VBox createPage(int pageIndex) {        
        VBox box = new VBox(5);
        int page = pageIndex * itemsPerPage();
        for (int i = page; i < page + itemsPerPage(); i++) {
            Label font = new Label(fonts[i]);
            box.getChildren().add(font);
        }
        return box;
    }
 
    @Override
    public void start(final Stage stage) throws Exception {
        fonts = Font.getFamilies().toArray(fonts);
        
        pagination = new Pagination(fonts.length/itemsPerPage(), 0);
        pagination.getStyleClass().add(Pagination.STYLE_CLASS_BULLET);
        pagination.setPageFactory((Integer pageIndex) -> createPage(pageIndex));
 
        AnchorPane anchor = new AnchorPane();
        AnchorPane.setTopAnchor(pagination, 10.0);
        AnchorPane.setRightAnchor(pagination, 10.0);
        AnchorPane.setBottomAnchor(pagination, 10.0);
        AnchorPane.setLeftAnchor(pagination, 10.0);
        anchor.getChildren().addAll(pagination);
        Scene scene = new Scene(anchor, 400, 450);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        scene.getStylesheets().add("paginationsample/ControlStyle.css");
        stage.show();
    }
}

新しく定義したスタイルをPaginationSampleアプリケーションに適用し、これをコンパイルして実行すると、図27-8に示すアプリケーション・ウィンドウが表示されます。

図27-8 箇条書きページ・インジケータおよび新しいCSSスタイルが適用されたPaginationSample

図27-8の説明が続きます
「図27-8 箇条書きページ・インジケータおよび新しいCSSスタイルが適用されたPaginationSample」の説明

適用されたスタイルに加えて、アプリケーション内のページ区切りコントロールの外観を変更するために次のスタイルを検討してください。

  • -fx-max-page-indicator-count - ページ・インジケータの最大数を設定します。

  • -fx-arrows-visible - 次および前ボタン矢印の可視性を切り替えます。デフォルトではtrueです。

  • -fx-tooltip-visible - ページ・インジケータ・ツールチップの可視性を切り替えます。デフォルトではtrueです。

  • -fx-page-information-visible - ページ情報の可視性を切り替えます。デフォルトではtrueです。

  • -fx-page-information-alignment - ページ情報の配置を設定します。

関連APIドキュメント

ウィンドウを閉じる

目次

JavaFX: JavaFX UIコンポーネントの操作

展開 | 縮小