![](/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.