How to change order of children in JavaFX

2019-02-16 11:14发布

问题:

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)

回答1:

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;
    }
}


回答2:

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

childNode.toFront();
childNode.toBack();


标签: java javafx-2