1. 程式人生 > >JavaFX UI控制元件教程(二十六)之Pagination Control

JavaFX UI控制元件教程(二十六)之Pagination Control

翻譯自  Pagination Control

本章介紹如何向JavaFX應用程式新增分頁控制元件。它教授如何嚮應用程式新增分頁控制元件,管理其頁面項,以及使用CSS樣式設定控制元件元素的樣式。

分頁控制元件,用於瀏覽分成較小部分的多頁內容。典型用途包括瀏覽郵箱中的電子郵件或在搜尋結果中進行選擇。在觸控裝置中,分頁控制元件可用於瀏覽文章的單個頁面或在螢幕之間導航。圖25-1顯示了一個分頁控制元件,它顯示了作業系統中可用的字型。

圖25-1分頁控制

 

建立分頁控制元件

分頁控制元件由頁面內容和頁面導航區域組成。頁面內容區域根據應用程式邏輯呈現和佈置內容。頁面導航區域包含預製控制元件,用於預覽內容的特定部分。圖25-2

顯示了導航區域的結構和基本元素。

圖25-2分頁控制的導航區域

您可以通過單擊特定頁面指示器或單擊“下一頁”和“上一頁”按鈕來瀏覽頁面。選擇第一頁時,將禁用“上一頁”按鈕。同樣,當選擇最後一個導航指示器時,將禁用“下一頁”按鈕。

JavaFX SDK API提供了Pagination將分頁控制元件新增到JavaFX應用程式的類。例25-1顯示了Pagination該類的三個可用建構函式。

例25-1分頁類的三個建構函式

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

例25-1中的pagination3控制元件顯示在圖25-3中

圖25-3沒有內容的分頁控制

請注意,頁面索引從0開始。因此,要從選擇的第三個頁面開始,您需要將其設定currentPageIndexProperty為2。

pagination3控制元件的頁面為空,因為沒有內容新增到控制元件。

您不能將任何專案直接新增到分頁控制元件,它需要設定頁面工廠。使用類的setPageFactory方法Pagination通過實現頁面工廠來定義頁面內容。

 

實施頁面工廠

setPageFactory被用於定義分頁控制元件的頁面工廠。應用程式開發人員建立一個回撥方法並將分頁頁面工廠設定為使用此回撥。選擇頁面時將呼叫回撥方法。它載入並返回所選頁面的內容。null

如果所選頁面索引不存在,則必須返回該值。例25-2建立了一個包含28頁的分頁控制元件,並使用搜索結果填充頁面,每頁分配8個專案。

示例25-2將超連結新增到分頁控制元件

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.Node;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
 
 
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(new Callback<Integer, Node>() {
            @Override
            public Node call(Integer pageIndex) {
                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);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        stage.show();
    }
}

頁面數和所選頁面是在Pagination類的建構函式中定義的。或者,您可以Pagination使用setPageCountsetCurrentPageIndex方法建立控制元件並隨後設定頁數和所選頁面的索引。

Pagination控制元件的內容在createPage用作頁面工廠的方法中宣告,並由setPageFactory方法呼叫。該createPage方法建立超連結對和相應的標籤,並垂直排列,在元素之間設定五個畫素的間隔。

編譯並執行例25-2時,應該看到如圖25-4所示的輸出。

圖25-4使用分頁控制元件預覽搜尋結果

Pagination如果頁數超過10 ,則控制元件的當前實現顯示10個頁面指示符。要為顯示的頁面指示符設定替代值,請使用類的setMaxPageIndicatorCount方法Pagination。例如,將以下行新增到示例25-2以顯示七個頁面指示符:pagination.setMaxPageIndicatorCount(7);圖25-5顯示了應用更改後的PaginationSample應用程式。

圖25-5更改頁面指示符的數量

例25-3顯示了分頁控制元件的另一種用法。應用程式呈現文字片段,每頁一個。片段的數量為5,並且分頁控制元件的宣告頁數為28.要避免某種ArrayIndexOutOfBoundsException情況,請新增頁面索引檢查(在示例25-3中以粗體突出顯示)並使回撥方法在返回null時返回頁數超過五。

示例25-3將文字片段新增到分頁控制元件

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Pagination;
import javafx.scene.Node;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
 
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(new Callback<Integer, Node>() {
 
            @Override
            public Node call(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();
    }
}

編譯並執行例25-3時,您將看到如圖25-6所示的輸出。

圖25-6在分頁控制元件中渲染文字片段

在某些情況下,您無法設定要呈現的確切專案數,因此也無法設定分頁控制元件中的頁數。在這種情況下,您可以包含一行程式碼,用於計算Pagination物件建構函式中的頁數。例25-4輸出系統字型列表,並計算頁數作為字型陣列的長度除以每頁的項數。

示例25-4添​​加未確定大小的內容

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.setStyle("-fx-border-color:red;");
        pagination.setPageFactory(new Callback<Integer, Node>() {
 
            @Override
            public Node call(Integer pageIndex) {          
                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, 450);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        stage.show();
    }
}

編譯並執行此示例時,它將生成如圖25-7所示的應用程式視窗。

圖25-7使用分頁控制元件渲染系統字型

 

設計分頁控制

您可以通過設定樣式類來自定義分頁控制元件以顯示專案符號頁面指示符而不是數字頁面指示符STYLE_CLASS_BULLET。此外,您可以在caspian樣式表中修改預設的分頁樣式。

例25-5給出了例25-4中分頁控制元件的可視元素的一些替代樣式。

例25-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;
}

例25-6將這些樣式應用於分頁控制元件,併為頁面指示器設定專案符號樣式。

例25-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(new Callback<Integer, Node>() {
 
            @Override
            public Node call(Integer pageIndex) {          
                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, 450);
        stage.setScene(scene);
        stage.setTitle("PaginationSample");
        scene.getStylesheets().add("paginationsample/ControlStyle.css");
        stage.show();
    }
}

將新定義的樣式應用於PaginationSample應用程式並編譯並執行它時,您將看到如圖25-8所示的應用程式視窗。

圖25-8帶子彈頁面指示符的PaginationSample和應用的新CSS樣式

除了應用的樣式,您還可以考慮以下樣式來更改應用程式中分頁控制元件的外觀:

  • -fx-max-page-indicator-count - 設定頁面指示符的最大數量。

  • -fx-arrows-visibletrue預設情況下,切換“下一個”和“上一個”按鈕箭頭的可見性。

  • -fx-tooltip-visibletrue預設情況下,切換頁面指示器工具提示的可見性。

  • -fx-page-information-visibletrue預設情況下,切換頁面資訊的可見性。

  • -fx-page-information-alignment - 設定頁面資訊的對齊方式。

 

相關的API文件