HBox 错误地显示节点,即使 getChildren() 以正确的顺序显示它们

HBox displaying Nodes incorrectly, even though getChildren() displays them in the correct order

好的,就这样吧,我折腾了一整天都没有找到解决方案:

我在屏幕上显示了一个 HBox,它包含多个 StackPanel 元素,每个元素包含一个 Circle 和一个 Label 元素,因此两者都显示在它们自己的顶部。 StackPanels 是 HBox 的节点,是基于数组而不是通过 xfml 文件添加的。 HBox 在 VBox 中,其中包含 3 个与此处无关的其他元素。

我的 objective 是使用动画切换其中两个节点,这是我使用具有弧形路径的 PathTransition 创建的。我同时有两个这样的动画运行,一个是节点到达目的地,一个是到达当前位置。

动画完成后,我使用switchNode()函数来切换两个节点,因为我想改变它们的顺序,因为我想继续执行动画,而动画本身并没有改变它们的顺序,只有位置。例如,HBox.getChildren().etc(将其转换为文本)如果我切换第 0 和第三个索引。

貌似交换成功了,问题是交换的位置没有显示出来

public class AnimationController2 {
private int[] arr = new int[] { 0, 1, 2, 3, 4, 5 };

@FXML
private VBox vbox;
@FXML
private HBox content;

@FXML
private HBox indexes;

@FXML
private void switchToInput() throws IOException {
    App.setRoot("input");
}

@FXML
private void repeat() {
    animate(0, 3); //should work for any index and be repeatable
}

public void initialize() {
    addElements();
}

public void animate(int from, int to) {
    PathTransition move1 = new PathTransition();
    PathTransition move2 = new PathTransition();
    Node node1 = content.getChildren().get(from);
    Node node2 = content.getChildren().get(to);
    move1.setNode(node1);
    move2.setNode(node2);
    move1.setDuration(Duration.seconds(3));
    move2.setDuration(Duration.seconds(3));
    move1.setPath(makePath(node1, node2, true));
    move2.setPath(makePath(node2, node1, false));
    move2.setOnFinished(b -> {
        switchNode(from, to);
    });
    move1.play();
    move2.play();
}

public void switchNode(int a, int b) {
    ObservableList<Node> workingCollection = FXCollections.observableArrayList(content.getChildren());
    /*
     * Debugging
     * System.out.println(" ");
     * System.out.println("Original: ");
     * for (Node i : workingCollection) {
     * Label aa = (Label) ((StackPane) i).getChildren().get(1);
     * System.out.print(aa.getText() + " ");
     * }
     */

    Collections.swap(workingCollection, a, b);

    /*
     * Debugging
     * System.out.println(" ");
     * System.out.println("Switched: ");
     * for (Node i : workingCollection) {
     * Label aa = (Label) ((StackPane) i).getChildren().get(1);
     * System.out.print(aa.getText() + " ");
     * }
     */
    content.getChildren().setAll(workingCollection);
}

public Path makePath(Node from, Node to, boolean right) {
    // creating variables
    double distance = to.getLayoutX() - from.getLayoutX();
    double x = from.boundsInLocalProperty().get().getCenterX();
    double y = from.boundsInLocalProperty().get().getCenterY();
    double fromX = x;
    double fromY = y;
    double toX = x + distance; // 300
    double toY = y;
    ArcTo arcTo = new ArcTo();
    arcTo.setLargeArcFlag(false);
    arcTo.setSweepFlag(true);
    arcTo.setRadiusX((toX + fromX) / 2);
    arcTo.setRadiusY(right ? 200 : distance / 3); // optimal values
    arcTo.setX(toX);
    arcTo.setY(toY);
    Path path = new Path();
    path.getElements().addAll(new MoveTo(fromX, fromY), arcTo);
    return path;
}
public void addElements() {
    for (int i = 0; i < arr.length; i++) {
        Circle circle = new Circle(30, 30, 30);
        circle.setFill(Color.BLUE);
        Label label = new Label(arr[i] + "");
        label.setTextFill(Color.BLACK);
        StackPane join = new StackPane();
        join.getChildren().addAll(circle, label);
        content.getChildren().add(join);
        Label index = new Label(i + "");
        indexes.getChildren().add(index);
        indexes.setSpacing(62);
    }
}

}

public class App extends Application {
private static Scene scene;

@Override
public void start(Stage stage) throws IOException {
    scene = new Scene(loadFXML("animation"), 640, 480);
    stage.setScene(scene);
    stage.setTitle("Array2Tree");
    stage.show();
}

static void setRoot(String fxml) throws IOException {
    scene.setRoot(loadFXML(fxml));
}

private static Parent loadFXML(String fxml) throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
    return fxmlLoader.load();
}

public static void main(String[] args) {
    launch(args);
}

}

FXML

<VBox fx:id = "vbox" alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.example.AnimationController2">
<children>
    <HBox alignment="CENTER" spacing="10.0" fx:id = "content" ></HBox>
    <HBox alignment="CENTER" spacing="10.0" fx:id = "indexes" ></HBox>
    <Label text="Animation View" />
    <Button fx:id="InputButton" onAction="#switchToInput" text="Switch to Input" />
    <Button fx:id = "Repeat" onAction="#repeat" text="Repeat" />
</children>
<padding>
    <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>

感谢@jewelsea 的评论。

添加

解决了我的问题
workingCollection.get(a).setTranslateX(0);
workingCollection.get(b).setTranslateX(0);

之前

Collections.swap(workingCollection, a, b);