Issue
In some situations I need to completely hide the page change buttons in the pagination control, but the hidden area may have been occupied by a page, that is, extend it downwards.
In this example of a window with pagination, I'd like to hide the gray area and enlarge the sky-colored area to the hidden area.
How can I do this?
I tried this:
package javafxpagination;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Pagination;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestPagination extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Test pagination");
Pagination pagination = new Pagination();
pagination.setPageCount(4);
pagination.setMaxPageIndicatorCount(4);
pagination.setCurrentPageIndex(0);
pagination.setPageFactory((pageIndex) -> {
Pane pagePane = new Pane();
pagePane.setPrefWidth(600);
pagePane.setPrefHeight(400);
pagePane.setStyle("-fx-background-color: #DDF1F8;"); //sky color
Button button = new Button("Hide/show page buttons");
button.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
HBox paginationHBox = (HBox)pagination.lookup(".control-box");
Node paginationControl = pagination.lookup(".pagination-control");
paginationControl.setStyle("-fx-background-color: gray;");
paginationControl.setVisible(!paginationControl.isVisible()); //switch visibility
paginationControl.setManaged(paginationControl.isVisible());
paginationControl.minHeight(0.0);
paginationControl.prefHeight(0.0);
paginationControl.maxHeight(0.0);
}
});
pagePane.getChildren().add(button);
return pagePane;
});
VBox vBox = new VBox(pagination);
Scene scene = new Scene(vBox, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
}
but it did not hide gray area and not stretch the sky-colored page area.
Solution
Solution using your VBox layout manager
By adding this line to your application, the Pagination control will expand to fill the available space:
VBox.setVgrow(pagination, Priority.ALWAYS);
That answers the "how to occupy" portion of your question: "JavaFX - pagination: how to hide bottom (control) panel and occupy its area with a page?"
For the hiding, you are already accomplishing that, which is based on the info at:
with the addition of the lookup,
Node paginationControl = pagination.lookup(".pagination-control")
that you are already doing, plus these lines:
paginationControl.setVisible(!paginationControl.isVisible());
paginationControl.setManaged(paginationControl.isVisible());
The lines to set the pagination control's minHeight, prefHeight, maxHeight to 0, are not needed and I wouldn't recommend keeping them.
Background on Layout Managers
Layouts are managed by layout managers. These layout managers have some default behavior, but sometimes you need to configure them or give them hints to achieve the layout behavior you want.
You have your Pagination
control inside a VBox
. If you look at the VBox documentation, it says:
If a vbox is resized larger than its preferred height, by default it will keep children to their preferred heights, leaving the extra space unused. If an application wishes to have one or more children be allocated that extra space it may optionally set a vgrow constraint on the child.
So, the default behavior, which is what you are using, is not to expand the managed content to fill additional available space (which is what you are seeing).
Alternate solution - replacing the pagination control
An alternative implementation is, when hiding, replace the Pagination control with the panel to be displayed rather than hiding the Pagination controls.
For example, remove the pagination control from the parent layout container (the vbox) and, in its place, add the panel to be displayed directly into the parent layout container.
To show the pagination again, you would do the opposite.
That is probably the solution that I would prefer for this kind of work.
For such a solution, you need to be mindful that a node can only be the child of a single parent at any one time and take that into account for your implementation. Also, the previous information about layout managers and setting Vgrow constraints on nodes still applies for this solution.
Answered By - jewelsea
Answer Checked By - Mildred Charles (JavaFixing Admin)