1

I have VBox which contains three labels and one button I set action handler to remove all node from the container except the button

button.setOnAction(event ->
{    
    for (Node node : root.getChildren())
        if (node != button)
            root.getChildren().remove(node);
});

but an Exception is thrown

Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException ...

the weirder thing is that when I do the remove without the loop the labels are removed every thing is fine

root.getChildren().remove(label1);
root.getChildren().remove(label2);
root.getChildren().remove(label3); 

Full Example

public class Main extends Application {

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

    @Override
    public void start(Stage stage) {

        VBox root = new VBox();
        Button button = new Button("Remove All Except Me");
        root.getChildren().add(button);
        Label label1 = new Label("test 1");
        Label label2 = new Label("test 2");
        Label label3 = new Label("test 3");
        root.getChildren().add(label1);
        root.getChildren().add(label2);
        root.getChildren().add(label3);

        System.out.println(Thread.currentThread().getName());
        button.setOnAction(event ->
        {
            System.out.println(Thread.currentThread().getName());
            //this will not work
            for (Node node : root.getChildren())
                if (node != button)
                    root.getChildren().remove(node);

            //this will work
            //root.getChildren().remove(label1);
            //root.getChildren().remove(label2);
            //root.getChildren().remove(label3);

        });


        //this will work
        //root.getChildren().remove(label1);
        //root.getChildren().remove(label2);
        //root.getChildren().remove(label3);


        //this will throws java.lang.reflect.InvocationTargetException caused by java.util.ConcurrentModificationException
        //for (Node node : root.getChildren())
        //    if (node != button)
        //       root.getChildren().remove(node);

        stage.setScene(new Scene(root));
        stage.show();
    }

}
Ali Faris
  • 17,754
  • 10
  • 45
  • 70
  • 2
    if you remove from the reading collection the `for` will not know how to handle that (https://stackoverflow.com/questions/1196586/calling-remove-in-foreach-loop-in-java). So you should use an interator for that. – Edwin Jan 31 '18 at 11:28
  • 2
    use iterator.remove() or java 8 removeIf – user1516873 Jan 31 '18 at 11:33

0 Answers0