javafx:当完成拖放操作触发 "long"任务时,d&d图标持续存在于目标上

标签 java drag-and-drop javafx

如标题所示,用户将文件拖放到目标上。这应该会触发一个不太立即的操作,比如需要 4 秒。

问题是系统用来表示拖动项目的图标一直保留在窗口上,直到操作完成,并且void handle(DragEvent d)事件返回。

The icon that freezes

这被用户视为应用程序“卡住”。我们知道应用程序需要 4 秒来处理放置的项目,但是如果图标在用户将项目释放到目标上并且之后立即消失,那么用户可能根本不会注意到这一点。 em>在 4 秒操作开始之前。

以下是与删除相关的代码:

s.setOnDragDropped(new EventHandler<DragEvent>() {
        @Override  public void handle(DragEvent t) {

            //1. The drop is OK
            t.setDropCompleted(true);

            //<--I THINK THAT SOMETHING SHOULD BE PUT HERE TO FORCE D&D TO REMOVE THE ICON

            //2. let's start an elaboration that involves the files
            //   that have been dropped!
            try { Thread.sleep(4000); } catch (InterruptedException ignore_exception_in_test) {}

        }
    });

有什么办法可以解决这个问题吗?

完整的代码,如果你只是想重现这个案例;只需修复导入并将文件从资源管理器拖放到舞台中即可。

public class ShortSelfCompilableExample01 extends Application {

Stage stage;

@Override public void start(Stage stage) throws Exception {

    stage.setTitle("Drag&Drop test");

    this.stage = stage;

    Scene s = new Scene(new BorderPane());

    stage.setScene(s);

    s.setOnDragDropped(new EventHandler<DragEvent>() {
        @Override  public void handle(DragEvent t) {

            //1. Ok, the drop is OK
            t.setDropCompleted(true);
            //2. let's start an elaboration that involves the files
            //   that have been dropped!
            try {
                Thread.sleep(6000);
            } catch (InterruptedException ignore_exception_in_test_environments) {}

        }
    });

    s.setOnDragOver(new EventHandler<DragEvent> () {
        @Override public void handle(DragEvent t) {
            t.acceptTransferModes(TransferMode.ANY);
        }
    });

    stage.show();

}
}

PS。为什么我没有使用线程
响应式 UI 的“一流”解决方案是使用线程。 但这不是一个执行时间很长的后台任务。在最坏的情况下,这应该持续 5 秒,而线程会带来一定程度的复杂性。 操作的长度越短,引入线程来“平滑”UI 就越不方便。

最佳答案

为什么会发生这种情况:问题出在 DnD 的设计上。这取决于平台,但一般来说,操作系统会调用一些方法,该方法会传播到 JavaFX 并最终到达您的事件处理程序中。该方法应该返回 DnD 操作的结果,以便操作系统知道要做什么。所以它在设计上是同步的。

该怎么办:您使用另一个线程的建议可能是处理此问题的唯一方法。它应该非常简单:在事件处理程序中获取长操作所需的所有信息,启动一个新线程,在那里进行长操作并使用 Platform.runLater

更新 UI

关于javafx:当完成拖放操作触发 "long"任务时,d&d图标持续存在于目标上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18747976/

相关文章:

java - Serializable接口(interface)的DTO实现

javascript - addEventListener 'drop' 在 Safari 上不起作用

Javafx:更新TableCell

Java 用户界面框架?

javafx - 需要从高度图创建三角形网格的帮助(JavaFX)

java - 从自定义适配器中的 listView 中删除对象

java - 如何避免 Firefox 中的窗口下载​​弹出窗口使用 Java selenium?我需要自动下载而不询问弹出窗口吗?

Java类组织

javascript - 将对象拖出 IFrame

c++ - 在 MFC 应用程序中接受 CFSTR_FILECONTENTS/CFSTR_FILEDESCRIPTOR int DoDrop