JavaFX将按钮从一个窗格拖到另一个窗格

时间:2017-02-25 18:02:17

标签: button javafx drag-and-drop

我有一个javafx应用程序,它在一个flowpane中包含许多按钮。为了使按钮可拖动,我将每个按钮放在一个单独的窗格中。用户可以从任何一个窗格中选择任何按钮并拖动和放大。将其放在任何其他窗格上。例如,从窗格1获取按钮并将其拖放到窗格5内。

由于以前不知道用户将选择哪个按钮,我认为必须首先以某种方式将其添加到dragboard,因此可以在setOnDragDropped操作的dragboard中检索它。

我可以使用以下方法在imageviews之间拖放图像:

    Dragboard db = iv_1.startDragAndDrop(TransferMode.MOVE);
    ClipboardContent content = new ClipboardContent();
    content.putImage(iv_1.getImage());

但是我无法找到一种方法来向dragboard添加按钮,因为没有特定的选项可用,只有看似不适用的选项,content.putText或content.putString()......

任何帮助将不胜感激。这就是我到目前为止所做的:

private void btn_1_setOnDragDetected(MouseEvent event) {

    Dragboard db = btn_1.startDragAndDrop(TransferMode.MOVE);
    ClipboardContent content = new ClipboardContent();
    // below seems to be wrong
    content.put(dataFormat,btn_1.toString());
    db.setContent(content);

    event.consume();
}


private void btn_1_setOnDragOver(DragEvent event) {

    if (event.getGestureSource() != btn_1 &&
            event.getDragboard().hasString()) {
        event.acceptTransferModes(TransferMode.MOVE);
    }
    event.consume();
}


private void pane_5_setOnDragDropped(DragEvent event) {

    Dragboard db = event.getDragboard();
    boolean success = false;
    if (db.hasString()) {
       // below must be wrong
       pane_5.setId(db.getString());
       success = true;
    }
    event.setDropCompleted(success);
    event.consume();
    }

1 个答案:

答案 0 :(得分:2)

无法向剪贴板内容添加按钮(即拖动板)。您只能添加特定类型(字符串,图像)和实现可序列化的对象(按钮不会,并且它无论如何都不会执行您想要的操作)。在这方面,拖放API非常缺乏,imho。您应该只添加一些虚拟文本到dragboard,并保持对当前被拖动的按钮的引用。

快速SSCCE:

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class DragAndDropButton extends Application {

    private final DataFormat buttonFormat = new DataFormat("com.example.myapp.formats.button");

    private Button draggingButton ;

    @Override
    public void start(Stage primaryStage) {
        FlowPane pane1 = new FlowPane();
        FlowPane pane2 = new FlowPane();

        for (int i = 1 ; i <= 10; i++) {
            pane1.getChildren().add(createButton("Button "+i));
        }

        addDropHandling(pane1);
        addDropHandling(pane2);

        SplitPane splitPane = new SplitPane(pane1, pane2);
        splitPane.setOrientation(Orientation.VERTICAL);

        Scene scene = new Scene(splitPane, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Button createButton(String text) {
        Button button = new Button(text);
        button.setOnDragDetected(e -> {
            Dragboard db = button.startDragAndDrop(TransferMode.MOVE);
            db.setDragView(button.snapshot(null, null));
            ClipboardContent cc = new ClipboardContent();
            cc.put(buttonFormat, "button");
            db.setContent(cc);
            draggingButton = button ;
        });
        button.setOnDragDone(e -> draggingButton = null);
        return button ;
    }

    private void addDropHandling(Pane pane) {
        pane.setOnDragOver(e -> {
            Dragboard db = e.getDragboard();
            if (db.hasContent(buttonFormat) 
                    && draggingButton != null 
                    && draggingButton.getParent() != pane) {
                e.acceptTransferModes(TransferMode.MOVE);
            }
        });

        pane.setOnDragDropped(e -> {
            Dragboard db = e.getDragboard();
            if (db.hasContent(buttonFormat)) {
                ((Pane)draggingButton.getParent()).getChildren().remove(draggingButton);
                pane.getChildren().add(draggingButton);
                e.setDropCompleted(true);
            }           
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}