JavaFX:拖放操作导致冻结放置图标后弹出警报
JavaFX: Alert popup after drag-and-drop action casues frozen drop icon
使用 JavaFX 8 我遇到了一个特定的拖放问题:
拖放后的确认弹出窗口会在释放拖动时将图标卡在屏幕上,甚至会覆盖警告对话框本身,如下所示:
(来源:image.ibb.co)
文本“复制”和图标会一直卡住,直到用户关闭弹出窗口。
这是重现问题的最少代码。要测试,运行 这个程序并将任何文件(例如从桌面)拖到应用程序 window:
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);
}
}
我通过执行以下操作自行解决了该问题:
知道模式对话框(警告弹出窗口等)基本上 "block" 每隔一个阶段通过调用 showAndwait()
问题一定是这也阻止了 dragEvent
完成onDragDropped 方法(通过 setOnDragDropped
中的 lambda 设置)。
确保将对弹出方法的调用包装起来,并将发生在 Platform.runLater()
中的实际掉落物品的内容
这会让 dragEvent
的东西先完成。观察我在以下方法行中所做的更改 start
:
root.setOnDragDropped((event) -> Platform.runLater(() -> isUserSure()));
请确保不要包装多余的东西,否则 Dragboard
中的项目将超出范围。从 Dragboard
中提取所需的物品必须在掉落时发生,而不是在 runLater()
内
要使其正常工作,runLater 必须从辅助线程启动:
root.setOnDragDropped((event) -> {
Thread t = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
Platform.runLater(() ->Platform.runLater(() -> isUserSure(););
});
t.run();
);
使用 JavaFX 8 我遇到了一个特定的拖放问题:
拖放后的确认弹出窗口会在释放拖动时将图标卡在屏幕上,甚至会覆盖警告对话框本身,如下所示:
(来源:image.ibb.co)
文本“复制”和图标会一直卡住,直到用户关闭弹出窗口。
这是重现问题的最少代码。要测试,运行 这个程序并将任何文件(例如从桌面)拖到应用程序 window:
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);
}
}
我通过执行以下操作自行解决了该问题:
知道模式对话框(警告弹出窗口等)基本上 "block" 每隔一个阶段通过调用 showAndwait()
问题一定是这也阻止了 dragEvent
完成onDragDropped 方法(通过 setOnDragDropped
中的 lambda 设置)。
确保将对弹出方法的调用包装起来,并将发生在 Platform.runLater()
这会让 dragEvent
的东西先完成。观察我在以下方法行中所做的更改 start
:
root.setOnDragDropped((event) -> Platform.runLater(() -> isUserSure()));
请确保不要包装多余的东西,否则 Dragboard
中的项目将超出范围。从 Dragboard
中提取所需的物品必须在掉落时发生,而不是在 runLater()
要使其正常工作,runLater 必须从辅助线程启动:
root.setOnDragDropped((event) -> {
Thread t = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
Platform.runLater(() ->Platform.runLater(() -> isUserSure(););
});
t.run();
);