我有一个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();
}
答案 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);
}
}