Tableview将一首歌连续拖放到侧栏javafx上的播放列表按钮中

时间:2015-01-20 17:29:30

标签: drag-and-drop javafx tableview

我有一个javafx TableView,其中填充了一个名为Song的类。我的边框窗格中有一个侧边栏,其中填充了表示名为Playlist的类的按钮。我的(当前基本的)UI看起来像这样: My 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>

1 个答案:

答案 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