滚动窗格内的 JavaFX 坐标
JavaFX coordinate inside scrollpane
我在 Vbox 中组织了各种对象,它工作得很好。我可以通过在 layoutX/Y 上使用 getter 来访问每个对象的坐标
myObject.getlayoutY() // for example
现在我将 Vbox 放在 Scrollpane 中以允许在 Vbox 上滚动,所以我有这样的配置:
<ScrollPane>
<content>
<VBox>
<children>
<myobject1/>
....
<myobjectN/>
</children>
</VBox>
</content>
它工作得很好,但问题是:我不明白它在滚动窗格内移动什么。
当我尝试在 Vbox 或 myObject 上使用 getlayoutY() 时,即使我滚动,我也有一个常量值。
我怎样才能轻松地将对象的新坐标真正地访问到滚动值??
编辑:我想在滚动窗格的父坐标系中进行转换
注意:我设法访问滚动条值(在 [0-1] 之间)并且我可以使用 getLocalToSceneTransform() 访问坐标,但我认为我走错了路。
看看下面的例子是否有助于实现你想要的:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class BindToScrollingObject extends Application {
@Override
public void start(Stage primaryStage) {
HBox root = new HBox();
ScrollPane scroller = new ScrollPane();
VBox vbox = new VBox(20);
scroller.setContent(vbox);
Label bindingLabel = new Label("Binding here");
for (int i = 0; i < 4; i++) {
vbox.getChildren().add(new Label("Item "+(i+1)));
}
vbox.getChildren().add(bindingLabel);
for (int i = 0; i < 4; i++) {
vbox.getChildren().add(new Label("Item "+(i+6)));
}
Label anchor = new Label("Anchor");
anchor.setStyle("-fx-background-color: antiquewhite");
StackPane stack = new StackPane(anchor);
root.getChildren().addAll(scroller, stack);
Line line = new Line();
line.setManaged(false);
root.getChildren().add(line);
ChangeListener<Object> listener = (obs, oldValue, newValue) ->
updateLine(line, anchor, bindingLabel);
anchor.boundsInLocalProperty().addListener(listener);
anchor.localToSceneTransformProperty().addListener(listener);
bindingLabel.boundsInLocalProperty().addListener(listener);
bindingLabel.localToSceneTransformProperty().addListener(listener);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
private void updateLine(Line line, Node start, Node end) {
Node target = line.getParent();
Bounds startBounds = convertBoundsToTarget(start, target);
Bounds endBounds = convertBoundsToTarget(end, target);
line.setStartX(startBounds.getMinX() + startBounds.getWidth() / 2);
line.setStartY(startBounds.getMinY() + startBounds.getHeight() / 2);
line.setEndX(endBounds.getMinX() + endBounds.getWidth() / 2);
line.setEndY(endBounds.getMinY() + endBounds.getHeight() / 2);
}
private Bounds convertBoundsToTarget(Node node, Node target) {
Bounds boundsInScene = node.localToScene(node.getBoundsInLocal());
return target.sceneToLocal(boundsInScene);
}
public static void main(String[] args) {
launch(args);
}
}
我在 Vbox 中组织了各种对象,它工作得很好。我可以通过在 layoutX/Y 上使用 getter 来访问每个对象的坐标
myObject.getlayoutY() // for example
现在我将 Vbox 放在 Scrollpane 中以允许在 Vbox 上滚动,所以我有这样的配置:
<ScrollPane>
<content>
<VBox>
<children>
<myobject1/>
....
<myobjectN/>
</children>
</VBox>
</content>
它工作得很好,但问题是:我不明白它在滚动窗格内移动什么。
当我尝试在 Vbox 或 myObject 上使用 getlayoutY() 时,即使我滚动,我也有一个常量值。
我怎样才能轻松地将对象的新坐标真正地访问到滚动值??
编辑:我想在滚动窗格的父坐标系中进行转换
注意:我设法访问滚动条值(在 [0-1] 之间)并且我可以使用 getLocalToSceneTransform() 访问坐标,但我认为我走错了路。
看看下面的例子是否有助于实现你想要的:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class BindToScrollingObject extends Application {
@Override
public void start(Stage primaryStage) {
HBox root = new HBox();
ScrollPane scroller = new ScrollPane();
VBox vbox = new VBox(20);
scroller.setContent(vbox);
Label bindingLabel = new Label("Binding here");
for (int i = 0; i < 4; i++) {
vbox.getChildren().add(new Label("Item "+(i+1)));
}
vbox.getChildren().add(bindingLabel);
for (int i = 0; i < 4; i++) {
vbox.getChildren().add(new Label("Item "+(i+6)));
}
Label anchor = new Label("Anchor");
anchor.setStyle("-fx-background-color: antiquewhite");
StackPane stack = new StackPane(anchor);
root.getChildren().addAll(scroller, stack);
Line line = new Line();
line.setManaged(false);
root.getChildren().add(line);
ChangeListener<Object> listener = (obs, oldValue, newValue) ->
updateLine(line, anchor, bindingLabel);
anchor.boundsInLocalProperty().addListener(listener);
anchor.localToSceneTransformProperty().addListener(listener);
bindingLabel.boundsInLocalProperty().addListener(listener);
bindingLabel.localToSceneTransformProperty().addListener(listener);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
private void updateLine(Line line, Node start, Node end) {
Node target = line.getParent();
Bounds startBounds = convertBoundsToTarget(start, target);
Bounds endBounds = convertBoundsToTarget(end, target);
line.setStartX(startBounds.getMinX() + startBounds.getWidth() / 2);
line.setStartY(startBounds.getMinY() + startBounds.getHeight() / 2);
line.setEndX(endBounds.getMinX() + endBounds.getWidth() / 2);
line.setEndY(endBounds.getMinY() + endBounds.getHeight() / 2);
}
private Bounds convertBoundsToTarget(Node node, Node target) {
Bounds boundsInScene = node.localToScene(node.getBoundsInLocal());
return target.sceneToLocal(boundsInScene);
}
public static void main(String[] args) {
launch(args);
}
}