2015-08-13 40 views
0

我有兩個任務,一個用於更改屏幕不透明度,另一個用於執行復雜計算。我想計算開始後,纔在屏幕衰落實際上已經改變了,所以我寫了下面的:JavaFX中的併發 - 任務未完成

  Task<Void> task = new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       stage.getScene().getRoot().setOpacity(0.2); 
       stage.show(); 
       return null; 
      } 
     }; 

     Task<Void> task2 = new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       // Complex computation 
       return null; 
      } 
     }; 
     task.setOnSucceeded(new EventHandler<WorkerStateEvent>() { 
      @Override 
      public void handle(WorkerStateEvent paramT) { 
       // this busy waiting line was added in attempt to force the 
       // fading before beginning second task 
       while (stage.getScene().getRoot().getOpacity() != 0.2) {} 
       stage.show(); 
       Platform.runLater(task2); 
      } 
     }); 
     task2.setOnSucceeded(new EventHandler<WorkerStateEvent>() { 
      @Override 
      public void handle(WorkerStateEvent paramT) { 
       stage.getScene().getRoot().setOpacity(1); 
       stage.show(); 
      } 
     }); 
     task.run(); 

但是,有時我看到的計算開始和屏幕,它的完成後才消失。有時它確實起作用。所以我認爲這裏有一個線程問題。注意:當我處於調試模式並停止執行每個任務時,它每次都能正常工作。在第二項任務開始之前可以做些什麼來強制屏幕褪色?

編輯: 至於建議,我改變了代碼如下:

  Task<Void> task1 = new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       // Long computation 
       return null; 
      } 
     }; 

     Task<Void> task = new Task<Void>() { 
      @Override 
      protected Void call() throws Exception { 
       FadeTransition ft = new FadeTransition(Duration.millis(1), stage.getScene().getRoot()); 
       ft.setFromValue(1.0); 
       ft.setToValue(0.1); 
       ft.setCycleCount(1); 
       //ft.setAutoReverse(true); 
       ft.play(); 

       ft.setOnFinished(new EventHandler<ActionEvent>() { 
        @Override 
        public void handle(ActionEvent event) { 
         new Thread(task1).run(); 
        } 
       }); 

       return null; 
      } 
     }; 

     task1.setOnSucceeded(new EventHandler<WorkerStateEvent>() { 
      @Override 
      public void handle(WorkerStateEvent paramT) { 
       FadeTransition ft1 = new FadeTransition(new Duration(0.1), stage.getScene().getRoot()); 
       ft1.setFromValue(0.1); 
       ft1.setToValue(1.0); 
       ft1.setCycleCount(1); 
       //ft.setAutoReverse(true); 
       ft1.play(); 
       //stage.show(); 
      } 
     }); 
     new Thread(task).run(); 

我仍然看到相同的行爲。

+0

有這麼多錯在這裏很難知道從哪裏開始。你的任務都不會在後臺線程中執行(第一個,你只需調用'run(...)',它將在當前線程中執行它;在第二個中,你可以用它來執行它FX應用程序線程調用'Platform.runLater(...)')。你的第一個'Task'更新UI,如果你在後臺線程中運行,這將是非法的。 'setOpacity(...)'不會像您期望的那樣創建「淡入淡出」,但會立即改變不透明度。你的'onSucceeded'阻止執行,這會凍結UI。 –

+0

如果您想要「淡入淡出」,請使用['FadeTransition]](http://docs.oracle.com/javase/8/javafx/api/javafx/animation/FadeTransition.html)。啓動淡入轉場的'onFinished'處理程序中的第二項任務。這裏不需要屏蔽(因爲淡入淡出已經完成)。在後臺線程中啓動執行計算的任務,或將其傳遞給執行程序。請參閱['任務'Javadocs](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)。 –

回答

0

更換

new Thread(task).run(); 

new Thread(task).start(); 
+0

這不是錯誤的原因,但仍然是調用start而不是run的好方式。 Findbugs也發現這是一個錯誤。 – maxam