簡體   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