import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.collections.ListChangeListener;
import javafx.scene.control.TableView;
import javafx.scene.control.SelectionMode;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {
    
    @Override
    public void start(Stage stage) {
     TableView<String> view = new TableView<>();
    TableView.TableViewSelectionModel<String> selectionModel = view.getSelectionModel();

    selectionModel.setSelectionMode( SelectionMode.MULTIPLE );

    String s0 = "s0";
    String s1 = "s1";
    String s2 = "s2";
    String s3 = "s3";
    view.getItems().add( s0 );
    view.getItems().add( s1 );
    view.getItems().add( s2 );
    view.getItems().add( s3 );


    selectionModel.getSelectedItems().addListener( ( ListChangeListener<String> ) aChange -> {
      while(aChange.next()) {
        System.out.println(aChange);
        for ( String removedString : aChange.getRemoved() ) {
          // Assertion fails: s1 is in the removed list but is still (correctly) in the items list.
          assert( aChange.getList().contains( removedString ) == false );
        }
      }
    } );

    selectionModel.select( s0 );
    selectionModel.select( s1 );
    selectionModel.select( s2 );
    selectionModel.select( s3 );

    // Select only s1.
    selectionModel.clearAndSelect( view.getItems().indexOf( s2 ) ); 

    }

    public static void main(String[] args) {
        launch();
    }
    
}