2013-12-13 19 views
8

JavaFXアプリケーションで長い操作を実行すると、カーソルをCursor.WAITに変更したいと考えています。私は、Platform.runLaterが私を助けると思った:JavaFXアプリケーションで長い操作のカーソルを変更する

this.getStage().getScene().setCursor(Cursor.WAIT); 

Platform.runLater(new Runnable() { 
    @Override 
    public void run() { 
     // Do some stuff 
     getStage().getScene().setCursor(Cursor.DEFAULT); 
    } 
}); 

しかし、カーソルは変更されません。なぜこれは機能しませんか?

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

// Do some stuff 

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

それとも、あなたはJavaFXアプリケーションのスレッド上に既にある場合は、あなたが使用できます。あなたはJavaFXのアプリケーションスレッドのオフ次のコードを実行している、待機カーソルを表示するためのパターンがあることしたと仮定すると

+1

fxスレッドでsetCursorを呼び出す必要があります... – assylias

答えて

16

Service

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.concurrent.*; 
import javafx.event.*; 
import javafx.geometry.*; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class ServiceWithCursorControl extends Application { 
    private final Button runButton = new Button("Run"); 
    private final Label label = new Label(); 

    private final Service service = new Service() { 
     @Override 
     protected Task createTask() { 
      return new Task<Void>() { 
       @Override protected Void call() throws Exception { 
        // do stuff 
        Thread.sleep(5000); 
        return null; 
       } 
      }; 
     } 
    }; 

    @Override public void start(Stage stage) { 
     VBox layout = createLayout(); 

     Scene scene = new Scene(layout, 100, 80); 
     stage.setScene(scene); 

     bindUIandService(stage); 

     stage.show(); 
    } 

    private void bindUIandService(Stage stage) { 
     label.textProperty() 
       .bind(
         service.stateProperty().asString() 
       ); 

     stage.getScene() 
       .getRoot() 
       .cursorProperty() 
       .bind(
         Bindings 
          .when(service.runningProperty()) 
           .then(Cursor.WAIT) 
           .otherwise(Cursor.DEFAULT) 
       ); 

     runButton 
       .disableProperty() 
       .bind(
         service.runningProperty() 
       ); 

     runButton.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       service.restart(); 
      } 
     }); 
    } 

    private VBox createLayout() { 
     VBox layout = new VBox(10); 

     layout.getChildren().setAll(runButton, label); 
     layout.setPadding(new Insets(10)); 
     layout.setAlignment(Pos.CENTER); 

     return layout; 
    } 

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

それはアプローチが最良のあなたの問題に合ったあなたの説明からは不明だが、うまくいけば、あなたはそれをうまくすることができます。

+0

申し訳ありませんが、私はメインスレッド上にあったことは明らかでした。サービスは間違いなく道のりです。偉大な答えをありがとう、それは私のための全く新しい考え方を開いた。 –

+0

@jewelseaこれは、私が必要とするもののためにはうまくいくかもしれないようですが、私は例外を得ています。私は、潜在的に多数のカスタムコントロール(最大50)を初期化し、それらをグリッドペインに移入する必要があります。おそらくあなたは私にそれを手伝うことができましたか?このペーストビンを見てください:http://pastebin.com/Mh2XZA9x – Will

+0

@ウィルこの質問とは別の問題のように見えます、新しい質問としてお尋ねください。 – jewelsea

関連する問題