JavaFX:拖放动作导致冻结放置图标后弹出警报

时间:2018-11-19 19:45:42

标签: java javafx popup alert frozen

使用JavaFX 8,我遇到一个特定的拖放问题:

放下后,弹出确认对话框会使图标停留在屏幕上,甚至像这样覆盖“警报”对话框本身:

Image

在用户关闭弹出窗口之前,文本“复制”和图标一直停留。

这是重现该问题的最少代码。要进行测试,请运行此程序并将任何文件(例如,来自桌面的文件)拖到应用程序窗口中:

public class Main extends Application {

private Parent root = new VBox();

private void onDragOver(DragEvent dragEvent) {
    if (dragEvent.getDragboard().hasFiles()) {
        dragEvent.acceptTransferModes(TransferMode.COPY);
    }
}

private void isUserSure() {
    Alert alert = new Alert(Alert.AlertType.WARNING,"",ButtonType.OK);
    alert.showAndWait();
}

@Override
public void start(Stage primaryStage) {
    root.setOnDragOver((event) -> onDragOver(event));
    root.setOnDragDropped((event) -> isUserSure());
    primaryStage.setTitle("ghost demo");
    primaryStage.setScene(new Scene(root, 300, 275));
    primaryStage.show();
}

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

2 个答案:

答案 0 :(得分:0)

我自己通过以下操作解决了该问题:

知道模态对话框(警告弹出窗口等)实质上是通过调用showAndwait()来“阻塞”其他每个阶段,因此问题必须是这也阻塞了dragEvent的onDragDropped方法(通过setOnDragDropped中的lambda设置)。

确保将对弹出式方法的调用以及实际发生的操作所发生的事情包装在Platform.runLater()

这将使dragEvent首先完成。观察我在方法start的以下行中所做的更改:

root.setOnDragDropped((event) -> Platform.runLater(() -> isUserSure()));

确保没有包装过多的东西,否则Dragboard中的物品将超出范围。从Dragboard中提取所需项目必须在放置时进行,而不是在runLater()

内部进行

答案 1 :(得分:-1)

要使其运行,必须从辅助线程启动runLater:

root.setOnDragDropped((event) -> {
 Thread t = new Thread(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
                Platform.runLater(() ->Platform.runLater(() -> isUserSure(););
            });
            t.run();
);