-2

I have a customized TableView defined in an FXML and the table works fine so far. The code is something like the followings:

<FitWidthTableView fx:id="dataDisplayView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="380.0" VBox.vgrow="ALWAYS">
    <columns>
        <TableColumn fx:id="rowColumn" maxWidth="50.0" prefWidth="30.0" sortable="false" style="-fx-alignment: CENTER_RIGHT;" text="Row" />
        ...
</FitWidthTableView>

Now, I need to add the Pagination due to a huge amount of data (from a DB). It would be great if I can wrap around the TableView tag with the Pagination tag. I find a sample with the approach as the following

    <Pagination fx:id="pagination" layoutX="2.0" layoutY="188.0" prefHeight="275.0" prefWidth="912.0">
    <fx:define>
        <FitWidthTableView fx:id="dataDisplayView" maxHeight="1.7976931348623157E308"
                           maxWidth="1.7976931348623157E308" prefHeight="300.0" prefWidth="380.0"
                           VBox.vgrow="ALWAYS">
            <columns>
                <TableColumn fx:id="rowColumn" maxWidth="50.0" prefWidth="30.0" sortable="false"
                             style="-fx-alignment: CENTER_RIGHT;" text="Row"/>
               ...
            </columns>
            <VBox.margin>
                <Insets left="1.0" right="1.0"/>
            </VBox.margin>
        </FitWidthTableView>
    </fx:define>
</Pagination>

while almost all examples of TableView with Pagination are done without FXML.

I, however, don't see the pagination controller code sample which shall do a few things: determine the number of pages, specify the page size, and populate data to the table. Can someone advise on the subject?

My controller is something like the followings:

public class DataViewerController implements Initializable {


@FXML
private Pagination pagination ;

@FXML
private FitWidthTableView<OutputData> dataDisplayView;

@FXML
private TableColumn<OutputData, Integer> rowColumn;

…

@Autowired
private OutputDataRepository outputDataRepository;

@Override // This method is called by the FXMLLoader when initialization is complete
@FXML
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
  …
  
  }
…
}

How to populate data with the above code structure?

vic
  • 2,548
  • 9
  • 44
  • 74
  • It's not clear what you're asking here. The controller code is just Java, so it would be the same as any examples you have found that don't use FXML. Can you create and post a [mre]? – James_D Nov 17 '22 at 16:20
  • I add the controller code snap to my post to clarify my question. I can't see how to populate the data to the table after adding pagination to the code. Thanks. – vic Nov 17 '22 at 17:21
  • I have no idea what a `FitWidthTableView` is. With a regular `TableView` you would just do `dataDisplayView.setItems(...)` as normal. With a `Pagination`, you presumably want to set the items to a sublist of the full data list in the page factory. Again, there is absolutely no difference between doing this in your controller code and doing this in a JavaFX application which doesn't use FXML, so it's not at all clear what your question is. Any pagination example should show you how to do this. – James_D Nov 17 '22 at 17:55
  • The class is from https://stackoverflow.com/questions/23284437/javafx-tablecolumn-resize-to-fit-cell-content/69961976#69961976 to allow a full display of extremely long data. And the previous code have the data populated in the public void initialize(URL fxmlFileLocation, ResourceBundle resources) method with dataDisplayView.setItems(FXCollections.observableArrayList(ll)); The same code doesn't get me a table at all, but only pagination on the bottom. – vic Nov 17 '22 at 18:15
  • 1
    [Here](https://stackoverflow.com/a/25424208/2189127) is an example showing how to use a table view in a pagination. – James_D Nov 17 '22 at 18:16
  • *"The same code doesn't get me a table at all, but only pagination on the bottom."*. Yes, of course. You wrapped it in [``](https://openjfx.io/javadoc/19/javafx.fxml/javafx/fxml/doc-files/introduction_to_fxml.html#define_elements) – James_D Nov 17 '22 at 18:18
  • Thanks very much for the reference. I will try it and see how it works out. I am confused with the createPage returned data type. In the code sample, it is Node. I have seen the Text as the returned data type in another code sample. Any insight? – vic Nov 17 '22 at 18:34
  • 1
    A `TableView` _is a_ `Node`. – trashgod Nov 17 '22 at 18:36
  • It's not clear what the question is. The only "catch" about using a `TableView` in a `Pagination` in FXML is that you have to provide the `TableView` from the page factory, so it can't be included anywhere else in the scene graph. The way to define it in FXML without it being part of the scene graph is to wrap it in ``. You've already done that, so the rest is all just standard pagination code, which I linked in the previous comment. – James_D Nov 17 '22 at 19:03
  • @trashgod If TableView is Node, why the createPage doesn't return a tableveiw but wraps it with BorderPane? – vic Nov 17 '22 at 19:10
  • There's no real need for it to wrap it in a `BorderPane`; there is a comment to that effect below the answer. – James_D Nov 17 '22 at 19:15
  • Thanks for your help. It works well so far to my test. – vic Nov 17 '22 at 20:50

1 Answers1

2

As shown here, any Pagination property can be initialized in your FXML:

<Pagination pageCount="8" currentPageIndex="3" …/>

More likely, you'll derive the values based on your actual data. Your implementation of the pageFactory() should set the desired partition on the table and return a table view, as seen here.

I want to keep the TableView in the FXML.

As, @James_D comments, the TableView declaration is irrelevant to the pageFactory(). As a concrete example, start from the complete example cited here and substitute the following FXML declarations in center:

<center>
    <Pagination fx:id="pager" currentPageIndex="1"/>
    <fx:define>
        <TableView fx:id="tableView" prefHeight="60.0">
            <columns>
                <TableColumn fx:id="itemName" text="Item Name" />
                <TableColumn fx:id="pricePerUnit" text="Price Per Unit" />
                <TableColumn fx:id="quantity" text="Quantity" />
                <TableColumn fx:id="amount" text="Amount" />
            </columns>
        </TableView>
    </fx:define>
</center>

In the controller, inject the pager and initialize() it:

@FXML
Pagination pager;
…
//tableView.setItems(objList);
pager.setPageCount(objList.size());
pager.setPageFactory((Integer pageIndex) -> createPage(pageIndex));

The following factory assigns a single row to the tableView and returns it:

public TableView<TestModel> createPage(int page) {
    tableView.getItems().setAll(objList.get(page));
    return tableView;
}

image

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I have seen the sample. I want to keep the tableview in the FXML because there are some style settings and I don't want to create a CSS file just for the table. – vic Nov 17 '22 at 18:45
  • 4
    @vic Again, the fact that the table is defined in FXML makes absolutely no difference to how the page factory is defined (and other configurations of the pagination). I don't understand why you keep raising this point; it's irrelevant. – James_D Nov 17 '22 at 18:56
  • Sorry, I am new to JavaFX. – vic Nov 17 '22 at 19:02