タイトルにあるように、ユーザーはターゲットにファイルをドロップします。これにより、即時ではない操作がトリガーされます。たとえば、4 秒かかります。問題は、ドラッグされたアイテムを表すためにシステムによって使用されるアイコンが、操作が完了してイベントが戻る
までウィンドウにとどまることです。void handle(DragEvent d)
これは、アプリケーションの「フリーズ」としてユーザーに認識されます。アプリケーションがドロップされたアイテムを処理するのに 4 秒かかることはわかっていますが、ユーザーがアイテムをターゲットでリリースした直後で、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 を「滑らかにする」ためだけにスレッドを導入するのが便利ではなくなります。