我有一个javafx TableView,其中填充了一个名为Song的类。我的边框窗格中有一个侧边栏,其中填充了表示名为Playlist的类的按钮。我的(当前基本的)UI看起来像这样:
我想这样做,如果我拖动一首歌并将其放入左侧的一个按钮,它会将该歌曲添加到播放列表中。此外,我在互联网上寻找答案,并没有找到任何有用的东西。话虽如此,请不要把我联系到某事。我已经尝试从以下链接实现代码:http://docs.oracle.com/javase/8/javafx/events-tutorial/drag-drop.htm#CHDJFJDH 如果您有任何建议请帮助我!谢谢!
更新: 这是我的代码,我的命名约定很容易理解:
musicTable.setOnMouseClicked(new EventHandler<MouseEvent>() { //click
@Override
public void handle(MouseEvent event) {
if (event.getClickCount() == 2) { // double click
Song selected = (Song)musicTable.getSelectionModel().getSelectedItem();
dragged = selected;
if (selected != null) {
System.out.println("select : " + selected);
}
}
}
});
musicTable.setOnDragDetected(new EventHandler<MouseEvent>() { //drag
@Override
public void handle(MouseEvent event) {
// drag was detected, start drag-and-drop gesture
Song selected = (Song)musicTable.getSelectionModel().getSelectedItem();
dragged = selected;
if (selected != null) {
Dragboard db = musicTable.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(selected.pointer.toString());
db.setContent(content);
event.consume();
}
}
});
musicTable.setOnDragOver(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
// data is dragged over the target
Dragboard db = event.getDragboard();
if (event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
}
});
musicTable.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
Dragboard db = event.getDragboard();
boolean success = false;
if (event.getDragboard().hasString()) {
String text = db.getString();
//tableContent.add(text);
//musicTable.setItems(tableContent);
success = true;
}
event.setDropCompleted(success);
event.consume();
}
});
playlistTable.setRowFactory(cb -> {
TableRow<Playlist> row = new TableRow<>();
row.setOnMouseClicked(ev -> {
musicTable.setItems(row.getItem().playlist);
row.setOnDragDropped( new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
boolean success = false;
row.getItem().add(dragged);
System.out.println("ACCEPED TRANSFER");
success = true;
event.setDropCompleted(success);
event.consume();
}
});
});
return row;
});
拖动是一首跟踪哪首歌被拖动的歌曲,如果你还有其他方式,请告诉我,musicTable是我拖动的,播放列表是我拖动的地方。 / p>
答案 0 :(得分:1)
好的,这是我可以创建的最小的例子:
@Override
public void start(Stage primaryStage) throws IOException {
ObservableList<String> tableData = FXCollections
.observableList(IntStream.range(0, 1000)
.mapToObj(Integer::toString)
.collect(Collectors.toList()));
TableView<String> stringTable = new TableView<>(tableData);
TableColumn<String, String> column1 = new TableColumn<>();
column1.setCellValueFactory(cb -> new ReadOnlyStringWrapper(cb
.getValue()));
stringTable.getColumns().add(column1);
stringTable.setRowFactory(cb -> {
TableRow<String> row = new TableRow<>();
row.setOnDragDetected(ev -> {
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString(row.getItem());
db.setContent(content);
ev.consume();
});
return row;
});
VBox leftSide = new VBox();
leftSide.setPrefWidth(300);
leftSide.setOnDragOver(ev -> {
if (ev.getGestureSource() != leftSide && ev.getDragboard().hasString()) {
ev.acceptTransferModes(TransferMode.COPY);
}
ev.consume();
});
leftSide.setOnDragDropped(ev -> {
Dragboard db = ev.getDragboard();
boolean success = false;
if (db.hasString()) {
Label label = new Label(db.getString());
leftSide.getChildren().add(label);
success = true;
}
ev.setDropCompleted(success);
ev.consume();
});
BorderPane root = new BorderPane(stringTable);
root.setLeft(leftSide);
Scene scene = new Scene(root, 700, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
这是一个BorderPane,其中心是TableView
,左侧是VBox
。
现在我添加了您请求的拖放处理程序,以便您可以将行(因此在row factory中完成)拖到左侧,在那里将它们作为新Label
添加到{ {1}}作为新生儿。
修改:第二个示例,VBox
作为放置目标:
ListView