While looking at Pagination
, the question of rendering complex pages arose. The API example, et al., typically specify a pageFactory
that simply constructs a new control each time it is called. Indeed, profiling the example below while paging showed minimal memory pressure, with a flurry of new instances that were promptly collected. What can I do if growing complexity changes the picture?
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Pagination;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
/** @see https://stackoverflow.com/q/76359690/230513 */
public class PaginationSample extends Application {
private static final int N = 100;
private record Item(String name, Color color) {
private static final Random r = new Random();
public static Item ofRandom() {
var s = (char) ('A' + r.nextInt(26))
+ String.valueOf(r.nextInt(900_000) + 100_000);
var c = Color.rgb(r.nextInt(255), r.nextInt(255), r.nextInt(255));
return new Item(s, c);
}
}
@Override
public void start(Stage stage) {
stage.setTitle("PaginationTStreamest");
List<Item> items = Stream.generate(Item::ofRandom)
.limit(N).collect(Collectors.toList());
var pagination = new Pagination(items.size(), 0);
pagination.setPageFactory((i) -> createItemPane(items.get(i)));
stage.setScene(new Scene(pagination));
stage.show();
pagination.requestFocus();
}
private StackPane createItemPane(Item item) {
var pane = new StackPane();
pane.setPadding(new Insets(16));
var label = new Label(item.name, new Rectangle(320, 240, item.color));
label.setTextFill(item.color.invert());
label.setStyle("-fx-font-family: serif; -fx-font-size: 36;");
label.setContentDisplay(ContentDisplay.CENTER);
var button = new Button("Button");
StackPane.setAlignment(button, Pos.BOTTOM_RIGHT);
button.setOnAction((e) -> {
System.out.println(item);
});
pane.getChildren().addAll(label, button);
return pane;
}
public static void main(String[] args) {
launch(args);
}
}