Encontrei um problema de controle ao trabalhar em um ListView com células personalizadas.
O código é mais ou menos assim:
import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Spinner;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
public class ListViewTest extends Application {
@Override
public void start(Stage primaryStage) {
VBox root = new VBox();
BorderPane b1 = new BorderPane();
b1.setPrefHeight(25);
VBox.setVgrow(b1, Priority.NEVER);
b1.setLeft(new Label("Title"));
ListView<Item> traceSetList = new ListView<>();
VBox.setVgrow(traceSetList, Priority.ALWAYS);
traceSetList.setCellFactory(listView -> {
ListCell<Item> listCell = new ListCell<>() {
@Override
protected void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
setText(item.getName());
CheckBox cb = new CheckBox();
cb.selectedProperty().bindBidirectional(item.getSelectedProperty());
setGraphic(cb);
}
}
};
return listCell;
});
traceSetList.getItems().addAll(addItems());
HBox h1 = new HBox();
h1.getChildren().addAll(new Label("Label"), new Spinner<Integer>());
VBox.setVgrow(h1, Priority.NEVER);
root.getChildren().addAll(b1, traceSetList, h1);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private static List<Item> addItems() {
List<Item> items = new ArrayList<>();
for (int i = 0; i < 20; i++) {
items.add(new Item("item-" + i));
}
return items;
}
public static void main(String[] args) {
launch(args);
}
@Data
public static class Item {
private String name;
private final SimpleBooleanProperty selectedProperty = new SimpleBooleanProperty(false);
public Item(String name) {
this.name = name;
}
}
}
O código acima é apenas um exemplo simplificado, então não há problema algum. Meu aplicativo é um pouco mais complicado e não tenho certeza do que está causando o problema.
Aqui está o problema:
Na foto acima, você pode ver que há mais espaço na parte inferior do ListView, mas ele não exibirá os demais itens.
E quando tento rolar o ListView arrastando o ScrollBar ou rolando o mouse, ele não funciona corretamente. Quando tento rolar para baixo, o espaço em branco foi movido para cima e não consigo ver o último item:
O comportamento parece que o ListView não consegue obter o tamanho da célula correto, portanto não consegue fazer o layout corretamente. Ou talvez haja alguns itens vazios. Não tenho certeza de qual é o problema e onde procurar. Realmente preciso de algumas sugestões.
Não consigo reproduzir o problema pelo código de exemplo. Desculpe por isso.
Ocorreram erros no comportamento de rolagem do JavaFX ListView com células personalizadas em algumas versões do JavaFX (não me lembro das versões exatas, mas algo como 17-20) e vários bugs foram corrigidos (alguns podem permanecer).
Experimente a versão estável mais recente (JavaFX 21.0.1).
Conforme observado pelo solicitante nos comentários: