Я пытаюсь отобразить большое количество узлов, и после определенного количества прокрутка становится очень медленной.
Поэтому я использую подход виртуализации, аналогичный TableView . Поскольку у меня есть сложные требования к макету (например, некоторые узлы могут находиться рядом с другими, некоторые должны оставаться на отдельной строке), TableView не подходит.
Я создал свой собственный компонент, но расположение детей не работает. При прокрутке виден светло-красный фон BorderPane, но фон метки и текст метки вообще не отображаются.
Есть идеи ?
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class VirtualNodesDemo extends Application {
@Override
public void start(Stage primaryStage) {
int virtualNodes = 100;
double nodeWidth = 100;
double nodeHeight = 100;
StackPane root = new StackPane();
Pane content = new Pane() {
@Override
protected void layoutChildren() {
System.out.println("content.layoutChildren() ...");
getChildren().clear();
ScrollPane scrollPane = (ScrollPane) getParent().getParent().getParent();
double viewportHeight = scrollPane.getViewportBounds().getHeight();
double scrollTop = scrollPane.getVvalue() * (getPrefHeight() - viewportHeight);
double y = 0;
for (int i = 0; i < virtualNodes; i++) {
if (y + nodeHeight > scrollTop && y < scrollTop + viewportHeight) {
Pane pane = createRealNode(i);
pane.resizeRelocate(10, y, nodeWidth, nodeHeight);
pane.layout();
getChildren().add(pane);
} else {
break;
}
y += nodeHeight + 10;
}
setPrefHeight(y);
}
private Pane createRealNode(int i) {
BorderPane borderPane = new BorderPane();
borderPane.setManaged(false);
Label label = new Label("Node " + i);
label.setStyle("-fx-background-color: #aaf;");
borderPane.setCenter(label);
borderPane.setStyle("-fx-background-color: #faa;");
return borderPane;
}
};
ScrollPane scrollPane = new ScrollPane(content);
scrollPane.setFitToWidth(true);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
scrollPane.vvalueProperty().addListener(observable -> content.layout());
root.getChildren().add(scrollPane);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
При изменении createRealNode, как показано ниже, метка и текст метки отображаются так, как ожидалось. Однако мне нужно иметь возможность использовать BorderPane (и связанные с ним, такие как StackPane, GridPane), поскольку узлы, которые мне нужно визуализировать, довольно большие и имеют много дочерних/подпанелей.
private Pane createRealNode(int i) {
Label label = new Label("Node " + i);
label.setStyle("-fx-background-color: #aaf;");
Pane p = new Pane();
p.setManaged(false);
p.getChildren().add(label);
return p;
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... -component
Дочерние элементы макета JavaFX в пользовательском компоненте макета ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение