【问题标题】:JavaFX drag & drop with custom node beside mouse iconJavaFX拖放鼠标图标旁边的自定义节点
【发布时间】:2017-01-18 23:40:00
【问题描述】:

在拖放过程中,在鼠标图标旁边显示节点的半透明“副本”的最佳方式是什么?

基本上,我有带有彩色背景和文本标签的 HBox,我希望它们在被拖动时“粘”在鼠标光标上。

如果用户可以直观地验证他们正在拖动的内容,而不是仅仅看到鼠标光标变为各种拖动图标,那就太好了。当您拖动某些组件(如 RadioButton)时,Scene Builder 往往会执行此操作。

【问题讨论】:

  • 您是否正在执行“平台支持的拖放”(即您在某个节点上调用startDragAndDrop)?如果是这样,您只需调用Dragboard.setDragView(...) 来设置拖动的图像光标。
  • 只是内部的,应用程序窗口之外什么都没有。
  • 我问的不是这个。
  • 我不清楚您所说的“平台支持”是什么意思。我认为这意味着拖入/拖出操作系统平台桌面或文件夹,我没有这样做。在 HBox 节点之一上调用 startDragAndDrop,如下面的答案所示。
  • three different dragging modes in JavaFX: "simple press-drag-release" (默认), "full press-drag-release" (调用startFullDrag) 和 "platform supported drag- and-drop”(通过调用 startDragAndDrop 开始)。下面概述的解决方案仅适用于第三个选项;但是从您的问题中无法知道您正在做什么。

标签: java javafx javafx-8


【解决方案1】:

“节点的半透明“复制””是通过在节点上调用snapshot(null, null) 来完成的,它返回一个WritableImage。然后将这个WritableImage 设置为DragBoard 的拖动视图。这是一个关于如何做到这一点的小例子:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DataFormat;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class DragAndDrop extends Application {
    private static final DataFormat DRAGGABLE_HBOX_TYPE = new DataFormat("draggable-hbox");

    @Override
    public void start(Stage stage) {
        VBox content = new VBox(5);

        for (int i = 0; i < 10; i++) {
            Label label = new Label("Test drag");

            DraggableHBox box = new DraggableHBox();
            box.getChildren().add(label);

            content.getChildren().add(box);
        }

        stage.setScene(new Scene(content));
        stage.show();
    }

    class DraggableHBox extends HBox {
        public DraggableHBox() {
            this.setOnDragDetected(e -> {
                Dragboard db = this.startDragAndDrop(TransferMode.MOVE);

                // This is where the magic happens, you take a snapshot of the HBox.
                db.setDragView(this.snapshot(null, null));

                // The DragView wont be displayed unless we set the content of the dragboard as well. 
                // Here you probably want to do more meaningful stuff than adding an empty String to the content.
                ClipboardContent content = new ClipboardContent();
                content.put(DRAGGABLE_HBOX_TYPE, "");
                db.setContent(content);

                e.consume();
            });
        }
    }

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

【讨论】:

  • 嘿,不知道你可以将 (null, null) 传递给快照,因为我的 RTFM 不够远……嗯,这仍然有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2013-04-20
  • 2014-05-28
相关资源
最近更新 更多