Javafx:询问节点是否在视口内?
当使用滚动窗格(使用缩放变换进行缩放)时,是否有自动方法获取场景树中当前可见(或不可见)的节点(例如通过事件回调)Javafx:询问节点是否在视口内?,javafx,Javafx,当使用滚动窗格(使用缩放变换进行缩放)时,是否有自动方法获取场景树中当前可见(或不可见)的节点(例如通过事件回调) 或者我必须使用单独的结构(四叉树,RTree)来跟踪节点吗 我不认为有什么特别简单的方法可以做到这一点,但您可以使用一些绑定来获得所需的内容。以下是一个基本想法: import javafx.application.Application; import javafx.beans.binding.Bindings; import javafx.beans.binding.Objec
或者我必须使用单独的结构(四叉树,RTree)来跟踪节点吗 我不认为有什么特别简单的方法可以做到这一点,但您可以使用一些绑定来获得所需的内容。以下是一个基本想法:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.collections.ListChangeListener;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ScrollPaneTracking extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
populatePane(pane);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(pane);
ObjectBinding<Bounds> visibleBounds = Bindings.createObjectBinding(() -> {
Bounds viewportBounds = scrollPane.getViewportBounds();
Bounds viewportBoundsInScene = scrollPane.localToScene(viewportBounds);
Bounds viewportBoundsInPane = pane.sceneToLocal(viewportBoundsInScene);
return viewportBoundsInPane ;
}, scrollPane.hvalueProperty(), scrollPane.vvalueProperty(), scrollPane.viewportBoundsProperty());
FilteredList<Node> visibleNodes = new FilteredList<>(pane.getChildren());
visibleNodes.predicateProperty().bind(Bindings.createObjectBinding(() ->
node -> node.getBoundsInParent().intersects(visibleBounds.get()),
visibleBounds));
visibleNodes.addListener((ListChangeListener.Change<? extends Node> c) -> {
visibleNodes.forEach(System.out::println);
System.out.println();
});
Scene scene = new Scene(scrollPane, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void populatePane(Pane pane) {
Rectangle rect = new Rectangle(50, 50, 250, 100);
rect.setFill(Color.CORNFLOWERBLUE);
Circle circle = new Circle(450, 450, 75);
circle.setFill(Color.SALMON);
Polygon triangle = new Polygon(600, 600, 750, 750, 450, 750);
triangle.setFill(Color.CHARTREUSE);
Ellipse ellipse = new Ellipse(200, 600, 50, 150);
ellipse.setFill(Color.DARKORCHID);
pane.getChildren().addAll(rect, circle, triangle, ellipse);
}
public static void main(String[] args) {
launch(args);
}
}
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.binding.ObjectBinding;
导入javafx.collections.ListChangeListener;
导入javafx.collections.transformation.FilteredList;
导入javafx.geometry.Bounds;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.ScrollPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.scene.shape.eliple;
导入javafx.scene.shape.Polygon;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
公共类ScrollPaneTracking扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
窗格=新窗格();
聚苯醚(窗格玻璃);
ScrollPane ScrollPane=新的ScrollPane();
scrollPane.setContent(窗格);
ObjectBinding visibleBounds=绑定。createObjectBinding(()->{
Bounds viewportBounds=scrollPane.getViewportBounds();
Bounds viewportBoundsInScene=scrollPane.localToScene(viewportBounds);
Bounds viewportBoundsInPane=pane.sceneToLocal(viewportBoundsInScene);
返回viewportBoundsInPane;
},scrollPane.hvalueProperty(),scrollPane.vvalueProperty(),scrollPane.viewportBoundsProperty());
FilteredList visibleNodes=新建FilteredList(pane.getChildren());
visibleNodes.predicateProperty().bind(Bindings.createObjectBinding(()->
节点->节点.getBoundsInParent().intersects(visibleBounds.get()),
可见边界);
visibleNodes.addListener((ListChangeListener.Change
ObservableSet<Node> visibleNodes = FXCollections.observableSet();
visibleBounds.addListener((obs, oldBounds, newBounds) -> {
for (Node node : pane.getChildren() ) {
if (node.getBoundsInParent().intersects(newBounds)) {
visibleNodes.add(node);
} else {
visibleNodes.remove(node);
}
}
});
visibleNodes.addListener((SetChangeListener.Change<? extends Node> c) -> {
visibleNodes.forEach(System.out::println);
System.out.println();
});