0
表包含以下行(只是舉例一列):拖放項目到TableView中,已有行之間
A
B
C
我試圖找出如何拖動一個項目到它,並有它放置在現有的行B和C之間。
我能夠拖放並導致在表格末尾添加項目,但我無法弄清楚如何將它放在行之間,基於在我釋放鼠標按鈕的位置。
表包含以下行(只是舉例一列):拖放項目到TableView中,已有行之間
A
B
C
我試圖找出如何拖動一個項目到它,並有它放置在現有的行B和C之間。
我能夠拖放並導致在表格末尾添加項目,但我無法弄清楚如何將它放在行之間,基於在我釋放鼠標按鈕的位置。
創建一個接受的姿態,通過鼠標的位置決定,是否要行之前或之後添加的項目rowFactory
生產TableRow
S:
@Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
Button button = new Button("A");
// d&d source providing next char
button.setOnDragDetected(evt -> {
Dragboard db = button.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(button.getText());
db.setContent(content);
});
button.setOnDragDone(evt -> {
if (evt.isAccepted()) {
// next char
button.setText(Character.toString((char) (button.getText().charAt(0) + 1)));
}
});
// accept for empty table too
table.setOnDragOver(evt -> {
if (evt.getDragboard().hasString()) {
evt.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
evt.consume();
});
table.setOnDragDropped(evt -> {
Dragboard db = evt.getDragboard();
if (db.hasString()) {
table.getItems().add(new Item(db.getString()));
evt.setDropCompleted(true);
}
evt.consume();
});
TableColumn<Item, String> col = new TableColumn<>("value");
col.setCellValueFactory(new PropertyValueFactory<>("value"));
table.getColumns().add(col);
// let rows accept drop too
table.setRowFactory(tv -> {
TableRow<Item> row = new TableRow();
row.setOnDragOver(evt -> {
if (evt.getDragboard().hasString()) {
evt.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
evt.consume();
});
row.setOnDragDropped(evt -> {
Dragboard db = evt.getDragboard();
if (db.hasString()) {
Item item = new Item(db.getString());
if (row.isEmpty()) {
// row is empty (at the end -> append item)
table.getItems().add(item);
} else {
// decide based on drop position whether to add the element before or after
int offset = evt.getY() > row.getHeight()/2 ? 1 : 0;
table.getItems().add(row.getIndex() + offset, item);
evt.setDropCompleted(true);
}
}
evt.consume();
});
return row;
});
Scene scene = new Scene(new VBox(button, table));
primaryStage.setScene(scene);
primaryStage.show();
}
public class Item {
public Item() {
}
public Item(String value) {
this.value.set(value);
}
private final StringProperty value = new SimpleStringProperty();
public String getValue() {
return value.get();
}
public void setValue(String val) {
value.set(val);
}
public StringProperty valueProperty() {
return value;
}
}