JavaFX TableView分页 - 无法创建基于fxml的解决方案

时间:2016-04-16 15:38:08

标签: java javafx pagination javafx-2 tableview

我在我的项目中使用JavaFX(也就是Spring,Hibernate e.t.c。)。

我正在尝试为TableView创建分页。我找到了许多合理的解决方案,但所有这些都是基于控制器的解决方案。其中最好的是this solution

但在我的情况下 - 我正在使用多个fxml文件,这些文件是在SceneBuilder中创建的,具有所有巨大的设计选项,并且包含TabPane,对于一个Tab,我有一个FXML文件和一个控制器。

我有一个导入其他文件的基本文件,在我的Main类中我正在加载它:

enter image description here

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
            minWidth="-Infinity" prefHeight="592.0" prefWidth="920.0" xmlns="http://javafx.com/javafx/8"
            fx:controller="com.varinsia.statistical.controller.GenericController">
    <children>
        <TabPane layoutX="3.0" layoutY="50.0" prefHeight="542.0" prefWidth="914.0" tabClosingPolicy="UNAVAILABLE">
            <tabs>
                <Tab text="Statistics">
                    <content>
                        <fx:include fx:id="statistics" source="/fxml/child/statistics.fxml"/>
                    </content>
                </Tab>
                <Tab text="Shedule">
                    <content>
                        <fx:include fx:id="shedule" source="/fxml/child/shedule.fxml"/>
                    </content>
                </Tab>
                <Tab text="Ponab devices">
                    <content>
                        <fx:include fx:id="ponabDevices" source="/fxml/child/ponabDevices.fxml"/>
                    </content>
                </Tab>
                <Tab text="Als devices">
                    <content>
                        <fx:include fx:id="alsDevices" source="/fxml/child/alsDevices.fxml"/>
                    </content>
                </Tab>
                <Tab text="Search">
                    <content>
                        <fx:include fx:id="search" source="/fxml/child/search.fxml"/>
                    </content>
                </Tab>
                <Tab text="Settings">
                    <content>
                        <fx:include fx:id="settings" source="/fxml/child/settings.fxml"/>
                    </content>
                </Tab>
            </tabs>
        </TabPane>
        <Label layoutX="127.0" layoutY="9.0" text="..."
               underline="true">
            <font>
                <Font size="18.0"/>
            </font>
        </Label>
    </children>
</AnchorPane>

在我的statistics.fxml的控制器类中,我正在创建TableView和列:

@FXML
    public TableView<StatisticsRemarkTableDto> statisticsTableView;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> objectColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> noteColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> stageColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> dateColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> vagonColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, String> repeatColumn;
    @FXML
    public TableColumn<StatisticsRemarkTableDto, Integer> remarkIdColumn;

以及this solution中的所有其他内容。 来自实体的信息被添加到我的表中,一切正常。但是!

问题在我尝试添加分页时开始,因为我无法理解我应该如何做到这一点。我的主要方法如下所示:

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/application-context.xml");
        context.getBeanFactory().registerResolvableDependency(Stage.class, primaryStage);
        primaryStage.setTitle(Constants.MAIN_TITLE);
        primaryStage.setScene(new Scene((Parent) context.getBean(SpringFXMLLoader.class).load(Constants.FXML_PATH), 914, 542));
        primaryStage.show();
    }
}

在所有TableView-pagination示例中,在Main类中添加了分页,就像在其他有效且已检查的示例中的代码一样:

private Node createPage(int pageIndex) {

        int fromIndex = pageIndex * rowsPerPage;
        int toIndex = Math.min(fromIndex + rowsPerPage, data.size());
        table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));

        return new BorderPane(table);
    }

    @Override
    public void start(final Stage stage) throws Exception {

        Pagination pagination = new Pagination((data.size() / rowsPerPage + 1), 0);
        pagination.setPageFactory(this::createPage);

        Scene scene = new Scene(new BorderPane(pagination), 1024, 768);
        stage.setScene(scene);
        stage.setTitle("Table pager");
        stage.show();
    }

    public static void main(String[] args) throws Exception {
        launch(args);
    }

有没有办法传递这个问题并将分页添加到我的TableView? 我对这个问题的任何答案都很高兴,问题不会在第一天受到影响。

解决:!

感谢James_Dhis solution。 我试过这个变种,它工作得很好。我的TableView现在已经加入了分页。

我已添加到我的statistics.fxml:

<Pagination fx:id="statisticsTableViewPagination" layoutX="2.0" layoutY="188.0" prefHeight="275.0"
                prefWidth="912.0">
        <fx:define>
            <TableView fx:id="statisticsTableView" layoutX="2.0" layoutY="188.0" prefHeight="301.0" prefWidth="912.0">
                <placeholder>
                    <Label text="No search results found."/>
                </placeholder>
                <columns>
                    <TableColumn fx:id="objectColumn" prefWidth="131.0" text="Object"/>
                    <TableColumn fx:id="noteColumn" minWidth="0.0" prefWidth="167.0" text="Remark"/>
                    <TableColumn fx:id="stageColumn" prefWidth="282.0" text="Stage"/>
                    <TableColumn fx:id="dateColumn" prefWidth="72.0" text="Date"/>
                    <TableColumn fx:id="vagonColumn" prefWidth="133.0" text="Laboratory"/>
                    <TableColumn fx:id="repeatColumn" prefWidth="125.0" text="Repeats"/>
                    <TableColumn fx:id="remarkIdColumn" minWidth="9.0" prefWidth="15.0" text="Id" visible="false"/>
                </columns>
            </TableView>
        </fx:define>
    </Pagination>

在我的控制器中,我添加了与this example中相同的部分。一切都很好。非常感谢!

1 个答案:

答案 0 :(得分:4)

只需在Pagination中定义statistics.fxml

<Pagination fx:id="pagination"/>

然后在该类的控制器中配置它:

@FXML
private TableView<StatisticsRemarkTableDto> statisticsTableView;

@FXML
private Pagination pagination ;

public void initialize() {
    pagination.setPageFactory(this::createPage);
    // etc...
}

由于表本身由页面工厂放置在场景图中,因此在调用initialize()方法之后,即在解析FXML之后,它不是场景图的一部分。因此,您可以直接在控制器中定义表(而不是将其包含在FXML文件中):

private TableView<StatisticsRemarkTableDto> statisticsTableView;

@FXML
private Pagination pagination ;

public void initialize() {

    statisticsTableView = new TableView<>();
    // create columns, etc...
    pagination.setPageFactory(this::createPage);
    // etc...
}

或者您可以在<fx:define>块中的FXML中定义它:

<Pagination fx:id="pagination">
    <fx:define>
        <TableView fx:id="statisticsTableView">
            <columns>
                <TableColumn fx:id="objectColumn" ... />
                <!-- etc -->
            </columns>
        </TableView>
    </fx:define>
</Pagination>

然后以通常的方式将@FXML注入控制器。