1

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.

image

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.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
Marogo
  • 23
  • 5
  • 1
    why? you increase the empty space and your users loose control about which page to show.. – kleopatra Aug 19 '21 at 22:37
  • @kleopatra I need to hide the buttons, because depending on certain conditions, I only display one page (the others are unavailable). Of course, instead of using pagination with one page, I could insert a panel in this place, but I have to think about which solution will be better. ;-) – Marogo Aug 20 '21 at 07:02

1 Answers1

2

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.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • Using the "VBox.setVgrow(pagination, Priority.ALWAYS);" was enough to achieve what I needed. Thanks a lot my Friend! – Marogo Aug 20 '21 at 06:51