Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8233179

VetoableListDecorator#sort throws IllegalArgumentException "duplicate children"

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • jfx25
    • jfx13
    • javafx
    • b07
    • x86_64
    • windows_10

      ADDITIONAL SYSTEM INFORMATION :
      openjdk 13.0.1 2019-10-15
      OpenJDK Runtime Environment (build 13.0.1+9)
      OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)

      javafx.version=13.0.1
      javafx.runtime.version=13.0.1+1
      javafx.runtime.build=1


      A DESCRIPTION OF THE PROBLEM :
      The VetoableListDecorator class does not override the default implementation of List#sort(Comparator). The default implementation copies the elements into an array, sorts the array, and then calls List#set in a loop to sort the List **without removing the old elements first**. This leads to the VetoableListDecorator intercepting the call to #set and seeing a "duplicate child" being added.

      Since sorting a list does not add or remove elements the VetoableListDecorator throwing the IllegalArgumentException does not make sense. Sorting the children of a Parent should be supported.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Add some children to a Parent.
      2. Sort the children by an attribute (e.g. the text of a Label).

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The children list is sorted without any problems.
      ACTUAL -
      An exception is thrown -> Caused by: java.lang.IllegalArgumentException: Children: duplicate children added: parent = ...

      ---------- BEGIN SOURCE ----------
      import javafx.application.Application;
      import javafx.scene.control.Label;
      import javafx.scene.layout.HBox;
      import javafx.stage.Stage;

      import java.util.Comparator;

      public class App extends Application {

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

        @Override
        public void start(Stage primaryStage) {
          Label label1 = new Label("1");
          Label label2 = new Label("2");

          HBox box = new HBox(5, label2, label1);

          box.getChildren()
              .sort(Comparator.comparing(node -> ((Label) node).getText()));
        }

      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            mstrauss Michael Strauß
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: