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

TabObservableList: change notification on reorder is incorrect

XMLWordPrintable

      The issue bubbled up at SO https://stackoverflow.com/q/70134511/203657

      To reproduce, run the example, drag the first tab to the end and note the output:

      expected:
      0 -> 2
      1 -> 0
      2 -> 1

      actual:
      0 -> 0
      1 -> 1
      2 -> 2

      The example:

      /**
       * https://stackoverflow.com/q/70134511/203657
       */
      public class TabPaneNotificationIssue extends Application {

          private Parent createContent() {
              TabPane tabPane = new TabPane(new Tab("Tab A"), new Tab("Tab B"), new Tab("Tab C"));
              tabPane.setTabDragPolicy(TabDragPolicy.REORDER);
              tabPane.getTabs().addListener((ListChangeListener<Tab>)change -> {
                  while (change.next()) {
                      if (change.wasPermutated()) {
                          for (int oldIndex = change.getFrom(); oldIndex < change.getTo(); oldIndex++) {
                              System.out.println(oldIndex + " -> " + change.getPermutation(oldIndex));
                          }
                      }
                  }
              });
              BorderPane content = new BorderPane(tabPane);
              return content;
          }

          @Override
          public void start(Stage stage) throws Exception {
              stage.setScene(new Scene(createContent()));
              stage.show();
          }

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

      }

      As a unit test:

          @Test
          public void testReorderNotificationIndexStandalone() {
              TabPane tabPane = new TabPane();
              tabPane.getTabs().addAll(new Tab("A"), new Tab("B"));
              List<Tab> copy = List.copyOf(tabPane.getTabs());
              TabObservableList<Tab> tabs = (TabObservableList<Tab>) tabPane.getTabs();
              List<Change> changes = new ArrayList<>();
              tabs.addListener((ListChangeListener) changes::add);
              tabs.reorder(copy.get(0), copy.get(1));
              assertEquals(1, changes.size());
              Change c = changes.get(0);
              assertTrue(c.next());
              assertTrue("change must be permutation", c.wasPermutated());
              assertEquals("from", 0, c.getFrom());
              assertEquals("to", 2, c.getTo());
              for (int oldIndex = c.getFrom(); oldIndex < c.getTo(); ++oldIndex) {
                  int newIndex = c.getPermutation(oldIndex);
                  Tab tab = copy.get(oldIndex);
                  assertEquals("permutation must return index of tab " + tab.getText() + " in permutated list",
                          c.getList().indexOf(tab), newIndex);
              }
          }

      BTW: not sure if it's okay to assign this to you Ambarish, but I think you have the most experience with TabPane :)

            arapte Ambarish Rapte
            fastegal Jeanette Winzenburg
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: