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

Invalid listview position when adding items to the beginning

XMLWordPrintable

    • x86
    • generic

      FULL PRODUCT VERSION :
      java version "1.8.0_131"
      Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      macOS Sierra
      10.12.5 (16F73)

      A DESCRIPTION OF THE PROBLEM :
      If you add items to the top of the listview, the list "jumps" to the wrong position.
      If you add items to the end of the list, then everything works correctly

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Fill the listview and after add a few items to the top of the list

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After adding new items, the listview position should remain the same as before adding new items
      ACTUAL -
      Position "jumps" up

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Run this code and press button ""Add elements to start"

      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.ListView;
      import javafx.scene.layout.VBox;
      import javafx.stage.Stage;

      import java.util.ArrayList;
      import java.util.List;


      public class Main extends Application {

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

          @Override
          public void start(Stage primaryStage) {
              List<String> listOfStrings = new ArrayList<>();
              for (int i = 0; i < 200; i++) {
                  listOfStrings.add(String.valueOf(i));
              }

              ObservableList<String> observableList = FXCollections.observableArrayList(listOfStrings);
              ListView<String> listView = new ListView<>(observableList);

              Button button = new Button("Add elements to start");
              button.setOnMouseClicked(event -> {
                  for (int i = 0; i > -200; i--) {
                      observableList.add(0, String.valueOf(i));
                  }
              });

              VBox vBox = new VBox(listView, button);

              Scene scene = new Scene(vBox, 500, 500);

              Stage stage = new Stage();
              stage.setScene(scene);
              stage.show();
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Now when I add new elements, I call the scrollTo method to the old position. But it does not work very well

      I think that the problem is somewhere in this code:
      com.sun.javafx.scene.control.skin.VirtualFlow line 1154:

              int currentIndex = computeCurrentIndex();
              if (lastCellCount != cellCount) {
                  // The cell count has changed. We want to keep the viewport
                  // stable if possible. If position was 0 or 1, we want to keep
                  // the position in the same place. If the new cell count is >=
                  // the currentIndex, then we will adjust the position to be 1.
                  // Otherwise, our goal is to leave the index of the cell at the
                  // top consistent, with the same translation etc.
                  if (position == 0 || position == 1) {
                      // Update the item count
      // setItemCount(cellCount);
                  } else if (currentIndex >= cellCount) {
                      setPosition(1.0f);
      // setItemCount(cellCount);
                  } else if (firstCell != null) {
                      double firstCellOffset = getCellPosition(firstCell);
                      int firstCellIndex = getCellIndex(firstCell);
      // setItemCount(cellCount);
                      adjustPositionToIndex(firstCellIndex);
                      double viewportTopToCellTop = -computeOffsetForCell(firstCellIndex);
                      adjustByPixelAmount(viewportTopToCellTop - firstCellOffset);
                  }

                  // Update the current index
                  currentIndex = computeCurrentIndex();
              }

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: