Javafx 2 如何使JavaFX组在添加子对象时不四处移动?
如果您观看下面的测试,您将看到所有的圆都在移动,而不仅仅是添加了一个新的圆。并不是每次都这样。我认为只有当新的孩子在现有的界限之外的时候。但是我怎样才能得到它,这样当我添加另一个圆时,无论我把圆放在哪里,它都不会移动组和它的所有子对象 请注意,如果我不设置组的比例,它们不会全部移动。因此,这与设置比例有关Javafx 2 如何使JavaFX组在添加子对象时不四处移动?,javafx-2,Javafx 2,如果您观看下面的测试,您将看到所有的圆都在移动,而不仅仅是添加了一个新的圆。并不是每次都这样。我认为只有当新的孩子在现有的界限之外的时候。但是我怎样才能得到它,这样当我添加另一个圆时,无论我把圆放在哪里,它都不会移动组和它的所有子对象 请注意,如果我不设置组的比例,它们不会全部移动。因此,这与设置比例有关 import javafx.application.*; import javafx.beans.value.*; import javafx.collections.*; import ja
import javafx.application.*;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.shape.*;
import javafx.stage.*;
import java.util.*;
public class GroupTest extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
Pane pane = new Pane();
Group root = new Group();
// NOTE: removing these two setScale* lines stops the undesirable behavior
root.setScaleX(.2);
root.setScaleY(.2);
root.setTranslateX(100);
root.setTranslateY(100);
root.layoutXProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observableValue, Number number, Number number2) {
System.out.println("root layout: " + root.getLayoutX() + ", " + root.getLayoutY());
}
});
root.getChildren().addListener(new ListChangeListener<Node>() {
@Override public void onChanged(Change<? extends Node> change) {
System.out.println("root: " + root.getBoundsInParent());
System.out.println("root: " + root.getBoundsInLocal());
System.out.println("root: " + root.getLayoutBounds());
System.out.println("root: " + root.getLayoutX() + ", " + root.getLayoutY());
}
});
pane.getChildren().add(root);
Scene scene = new Scene(pane, 500, 500);
stage.setScene(scene);
stage.show();
new Thread(() -> {
Random r = new Random();
try {
while (true) {
expand = expand * 1.1;
Thread.sleep(700);
Platform.runLater(() -> {
root.getChildren().add(new Circle(r.nextInt((int)(1000*expand)) - 500*expand, r.nextInt((int)(1000*expand)) - 500*expand, r.nextInt(50)+30));
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
static double expand = 1.0;
}
导入javafx.application.*;
导入javafx.beans.value.*;
导入javafx.collections.*;
导入javafx.scene.*;
导入javafx.scene.layout.*;
导入javafx.scene.shape.*;
导入javafx.stage.*;
导入java.util.*;
公共类GroupTest扩展了应用程序{
公共静态void main(字符串[]args){
发射(args);
}
公众假期开始(阶段){
窗格=新窗格();
组根=新组();
//注意:删除这两条setScale*行将停止不希望出现的行为
根.setScaleX(.2);
根.setScaleY(.2);
根.setTranslateX(100);
根。setTranslateY(100);
root.layoutXProperty().addListener(新的ChangeListener()){
@凌驾
public void已更改(observeValue,因为在添加每个圆后更改组的大小,从而触发组在窗格内的重新定位
您可以:
将圆直接添加到窗格中
pane.getChildren().add(new Circle(...
添加大背景以固定组大小:
// numbers are huge because you are using 1/5 scaling
Rectangle base = new Rectangle(-10000, -10000, 20000, 20000);
base.setFill(Color.LIGHTGRAY);
root.getChildren().add(base);
首先,我想说的是,你所看到的行为可以通过一个小得多的程序来实现,更不用说你对圆所做的计算了。r.nextInt(250)
对于圆的位置,可以足够看到行为,并且更容易看到发生了什么。此外,为了调试,我在绑定到组的layoutbounds的窗格中添加了一个可见矩形,您可以在其中看到发生了什么:
final Rectangle background = new Rectangle(0, 0, 0, 0);
root.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
@Override
public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
background.setX(newValue.getMinX());
background.setY(newValue.getMinY());
background.setWidth(newValue.getWidth());
background.setHeight(newValue.getHeight());
}
});
background.setFill(null);
background.setStroke(Color.RED);
pane.getChildren().add(background);
最终矩形背景=新矩形(0,0,0,0);
root.layoutBoundsProperty().addListener(新的ChangeListener()){
@凌驾
public void已更改(observeValue此处的真正问题是组的轴心点(旋转和缩放的相对点)取决于组的布局边界。因此,如果布局边界因添加新子级(或现有子级更改位置、大小或旋转)而更改,组上所有变换的相对点也会更改
在JavaFX源代码中,您可以在Node.java文件中找到轴心点的定义。方法impl_getPivotX()
和impl_getPivotY()
返回布局边界的中心x和y坐标
遗憾的是,没有手动设置轴心点的选项。但是,由于每个节点都管理一个附加转换列表,这些转换应用于标准转换之上,因此您可以轻松实现所需的行为:
final Scale scale = new Scale();
group.getTransforms().add(scale);
// change scale
scale.setX(2);
我在画一个信号时遇到了同样的问题,这个信号有一些超出界限的值
使用窗格而不是组。您也使用绝对定位,并且它不会在其边界周围移动。
使用javafx.scene.layout.Pane而不是javafx.scene.Group.谢谢,但这两种解决方案都是不可接受的。我总是会在30000中添加一个圆,所以也会遇到同样的问题。我需要能够将组作为一个整体移动,所以我不能将圆添加到窗格中。非常透彻地解释了为什么。现在…如何让它看起来不这样做。M首先,如何在添加新节点时使现有节点看起来不移动。应该有一种方法来计算反向转换或使其工作。我不完全理解您的要求,但是,我编辑了我的答案,以包含一个使用缩放的示例,并且节点保持在其位置。我正在构建一个平移缩小/缩放UI。单独变换每个节点是不可行的。@taotree,获得一些反馈会很棒。这能解决您的问题吗?这可能是一个稍微不同的问题,但切换到窗格有时可以解决这些问题。这是因为窗格不会从sam中的子级自动推断其大小e.作为一个群体的方式(如其他答案所述)。
final Scale scale = new Scale();
group.getTransforms().add(scale);
// change scale
scale.setX(2);