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

ListView displaying element multiple times when clearing and readding to Itemlist

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • 8
    • 8
    • javafx
    • Windows 7 64 bit, JDK 8 b124 x64, JavaFX that is packaged with that version

      When I create a ListView with a custom ListCell that displays a Graphic and no text and then add a single item, clear the list and add multiple other items, the removed items are not really removed and still displayed in the ListView.

      Sample Code:

      package application;

      import java.util.Arrays;

      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.ListCell;
      import javafx.scene.control.ListView;
      import javafx.scene.layout.VBox;
      import javafx.scene.paint.Color;
      import javafx.scene.shape.Rectangle;
      import javafx.scene.text.Text;
      import javafx.stage.Stage;

      public class ListViewAddingObjectsAgain extends Application
      {
      private class Cell extends ListCell<String>
      {
      @Override
      protected void updateItem(final String string, final boolean empty)
      {
      super.updateItem(string, empty);

      if (!empty)
      {
      final Text text = new Text(string);

      final Rectangle rectSmall = new Rectangle(20,20);
      rectSmall.setFill(Color.GREEN);

      final Rectangle rectLarge = new Rectangle(50,50);
      rectLarge.setFill(Color.BLUE);

      setText(null);

      // use one of the above, results in different versions of the error
      setGraphic(rectLarge);
      }
      }
      }

      @Override
      public void start(final Stage primaryStage)
      {
      final ObservableList<String> list = FXCollections.observableArrayList();
      final ListView<String> view = new ListView<>(list);
      view.setCellFactory(v -> new Cell());

      final Button aButton = new Button("A");
      aButton.setOnAction(event -> { list.clear(); list.addAll(Arrays.asList(new String[] { "A" })); });

      final Button bButton = new Button("B");
      bButton.setOnAction(event -> { list.clear(); list.addAll(Arrays.asList(new String[] { "B", "C" })); });

      final Button clearButton = new Button("clear");
      clearButton.setOnAction((event) -> list.clear());

      final VBox box = new VBox();
      box.getChildren().add(view);
      box.getChildren().add(aButton);
      box.getChildren().add(bButton);
      box.getChildren().add(clearButton);

      primaryStage.setScene(new Scene(box));
      primaryStage.show();
      }

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

      }


      Steps to reproduce:
      1) start application
      2) click "A" Button
      3) click "B" Button

      optional
      4) click "A" Button
      5) click "B" Button
      6) repeat 4 + 6, and add press on "clear" from time to time


      It is also possible to use the rectSmall or the text Node instead of the rectLarge, in that case there will always be two listcells being displayed:

      0) setGraphic(text or rectSmall)
      1) start application
      2) click "A" Button
      3) click "B" Button
      4) click "A" Button

            jgiles Jonathan Giles
            cmuthingjfx Clemens Muthing (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: