Мой вопрос с макетом
У меня есть небольшая проблема с ListView
, и я не уверен, что это из-за каких-то знаний, которые я потерял, или если мой подход ошибочен. Должен признаться, я еще не понял, как JavaFX обрабатывает макет во многих возможных случаях.
Приведенный выше снимок экрана показывает результат, который я получаю дважды с помощью того же кода, за исключением того, что на втором невидимая форма, которую я использую для когерентного макета , становится видимой для отладки.
Различные классы, участвующие в CellFactory
, расширяются Group
, я пробовал с некоторыми другими Parent
без особого успеха до сих пор.
Как воспроизвести
Вместо того, чтобы делиться моими StarShape
, StarRow
и некоторыми другими классами misc (я был бы рад, если это было необходимо), я написал образец, воспроизводящий проблему. Класс расширяет Application
и переопределяет метод start(...)
как таковой:
@Override
public void start(Stage primaryStage) throws Exception {
final StackPane root = new StackPane();
final Scene scene = new Scene(root, 400, 600);
final ListView<Boolean> listView = new ListView<>();
listView.setCellFactory(this::cellFactory);
for (int i = 0; i < 5 ; i++) {
listView.getItems().add(true);
listView.getItems().add(false);
}
root.getChildren().add(listView);
primaryStage.setScene(scene);
primaryStage.setTitle("ListView trims the invisible");
primaryStage.show();
}
где this::cellFactory
-
private ListCell<Boolean> cellFactory(ListView<Boolean> listView) {
return new ListCell<Boolean>() {
@Override
protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
final Rectangle tabShape = new Rectangle();
tabShape.setHeight(20);
tabShape.setWidth(40);
tabShape.setVisible(item);
final Label label = new Label(item.toString());
label.setLayoutX(40);
final Group cellRoot = new Group();
cellRoot.getChildren().add(tabShape);
cellRoot.getChildren().add(label);
setGraphic(cellRoot);
}
}
};
}
В приведенном выше примере будет отображаться ListView<Boolean>
с черными фигурами перед элементами true
(из-за бит tabShape.setVisible(item);
). Элементы false
выглядят как обычные объекты Label
, как если бы невидимая форма в их Group
не была (но это так).
Закрытие комментариев
Отлаживая это, оказывается, что группы с невидимыми фигурами получают отрицательные значения свойства layoutX. Таким образом, элементы управления Label
не выравниваются, как хотелось бы. Этого не происходит, когда я вызываю setLayoutX
и setLayoutY
вне ListView
(невидимые фигуры вынуждают смещения), но это, вероятно, не единственное место, где это произойдет.
Что происходит и как его избежать? В качестве альтернативы, как Я предполагаю, что я приближаюсь к этому неправильному, что было бы правильным путем? Другими словами, в чем вопрос, который я должен задать вместо этого?