![](/img/trans.png)
[英]JavaFX: how to change a scene included in the center of a BorderPane
[英]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
)。 (注釋掉setLayoutX
和setLayoutY
行,您將發現它們沒有區別。)布局容器將根據1.為其子節點保留多少空間,2.根據子節點的最小,首選和最大大小來調整其子節點的大小。大小。 由於BorderPane
在此示例中沒有任何其他子節點,因此它希望將其所有可用空間分配給graph
。 由於graph
位於中心,因此如果沒有空間可以分配,則它將居中,剩下的空間則不使用。
Group
的行為與Region
(包含Control
, Pane
及其子類)的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
上的左側Group
和195
上的右側。 因此,此時, 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
不執行任何布局,因此在這種情況下, layoutX
和layoutY
設置將生效。 因此,您可以將圓心還原為(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.