Tableview将一首歌曲连续拖放到侧栏javafx上的播放列表按钮
Tableview drag and drop a song in a row to a playlist button on the side bar javafx
我有一个 javafx TableView,其中填充了一个名为 Song 的 class。我的边框窗格中有一个边栏,其中填充了代表 class 称为播放列表的按钮。我的(目前是基本的)UI 看起来像这样:
我想做的是,如果我将一首歌曲拖放到左侧的其中一个按钮中,它就会将该歌曲添加到播放列表中。此外,我在互联网上查看并搜索了答案,但没有找到任何有用的信息。话虽如此,请不要 link 我做某事。我已经尝试实施以下 link 中的代码: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;
});
dragged 是一首跟踪哪首歌被拖动的歌曲,如果您有任何其他方法请告诉我,musicTable 是我从中拖动的,播放列表 table 是我的位置'拖到.
好的,这是我能创建的最小示例:
@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
添加到VBox
为新 children.
编辑:第二个示例,其中 ListView
作为放置目标:
@Override
public void start(Stage primaryStage) {
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;
});
ObservableList<String> leftSideItems = FXCollections
.observableList(IntStream.range(0, 1000)
.mapToObj(Integer::toString)
.collect(Collectors.toList()));
ListView<String> leftSideDropTarget = new ListView<String>(
leftSideItems);
leftSideDropTarget.setPrefWidth(200);
leftSideDropTarget.setCellFactory(cb -> {
ListCell<String> cell = new TextFieldListCell<>();
cell.setOnDragOver(ev -> {
if (ev.getGestureSource() != cell
&& ev.getDragboard().hasString()) {
ev.acceptTransferModes(TransferMode.COPY);
}
ev.consume();
});
cell.setOnDragDropped(ev -> {
Dragboard db = ev.getDragboard();
boolean success = false;
if (db.hasString()) {
cell.setText("Got Item: " + db.getString());
success = true;
}
ev.setDropCompleted(success);
ev.consume();
});
return cell;
});
BorderPane root = new BorderPane(stringTable);
root.setLeft(leftSideDropTarget);
Scene scene = new Scene(root, 700, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
我有一个 javafx TableView,其中填充了一个名为 Song 的 class。我的边框窗格中有一个边栏,其中填充了代表 class 称为播放列表的按钮。我的(目前是基本的)UI 看起来像这样:
我想做的是,如果我将一首歌曲拖放到左侧的其中一个按钮中,它就会将该歌曲添加到播放列表中。此外,我在互联网上查看并搜索了答案,但没有找到任何有用的信息。话虽如此,请不要 link 我做某事。我已经尝试实施以下 link 中的代码: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;
});
dragged 是一首跟踪哪首歌被拖动的歌曲,如果您有任何其他方法请告诉我,musicTable 是我从中拖动的,播放列表 table 是我的位置'拖到.
好的,这是我能创建的最小示例:
@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
添加到VBox
为新 children.
编辑:第二个示例,其中 ListView
作为放置目标:
@Override
public void start(Stage primaryStage) {
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;
});
ObservableList<String> leftSideItems = FXCollections
.observableList(IntStream.range(0, 1000)
.mapToObj(Integer::toString)
.collect(Collectors.toList()));
ListView<String> leftSideDropTarget = new ListView<String>(
leftSideItems);
leftSideDropTarget.setPrefWidth(200);
leftSideDropTarget.setCellFactory(cb -> {
ListCell<String> cell = new TextFieldListCell<>();
cell.setOnDragOver(ev -> {
if (ev.getGestureSource() != cell
&& ev.getDragboard().hasString()) {
ev.acceptTransferModes(TransferMode.COPY);
}
ev.consume();
});
cell.setOnDragDropped(ev -> {
Dragboard db = ev.getDragboard();
boolean success = false;
if (db.hasString()) {
cell.setText("Got Item: " + db.getString());
success = true;
}
ev.setDropCompleted(success);
ev.consume();
});
return cell;
});
BorderPane root = new BorderPane(stringTable);
root.setLeft(leftSideDropTarget);
Scene scene = new Scene(root, 700, 400);
primaryStage.setScene(scene);
primaryStage.show();
}