2

プログラムがビジーであることを示すカーソルを変更しようとしています。これはかなり単純なはずですが、正しく動作させることができず、数時間検索しても解決策が見つかりませんでした. これが私がやろうとしていることです。

public class ButtonTest extends Application {
  @Override
  public void start(Stage primaryStage) {
    final StackPane root = new StackPane();
    primaryStage.setScene(new Scene(root, 200, 150));

    Button button = new Button();
    button.setText("Button");
    root.getChildren().add(button);

    primaryStage.show();

    button.setOnAction(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent event) {
        // Set the cursor to the wait cursor.
        root.setCursor(Cursor.WAIT);
        // Do some work.
        try {
          Thread.sleep(5000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        // Set the cursor back to the default.
        root.setCursor(Cursor.DEFAULT);
      }

    });
}

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

setCursor(Cursor.DEFAULT) をコメントアウトすると、ボタンを押した後、5 秒間待機してから、カーソルが待機カーソルに変わります。そのため、スリープ後まで待機してから setCursor(Cursor.WAIT) を実行し、その直後に setCursor(Cursor.DEFAULT) を実行しているようです。私は何が欠けていますか?

4

2 に答える 2

3

カーソルの形状を変更するはずの同じスレッドであるメイン UI スレッドをスリープ状態にしています。メイン UI スレッドがハンドル メソッドを終了し、UI イベント ループに戻る間、バックグラウンド スレッドでスリープ (または高価な操作) を開始して、カーソルの変更がアクティブになるようにする必要があります。

于 2013-06-24T17:01:56.827 に答える
1

このために Platform.runLater を試したことがありますか:

次のように動作するはずです。

primaryStage.getScene().setCursor(Cursor.WAIT);
Platform.runLater(new Runnable() {
  @Override
  public void run() {
    doSomethingInteresting();
    primaryStage.getScene().setCursor(Cursor.DEFAULT);
  }
});

ここでの考え方は単純です。元のイベントでは、マウスの形だけが定義され、この直後にアクションを実行する新しいイベントがスケジュールされます。

于 2014-06-02T21:02:13.843 に答える