When I try to initiate a multiple selection drag gesture on a ListView it works as expected. I can use Shift or Ctrl to multiselect and then click and drag. The drag gesture starts with all my items still selected.
When I try the same thing with a TableView my multiple selection is lost as soon as I click to start my drag gesture. The only way I can make it work is to start the drag gesture at the same time as I Shift select my multiple items.
Run the following test code and try to initiate a drag with multiple rows selected:
************************************************************
import java.util.Iterator;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableBlankCells extends Application {
@Override public void start(Stage primaryStage) {
final TableView<String> table = new TableView<>();
final TableColumn<String, String> column1 = new TableColumn<>("Column 1");
column1.setCellValueFactory(new Callback<CellDataFeatures<String,String>,
ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<String, String> p){
return new ReadOnlyStringWrapper(p.getValue());
}
});
column1.setPrefWidth( 200 );
table.getColumns().add( column1 );
table.getItems().addAll("one", "two", "three", "four");
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
List<String> strings = table.getSelectionModel().getSelectedItems();
if ( !strings.isEmpty() ) {
Dragboard db = table.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
StringBuilder sb = new StringBuilder();
for ( Iterator<String> it = strings.iterator(); it.hasNext(); ){
sb.append( it.next() );
if ( it.hasNext() ) {
sb.append(", ");
}
}
content.put(DataFormat.PLAIN_TEXT, sb.toString());
db.setContent(content);
event.consume();
}
}
});
primaryStage.setScene( new Scene(new StackPane(table)) );
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
When I try the same thing with a TableView my multiple selection is lost as soon as I click to start my drag gesture. The only way I can make it work is to start the drag gesture at the same time as I Shift select my multiple items.
Run the following test code and try to initiate a drag with multiple rows selected:
************************************************************
import java.util.Iterator;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TableBlankCells extends Application {
@Override public void start(Stage primaryStage) {
final TableView<String> table = new TableView<>();
final TableColumn<String, String> column1 = new TableColumn<>("Column 1");
column1.setCellValueFactory(new Callback<CellDataFeatures<String,String>,
ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<String, String> p){
return new ReadOnlyStringWrapper(p.getValue());
}
});
column1.setPrefWidth( 200 );
table.getColumns().add( column1 );
table.getItems().addAll("one", "two", "three", "four");
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
List<String> strings = table.getSelectionModel().getSelectedItems();
if ( !strings.isEmpty() ) {
Dragboard db = table.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
StringBuilder sb = new StringBuilder();
for ( Iterator<String> it = strings.iterator(); it.hasNext(); ){
sb.append( it.next() );
if ( it.hasNext() ) {
sb.append(", ");
}
}
content.put(DataFormat.PLAIN_TEXT, sb.toString());
db.setContent(content);
event.consume();
}
}
});
primaryStage.setScene( new Scene(new StackPane(table)) );
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}