如何居中javafx场景图"相机"

时间:2016-09-07 20:59:03

标签: java javafx

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

有没有办法将相机对准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();
}
 }

2 个答案:

答案 0 :(得分:1)

要了解此处布局的内容,请首先注意Group graph的布局坐标完全被忽略,因为您将graph放置在布局容器中(a { {1}})。 (注释掉BorderPanesetLayoutX行,你会看到它们没有区别。)布局容器将根据它的子节点大小调整其子节点的大小,2。节点'最小,首选和最大尺寸。由于setLayoutY在此示例中没有任何其他子节点,因此它希望将所有可用空间分配给BorderPane。由于graph位于中心,如果有空间无法分配给它,它将使其居中,而剩下的空间则不用。

graphGroup s(包括Region s,Control及其子类)的行为不同:根据documentation它们是Pane 无法调整大小承担其子女的集体界限

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

在动画结束时,一个圆圈保持在BorderPane,宽度为(-5,-5),而另一个圆圈已向右翻译10x10个像素,因此其边界框从{ {1}}到100。因此,(95, -5)的边界框占据其子节点的集合边界,其左上角为(105, 5),宽度为Group,高度为(-5, -5)。此框无法调整大小,因此110的布局机制将此框置于可用区域的中心。由于10的宽度为BorderPane个像素,因此宽度中有390个未使用的像素,它们在BorderPane左侧的500左右平均分配:195 Group在右边。因此,此时195的左边缘(未翻译圆的左边缘)位于Group坐标系中的x=195。因此,在动画结束时,未翻译的圆圈已将BorderPane像素(平移距离的一半)移动到50坐标系中的左侧。

这里更自然的事情是使用BorderPane代替PaneGroup可调整大小,因此Pane只会展开它以填充所有可用空间。因此,它将位于BorderPane的左上角并填充BorderPaneBorderPane的边界从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不做任何布局,因此在这种情况下,PanelayoutX设置将生效。因此,您可以将圈子的中心还原为layoutY,并使用(0,0)上的布局设置将其居中:

graph

答案 1 :(得分:0)

您可以将班级名称更改为您想要的任何名称。

您遇到的问题是您通过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();
    }
}