gpt4 book ai didi

java - 如何居中JavaFX场景图“相机”

转载 作者:行者123 更新时间:2023-12-02 03:22:58 31 4
gpt4 key购买 nike

我有一个带有两个圆的组,当我用平移过渡移动其中一个时,我应该看到静止的一个保持在中心(位于场景图的中间),而另一个移动。取而代之的是,“摄像机”跟随移动的圆圈,使其看起来好像都在分开。

有没有一种方法可以将相机定在0,0的中心,以便它保持在那里而不是跟随圆圈呢?

 import javafx.animation.Interpolator;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test extends Application
{
public static void main(String[] args)
{
launch(args);
}

public void start(Stage stage)
{
BorderPane root = new BorderPane();
root.setStyle("-fx-background-color: Black");
Group graph = new Group();
root.setCenter(graph);
graph.setLayoutX(250);
graph.setLayoutY(250);

Circle circle = new Circle(0,0,5);
circle.setFill(Color.ORANGE);
graph.getChildren().add(circle);

Circle circle2 = new Circle(0, 0, 5);
circle2.setFill(Color.AQUA);
graph.getChildren().add(circle2);

TranslateTransition t = new TranslateTransition(Duration.millis(1000), circle);
t.setFromX(0);
t.setToX(100);
t.setFromY(0);
t.setToY(0);

t.setInterpolator(Interpolator.LINEAR);
t.play();

stage.setTitle("Circle Test");
stage.setScene((new Scene(root, 500, 500)));
stage.show();
}
}

最佳答案

要了解此处的布局所发生的情况,首先请注意,完全将Group graph的布局坐标忽略了,因为您将graph放置在布局容器(a BorderPane)中。 (注释setLayoutXsetLayoutY行,您将发现它们没有区别。)布局容器将根据1.为其子节点留有多少空间,2。子节点的最小空间,首选和最大尺寸。由于在此示例中BorderPane没有任何其他子节点,因此它希望将其所有可用空间分配给graph。由于graph位于中心,因此如果无法分配空间,它将居中,而其余空间则未使用。

Group的行为不同于Region(包括ControlPane及其子类):根据documentation,它们不可调整大小,并具有子代的集体界限。

在动画开始时,两个圆是重合的,以(0,0)为中心,半径为5:因此,它们的边界框(因此是Group的边界框)的左上角为(-5,-5),宽度为和10的高度。此方形10x10边界框不能做大(因为它是Group,不能调整大小),并且位于屏幕中央。由于BorderPane具有可用的总宽度的500像素,因此有490个未使用宽度的像素,它们在Group的两侧均等地划分以居中:245左侧和 在右边。因此, 245的左边缘(即两个圆的左边缘)在 Group坐标系中的 x=245处。

动画结束时,一个圆圈保留在 BorderPane处,宽度为 (-5,-5),而另一个圆圈已向右平移 10x10个像素,因此其边界框从 100扩展到 (95, -5)。因此, (105, 5)的边界框具有其子节点的集体边界,在 Group,宽度 (-5, -5)和高度 110的左上方。此框无法调整大小,因此 10的布局机制将其定位在其可用区域的中心。由于 BorderPane的可用宽度为 BorderPane像素,因此有390个未使用的像素宽度在两边均分: 500的左侧为 195,右侧的为 Group。因此,此时, 195的左边缘(即未平移圆的左边缘)在 Group坐标系中位于 x=195处。因此,在动画结束时,未平移的圆圈已将 BorderPane像素(平移距离的一半)向 50坐标系中的左侧移动。

此处更自然的事情是使用 BorderPane代替 PaneGroup是可调整大小的,因此 Pane只需将其扩展以填充所有可用空间。因此它将位于 BorderPane的左上方并填充 BorderPaneBorderPane的边界从 Pane开始,并扩展到其宽度和高度。因此,如果仅将 (0,0)更改为 Group,则未平移的圆将不会在动画过程中根据需要移动。

但是,圆圈​​现在都将从窗格的左上角而不是中心开始。如果希望它们从中心开始,则可以更改圆自身的坐标,因此它们以 Pane为中心开始:

import javafx.animation.Interpolator;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test extends Application {
public static void main(String[] args) {
launch(args);
}

public void start(Stage stage) {
BorderPane root = new BorderPane();
root.setStyle("-fx-background-color: Black");
Pane graph = new Pane();
root.setCenter(graph);
// graph.setLayoutX(250);
// graph.setLayoutY(250);

Circle circle = new Circle(250, 250, 5);
circle.setFill(Color.ORANGE);
graph.getChildren().add(circle);

Circle circle2 = new Circle(250, 250, 5);
circle2.setFill(Color.AQUA);
graph.getChildren().add(circle2);

TranslateTransition t = new TranslateTransition(Duration.millis(1000), circle);
t.setFromX(0);
t.setToX(100);
t.setFromY(0);
t.setToY(0);

t.setInterpolator(Interpolator.LINEAR);
t.play();

stage.setTitle("Circle Test");
stage.setScene((new Scene(root, 500, 500)));
stage.show();
}
}


或者,您可以使用 (250, 250)作为根,而不是 Pane。普通的 BorderPane不做任何布局,因此在这种情况下 PanelayoutX设置将生效。因此,您可以将圆的中心还原为 layoutY,并使用 (0,0)上的布局设置将其居中:

import javafx.animation.Interpolator;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test extends Application {
public static void main(String[] args) {
launch(args);
}

public void start(Stage stage) {
Pane root = new Pane();
root.setStyle("-fx-background-color: Black");
Pane graph = new Pane();
root.getChildren().add(graph);
graph.setLayoutX(250);
graph.setLayoutY(250);

Circle circle = new Circle(0, 0, 5);
circle.setFill(Color.ORANGE);
graph.getChildren().add(circle);

Circle circle2 = new Circle(0, 0, 5);
circle2.setFill(Color.AQUA);
graph.getChildren().add(circle2);

TranslateTransition t = new TranslateTransition(Duration.millis(1000), circle);
t.setFromX(0);
t.setToX(100);
t.setFromY(0);
t.setToY(0);

t.setInterpolator(Interpolator.LINEAR);
t.play();

stage.setTitle("Circle Test");
stage.setScene((new Scene(root, 500, 500)));
stage.show();
}
}

关于java - 如何居中JavaFX场景图“相机”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39378901/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com