2013-12-13 5 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); 
    } 
}); 

커서는 변경되지 않습니다. 왜이 기능이 작동하지 않습니까? 당신은 자바 FX 애플리케이션 스레드에 이미있는 경우, 당신은 사용할 수,

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); 
    } 
}); 

을 또는 :

+1

fx 스레드에서 setCursor를 호출해야합니다 ... – assylias

답변

16

당신은 자바 FX 애플리케이션 스레드의 해제 다음 코드를 실행하는 가정, 대기 커서를 표시하는 패턴이 될 수있다 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 개)을 초기화하고 표 패널에 채워야합니다. 아마 그걸 도와 줄 수 있니? 이 pastebin을 참조하십시오 : http://pastebin.com/Mh2XZA9x – Will

+0

@Will이 질문과 다른 이슈가 나타나는 것 같습니다. 새로운 질문으로 문의하십시오. – jewelsea

관련 문제