javafx - 带分页的 JavaFx TableView
问题描述
我在 Scenebuilder 中使用 Tableview 和 Pagination 制作了 FXML。但我无法让分页工作,尤其是 PageFactory。
我有以下代码:
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="recordsOverview" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="accentor.overview.RecordsOverviewController">
<children>
<Pagination fx:id="paginator" onMouseClicked="#pageClicked" prefHeight="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="340.0" />
<HBox alignment="TOP_RIGHT" spacing="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="60.0">
<children>
<Label prefHeight="25.0" text="Search:" />
<TextField prefHeight="25.0" prefWidth="137.0" />
<Label prefHeight="25.0" text="Sort:" />
<ChoiceBox prefHeight="25.0" prefWidth="100.0" />
<ChoiceBox prefHeight="25.0" prefWidth="100.0" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</HBox>
<Label prefHeight="52.0" text="Records" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0">
<font>
<Font size="48.0" />
</font>
</Label>
<TableView fx:id="table" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="100.0">
<columns>
<TableColumn fx:id="trackid" text="#" />
<TableColumn fx:id="title" text="Title" />
<TableColumn fx:id="length" text="Length" />
<TableColumn fx:id="album" text="Album" />
<TableColumn fx:id="artists" text="Artist(s)" />
</columns>
</TableView>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</AnchorPane>
控制器:
public void fillTable(int page) {
this.dataModel.setTracksPage(page);
this.table.setItems(FXCollections.observableArrayList(this.dataModel.getTracks().getData()));
this.paginator.setCurrentPageIndex(page);
}
@Override
public void showOverview() {
recordsOverview.setVisible(true);
}
@Override
public void setDataModel(DataModel dataModel) {
if (this.dataModel == null) {
this.dataModel = dataModel;
}
fillTable(1);
paginator.setPageCount(this.dataModel.getTracks().getTotalPages());
this.paginator.setPageFactory((Integer pageIndex) -> {
fillTable(pageIndex);
return null; // ???
}
);
}
我只想用新数据填充表格,但返回 null 会给我错误。如果我返回其他东西,比如 return new BorderPane(table),它也不起作用,同样的错误。我该如何解决这个问题?
解决方案
您的页面工厂需要返回将显示为“页面”的节点。然后Pagination
将管理该节点并使其成为其下的场景图的一部分。您要做的是TableView
在分页中显示,因此您应该从页面工厂返回它。
你没有从你提到的错误中发布任何堆栈跟踪,但我猜发生的事情是当你返回表时,你会收到一个错误,因为TableView
它已经是场景图的一部分,并且节点可以' t 存在于两个不同的地方。
一种解决方案是从 FXML 中完全省略该表,而只在控制器中定义它(在方法中设置它initialize()
,然后从页面工厂返回对它的引用)。
如果您仍希望在 FXML 文件中定义它,您可以在 FXML 中定义不属于场景图的元素,方法是将它们包装在一个<fx:define>
block中。
所以你的 FXML 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="recordsOverview" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="accentor.overview.RecordsOverviewController">
<fx:define>
<TableView fx:id="table" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="100.0">
<columns>
<TableColumn fx:id="trackid" text="#" />
<TableColumn fx:id="title" text="Title" />
<TableColumn fx:id="length" text="Length" />
<TableColumn fx:id="album" text="Album" />
<TableColumn fx:id="artists" text="Artist(s)" />
</columns>
</TableView>
</fx:define>
<children>
<Pagination fx:id="paginator" onMouseClicked="#pageClicked" prefHeight="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="340.0" />
<HBox alignment="TOP_RIGHT" spacing="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="60.0">
<children>
<Label prefHeight="25.0" text="Search:" />
<TextField prefHeight="25.0" prefWidth="137.0" />
<Label prefHeight="25.0" text="Sort:" />
<ChoiceBox prefHeight="25.0" prefWidth="100.0" />
<ChoiceBox prefHeight="25.0" prefWidth="100.0" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</HBox>
<Label prefHeight="52.0" text="Records" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0">
<font>
<Font size="48.0" />
</font>
</Label>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</AnchorPane>
然后你做
this.paginator.setPageFactory((Integer pageIndex) -> {
fillTable(pageIndex);
return table;
}
);
推荐阅读
- firebase - Firebase 应用程序的 Google OAuth 同意屏幕
- apache-kafka - 消费者死后,消费者群体还能活多久?
- javascript - 反应 JS。NavLink activeClassName ICON, IMAGE
- java - 从 Java 中的泛型约束接口继承
- networking - 如何收集 k8s 集群 pod 的所有 igress 和 egress 流量?
- netlogo - 为什么在 IF 语句中使用 map 会出现问题?
- vue.js - 在 vuejs 中将 Dashbord 和 Forum 组件与 App 组件分开
- android - ListView 的自定义适配器忽略设置值
- angular - Angular 材料中的中心对齐内容不起作用
- python - 如何使用 getattr 访问 python 对象中的列表元素?