How to change order of children in JavaFX

2019-02-16 10:49发布

Is it possible to change order of Nodes in JavaFX2 children list? I tried set() and Collections.swap() however both throw IllegalArgumentException in Parent as in some point the children list contains the same item at two positions (when node is at new position and has not been removed from the old position). There are flags inside Parent which JavaFX uses internaly in toFront() and toBack() which prevents the exception, however there is no way to access them from outside.

java.lang.IllegalArgumentException: Children: duplicate children added: parent = HBox@1424bf0
    at javafx.scene.Parent$1.onProposedChange(Parent.java:307)
    at com.sun.javafx.collections.VetoableObservableList.set(VetoableObservableList.java:156)
    at com.sun.javafx.collections.ObservableListWrapper.set(ObservableListWrapper.java:281)
    at java.util.Collections.swap(Collections.java:532)

标签: java javafx-2
2条回答
Luminary・发光体
2楼-- · 2019-02-16 11:51

You can move the child in the parent's children list by

childNode.toFront();
childNode.toBack();
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-16 11:53
ObservableList<Node> workingCollection = FXCollections.observableArrayList(pane.getChildren());
Collections.swap(workingCollection, 0, 1);
pane.getChildren().setAll(workingCollection);

Refer to this code:

package swapnode;

import java.util.Collection;
import java.util.Collections;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @author reegan
 */
public class SwapNode extends Application {

    @Override
    public void start(Stage primaryStage) {
        VBox root = new VBox(20);
        /* Thid Part Swap Children of Node */
        Pane pane = view();
        ObservableList<Node> workingCollection = FXCollections.observableArrayList(pane.getChildren());
        Collections.swap(workingCollection, 0, 1);
        pane.getChildren().setAll(workingCollection);

        root.getChildren().addAll(view(),pane);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public Pane view() {
        HBox pane = new HBox(10);
        Button button = new Button("Hello");
        TextField field = new TextField("World");
        pane.getChildren().addAll(button,field);
        return pane;
    }
}
查看更多
登录 后发表回答