文档



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提供了Pagination类,用于将分页控件添加到JavaFX应用程序中。 示例27-1 显示了Pagination类的三个可用构造函数。

示例27-1 Pagination类的三个构造函数

//创建一个具有不确定页面数和当前页面索引为零的分页控件
Pagination pagination1 = new Pagination();
//创建一个具有5个页面和当前页面索引为零的分页控件
Pagination pagination2 = new Pagination(5);
//创建一个具有5个页面和当前选定索引为2的分页控件
Pagination pagination3 = new Pagination(5, 2);

示例27-1中的pagination3控件显示在图27-3中。

图27-3 不带内容的分页控件

图27-3的描述如下
"图27-3 不带内容的分页控件"的描述

请注意,页面索引从0开始。因此,要从第三页开始选中,需要将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("项目 " + (i+1));
            link.setVisited(true);
            Label text = new Label("搜索结果\n" + 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控件,并使用setPageCountsetCurrentPageIndex方法在之后设置页面数量和选定的页面索引。

Pagination控件的内容在createPage方法中声明,该方法作为页面工厂被setPageFactory方法调用。 createPage方法创建了超链接和相应标签的对,并垂直排列它们,在元素之间设置了五个像素的间隔。

当您编译和运行Example 27-2时,您应该看到Figure 27-4中显示的输出。

图27-4 使用Pagination控件预览搜索结果

图27-4的描述如下
"图27-4 使用Pagination控件预览搜索结果"的描述

如果页面数量超过10页,Pagination控件的当前实现将显示10个页面指示器。要设置显示的页面指示器的替代值,请使用Pagination类的setMaxPageIndicatorCount方法。例如,将以下行添加到Example 27-2中以显示七个页面指示器:pagination.setMaxPageIndicatorCount(7);。更改应用程序后,Figure 27-5显示了PaginationSample应用程序。

图27-5 改变页面指示器的数量

图27-5的描述如下
"图27-5 改变页面指示器的数量"的描述

Example 27-3展示了pagination控件的另一种用法。该应用程序每页呈现一个文本片段。片段的数量为5,pagination控件的声明页面数量为28。为了避免ArrayIndexOutOfBoundsException的情况,添加了页面索引检查(在Example 27-3中以粗体显示),当页面数量超过五页时,回调方法返回null

示例27-3 向分页控件添加文本片段

pagination.setPageFactory((Integer pageIndex) -> {
if (pageIndex >= textPages.length) {
return null;
} else {
return createPage(pageIndex);
}
});

pagination.setPageFactory((Integer pageIndex) -> {
if (pageIndex >= textPages.length) {
return null;
} else {
return createPage(pageIndex);
}
});

当您编译和运行示例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 PaginationSample应用程序应用了带有圆点页码指示器和新的CSS样式

图27-8的描述如下
"图27-8 PaginationSample应用了带有圆点页码指示器和新的CSS样式"的描述

除了应用的样式,您还可以考虑以下样式来改变应用程序中分页控件的外观:

  • -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组件

展开 折叠