繁体   English   中英

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

[英]How to center javafx scene graph “camera”

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

有没有一种方法可以将相机定在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在布局容器( BorderPane )。 (注释掉setLayoutXsetLayoutY行,您将发现它们没有区别。)布局容器将根据1.为其子节点保留多少空间,2.根据子节点的最小,首选和最大大小来调整其子节点的大小。大小。 由于BorderPane在此示例中没有任何其他子节点,因此它希望将其所有可用空间分配给graph 由于graph位于中心,因此如果没有空间可以分配,则它将居中,剩下的空间则不使用。

Group的行为与Region (包含ControlPane及其子类)的Region不同:根据文档,它们的大小不可调整,具有其子代的集体边界

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

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

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

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

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();
    }
}

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

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();
    }
}

您可以将类名更改为所需的任何名称。

您遇到的问题是您通过setCenter()方法添加了它,该方法自动使它的中心成为窗格的中心。

我希望这是及时的。

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 NewClass extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage stage) {
        BorderPane root = new BorderPane();
        root.setStyle("-fx-background-color: #efefef");
        Group graph = new Group();
        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.setCycleCount(5);
        t.play();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM