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

No change event on selection when selected row is removed from TableView

    XMLWordPrintable

Details

    Description

      When the row that is currently selected in a TableView is removed, the selection is rendered on another
      row but the change listener on the selection model is not triggered. See code below:


      import javafx.application.Application;
      import javafx.beans.property.DoubleProperty;
      import javafx.beans.property.ReadOnlyStringWrapper;
      import javafx.beans.property.SimpleDoubleProperty;
      import javafx.beans.value.ChangeListener;
      import javafx.beans.value.ObservableValue;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.TableColumn;
      import javafx.scene.control.TableColumn.CellDataFeatures;
      import javafx.scene.control.TableView;
      import javafx.scene.control.TextArea;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.HBoxBuilder;
      import javafx.scene.layout.VBox;
      import javafx.scene.layout.VBoxBuilder;
      import javafx.stage.Stage;
      import javafx.util.Callback;

      /**
       * When the selected row is removed the selection is rendered on another
       * row but there is no notification
       */
      public class TableViewSelectionTest extends Application {

      static class Order {
      String name;
      DoubleProperty price = new SimpleDoubleProperty();
      DoubleProperty qty = new SimpleDoubleProperty();

      Order(String n, double p) {
      name = n;
      price.set(p);
      qty.set(1);
      }
      @Override
      public String toString() {
      return name + ": " + qty.get() + " @ " + price.get();
      }
      }

      private static int nextOrderId = 100;
      private static Order nextOrder() {
      return new Order("Order" + String.valueOf(nextOrderId++), nextOrderId / 10.0);
      }

      final Order items[] = { new Order("Item 0", 4.0), new Order("Item 1", 5.0),
      new Order("Item 2", 6.0), new Order("Item 3", 7.0),
      new Order("Item 4", 8.0), new Order("Item 5", 9.0),
      new Order("Item 6", 10.0), new Order("Item 7", 11.0) };

      @Override
      public void start(final Stage primaryStage) throws Exception {
      final TableView<Order> tv = new TableView<Order>();
      final TextArea ta = new TextArea();

      final Button updateButton = new Button("Replace Row");
      updateButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(final ActionEvent actionEvent) {
      tv.getItems().set(tv.getSelectionModel().getSelectedIndex(), nextOrder());
      }
      });

      final Button deleteButton = new Button("Remove Row");
      deleteButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(final ActionEvent actionEvent) {
      tv.getItems().remove(tv.getSelectionModel().getSelectedIndex());
      }
      });

      final TableColumn<Order, String> nameCol = new TableColumn<Order, String>(
      "Item");
      final TableColumn<Order, Number> priceCol = new TableColumn<Order, Number>(
      "Price");
      final TableColumn<Order, Number> qtyCol = new TableColumn<Order, Number>(
      "Quantity");

      nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Order, String>, ObservableValue<String>>() {
      @Override
      public ObservableValue<String> call(
      final CellDataFeatures<Order, String> d) {
      return new ReadOnlyStringWrapper(d.getValue().name);
      }
      });

      priceCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Order, Number>, ObservableValue<Number>>() {
      @Override
      public ObservableValue<Number> call(
      final CellDataFeatures<Order, Number> cellData) {
      return cellData.getValue().price;
      };
      });

      qtyCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Order, Number>, ObservableValue<Number>>() {
      @Override
      public ObservableValue<Number> call(
      final CellDataFeatures<Order, Number> cellData) {
      return cellData.getValue().qty;
      };
      });

      tv.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Order>() {

      @Override
      public void changed(ObservableValue<? extends Order> arg0,
      Order arg1, Order newOrder) {
      ta.setText(String.format("Selected Order %s", newOrder));
      }
      });



      tv.getColumns().addAll(nameCol, priceCol, qtyCol);
      tv.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
      tv.getItems().addAll(items);

      final HBox hb = HBoxBuilder.create().children(updateButton, deleteButton)
      .build();
      final VBox vb = VBoxBuilder.create().children(tv, ta, hb).build();
      primaryStage.setScene(new Scene(vb));
      primaryStage.setHeight(500.0);
      primaryStage.show();
      }

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

      Attachments

        Activity

          People

            jgiles Jonathan Giles
            aswanepoejfx Abraham Swanepoel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported: