I have a JavaFx TableView
. I'd like to allow the user to click and drag to reorder the table rows. I can't seem to find any way to do this, but it seems like a pretty common thing in GUIs.
Here is some code to re-order rows in a ListView by dragging the rows.
Drag the birds to re-order them.
Implementation for a TableView would be somewhat similar.
import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.*;
public class ListOrganizer extends Application {
private static final String PREFIX =
"http://icons.iconarchive.com/icons/jozef89/origami-birds/72/bird";
private static final String SUFFIX =
"-icon.png";
private static final ObservableList<String> birds = FXCollections.observableArrayList(
"-black",
"-blue",
"-red",
"-red-2",
"-yellow",
"s-green",
"s-green-2"
);
private static final ObservableList<Image> birdImages = FXCollections.observableArrayList();
@Override
public void start(Stage stage) throws Exception {
birds.forEach(bird -> birdImages.add(new Image(PREFIX + bird + SUFFIX)));
ListView<String> birdList = new ListView<>(birds);
birdList.setCellFactory(param -> new BirdCell());
birdList.setPrefWidth(180);
VBox layout = new VBox(birdList);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) {
launch(ListOrganizer.class);
}
private class BirdCell extends ListCell<String> {
private final ImageView imageView = new ImageView();
public BirdCell() {
ListCell thisCell = this;
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setAlignment(Pos.CENTER);
setOnDragDetected(event -> {
if (getItem() == null) {
return;
}
ObservableList<String> items = getListView().getItems();
Dragboard dragboard = startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(getItem());
dragboard.setDragView(
birdImages.get(
items.indexOf(
getItem()
)
)
);
dragboard.setContent(content);
event.consume();
});
setOnDragOver(event -> {
if (event.getGestureSource() != thisCell &&
event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
setOnDragEntered(event -> {
if (event.getGestureSource() != thisCell &&
event.getDragboard().hasString()) {
setOpacity(0.3);
}
});
setOnDragExited(event -> {
if (event.getGestureSource() != thisCell &&
event.getDragboard().hasString()) {
setOpacity(1);
}
});
setOnDragDropped(event -> {
if (getItem() == null) {
return;
}
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
ObservableList<String> items = getListView().getItems();
int draggedIdx = items.indexOf(db.getString());
int thisIdx = items.indexOf(getItem());
Image temp = birdImages.get(draggedIdx);
birdImages.set(draggedIdx, birdImages.get(thisIdx));
birdImages.set(thisIdx, temp);
items.set(draggedIdx, getItem());
items.set(thisIdx, db.getString());
List<String> itemscopy = new ArrayList<>(getListView().getItems());
getListView().getItems().setAll(itemscopy);
success = true;
}
event.setDropCompleted(success);
event.consume();
});
setOnDragDone(DragEvent::consume);
}
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setGraphic(null);
} else {
imageView.setImage(
birdImages.get(
getListView().getItems().indexOf(item)
)
);
setGraphic(imageView);
}
}
}
// Iconset Homepage: http://jozef89.deviantart.com/art/Origami-Birds-400642253
// License: CC Attribution-Noncommercial-No Derivate 3.0
// Commercial usage: Not allowed
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With