1

タイトルにあるように、ユーザーはターゲットにファイルをドロップします。これにより、即時ではない操作がトリガーされます。たとえば、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 を「滑らかにする」ためだけにスレッドを導入するのが便利ではなくなります。

4

1 に答える 1

2

これが起こる理由: 問題は DnD の設計にあります。プラットフォームによって異なりますが、一般に、OS は、JavaFX まで伝播し、イベント ハンドラーで終了するメソッドを呼び出します。このメソッドは、DnD 操作の結果を返して、OS が何をすべきかを認識できるようにする必要があります。したがって、設計上は同期です。

何をすべきか: 別のスレッドを使用するという提案は、おそらくこの問題を処理する唯一の方法です。それは非常に単純なはずです: イベント ハンドラーで長い操作に必要なすべての情報を取得し、新しいスレッドを開始し、そこで長い操作を行い、次を使用して UI を更新します。Platform.runLater

于 2013-09-12T19:48:01.220 に答える