Sort table using drag and drop (row)

My goal is to sort the table using drag and drop. I followed this example: http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm

For drag and drop, I added fxml via Scene Builder

<TableView fx:id="tableView" onDragDetected="#dragDetected" onDragDropped="#dragDropped" onDragOver="#dragOver" 

and did the controllers

 @FXML private void dragDetected(MouseEvent event) { System.out.println("dragDetected"); Integer idx; idx = tableView.getSelectionModel().getFocusedIndex(); Dragboard db = tableView.startDragAndDrop(TransferMode.MOVE); ClipboardContent content = new ClipboardContent(); content.putString(idx.toString()); db.setContent(content); System.out.println(idx); // System.out.println(event.getPickResult()); event.consume(); } @FXML private void dragOver(DragEvent event) { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); event.consume(); } @FXML private void dragDropped(DragEvent event) { System.out.println("dragDropped"); System.out.println(event.getTarget()); System.out.println(event.getPickResult()); } 

but when dragging and dropping I cannot get the line of the place where I dropped the object All I get is cell information. Text[text="Smith", x=0.0, y=0.0, ...

How do I get this job? Maybe a Class TableRow<T> could help, but I don't understand how to use it proberly.

+5
source share
2 answers

As you suspected, the answer is to use TableRow . You do this by setting the factory row in your table, which is used to create table rows as needed. You can create them and install drag and drop handlers on them before returning them.

So, remove the onDragDetected , onDragDropped etc attributes from FXML, and set the drag and drop handlers in the line in the initialization method in the controller.

Here is a complete example using a regular example from Oracle tutorials. I did not use FXML in this example (I just created the table view directly in the Java class), but you can just move the whole table view configuration to the initialization method.

 import java.util.function.Function; import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableRow; import javafx.scene.control.TableView; import javafx.scene.input.ClipboardContent; import javafx.scene.input.DataFormat; import javafx.scene.input.Dragboard; import javafx.scene.input.TransferMode; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class TableViewDragRows extends Application { private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object"); @Override public void start(Stage primaryStage) { TableView<Person> tableView = new TableView<>(); tableView.getColumns().add(createCol("First Name", Person::firstNameProperty, 150)); tableView.getColumns().add(createCol("Last Name", Person::lastNameProperty, 150)); tableView.getColumns().add(createCol("Email", Person::emailProperty, 200)); tableView.getItems().addAll( new Person("Jacob", "Smith", " jacob.smith@example.com "), new Person("Isabella", "Johnson", " isabella.johnson@example.com "), new Person("Ethan", "Williams", " ethan.williams@example.com "), new Person("Emma", "Jones", " emma.jones@example.com "), new Person("Michael", "Brown", " michael.brown@example.com ") ); tableView.setRowFactory(tv -> { TableRow<Person> row = new TableRow<>(); row.setOnDragDetected(event -> { if (! row.isEmpty()) { Integer index = row.getIndex(); Dragboard db = row.startDragAndDrop(TransferMode.MOVE); db.setDragView(row.snapshot(null, null)); ClipboardContent cc = new ClipboardContent(); cc.put(SERIALIZED_MIME_TYPE, index); db.setContent(cc); event.consume(); } }); row.setOnDragOver(event -> { Dragboard db = event.getDragboard(); if (db.hasContent(SERIALIZED_MIME_TYPE)) { if (row.getIndex() != ((Integer)db.getContent(SERIALIZED_MIME_TYPE)).intValue()) { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); event.consume(); } } }); row.setOnDragDropped(event -> { Dragboard db = event.getDragboard(); if (db.hasContent(SERIALIZED_MIME_TYPE)) { int draggedIndex = (Integer) db.getContent(SERIALIZED_MIME_TYPE); Person draggedPerson = tableView.getItems().remove(draggedIndex); int dropIndex ; if (row.isEmpty()) { dropIndex = tableView.getItems().size() ; } else { dropIndex = row.getIndex(); } tableView.getItems().add(dropIndex, draggedPerson); event.setDropCompleted(true); tableView.getSelectionModel().select(dropIndex); event.consume(); } }); return row ; }); Scene scene = new Scene(new BorderPane(tableView), 600, 400); primaryStage.setScene(scene); primaryStage.show(); } private TableColumn<Person, String> createCol(String title, Function<Person, ObservableValue<String>> mapper, double size) { TableColumn<Person, String> col = new TableColumn<>(title); col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue())); col.setPrefWidth(size); return col ; } public class Person { private final StringProperty firstName = new SimpleStringProperty(this, "firstName"); private final StringProperty lastName = new SimpleStringProperty(this, "lastName"); private final StringProperty email = new SimpleStringProperty(this, "email"); public Person(String firstName, String lastName, String email) { this.firstName.set(firstName); this.lastName.set(lastName); this.email.set(email); } public final StringProperty firstNameProperty() { return this.firstName; } public final String getFirstName() { return this.firstNameProperty().get(); } public final void setFirstName(final String firstName) { this.firstNameProperty().set(firstName); } public final StringProperty lastNameProperty() { return this.lastName; } public final String getLastName() { return this.lastNameProperty().get(); } public final void setLastName(final String lastName) { this.lastNameProperty().set(lastName); } public final StringProperty emailProperty() { return this.email; } public final String getEmail() { return this.emailProperty().get(); } public final void setEmail(final String email) { this.emailProperty().set(email); } } public static void main(String[] args) { launch(args); } } 
+21
source

1 answer works (from James_D) in FMXL:

<TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">

 public class FXMLTableViewController implements Initializable { private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object"); @Override public void initialize(URL url, ResourceBundle resourceBundle) { tableView.setRowFactory(tv -> { ... return row ; }); } @FXML private TableView<Person> tableView; ... 
+1
source

Source: https://habr.com/ru/post/1213692/


All Articles