2014-12-03 39 views
0

我目前正在做一些GUI動畫。我最終編寫了自己的標籤顏色變化。爲此,我採取了以下任務:JavaFX System.currentTimeMillis()+任務

Task tk= new Task() { 
      @Override protected Void call() throws Exception 
      { 
       colorAnimation=true; 
       boolean red = true; 
       long timer = System.currentTimeMillis(); 
       long waitTime= 1000; 
       nome.setStyle("-fx-background-color: red;"); 
       main: while(colorAnimation) 
       { 
        while(System.currentTimeMillis() < waitTime+ timer) 
        { 
         System.out.println(System.currentTimeMillis()-timer); 
         if(!colorAnimation) 
          break main; 
        } 
        timer=System.currentTimeMillis(); 

        red=!red; 
        if(red) 
        { 
         nome.setStyle("-fx-background-color: red;"); 
         waitTime=1000; 
        } 
        else 
        { 
         nome.setStyle("-fx-background-color: black;"); 
         waitTime=500; 
        } 
       } 
       nome.setStyle("-fx-background-color: black;"); 
       return null; 
      } 
     }; 
     Thread t = new Thread(tk); 
     t.setDaemon(true); 
     t.start(); 

以上函數應該初始化標籤顏色爲紅色,等待1秒,將其更改爲黑色,等待半秒並再次將其變爲紅色,重複這個過程,直到關閉colorAnimation(聲明爲volatile)。問題在於函數在第二秒內被打碎,並且在控制檯上等待時間(System.currentTimeMillis() - timer)被打印到982.如果我將初始等待時間更改爲500,那麼打印的等待時間我被困在469.我真的不知道發生了什麼。

謝謝!

回答

1

首先,你的代碼對我有用,所以我無法解釋你爲什麼看到你所看到的效果。

雖然你不應該使用這個。它違反了JavaFX的規則之一:你不應該從JavaFX應用程序線程之外訪問場景圖的狀態。 (例如,請參見Threading in the Application Javadocs上的部分。)可能是因爲在嘗試執行setStyle(...)調用時引發異常,導致線程終止;這可能解釋你所看到的行爲。 (但是,這似乎並沒有發生在我的系統上。)

此外,您的代碼非常複雜,難以維護。有爲這種功能設計的更高級別的API,例如Timeline。您應該使用這些API來簡化代碼並避免線程錯誤。

例如:

import javafx.animation.Animation; 
import javafx.animation.KeyFrame; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class ColorAnimationTest extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     Label nome = new Label("Hello"); 

     // This chunk of code replaces your entire thread/task code 
     Timeline animation = new Timeline(
       new KeyFrame(Duration.millis(1000), 
         event -> nome.setStyle("-fx-background-color: red;")), 
       new KeyFrame(Duration.millis(1500), 
         event -> nome.setStyle("-fx-background-color: black"))); 

     animation.setCycleCount(Animation.INDEFINITE); 
     animation.play(); 

     // Button to stop/start the animation: 
     Button button = new Button(); 
     button.setOnAction(event -> { 
      if (animation.getStatus() == Animation.Status.RUNNING) { 
       animation.stop(); 
      } else { 
       animation.play(); 
      } 
     }); 

     // change text of button approprite to animation state: 
     button.textProperty().bind(Bindings 
       .when(animation.statusProperty().isEqualTo(Animation.Status.RUNNING)) 
       .then("Stop") 
       .otherwise("Start")); 

     VBox root = new VBox(10, nome, button); 
     root.setAlignment(Pos.CENTER); 
     Scene scene = new Scene(root, 350, 100); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

感謝您的答覆,並用於特技。我看到了代碼,我在想這是否可行。我的問題在於你爲紅色和黑色設定的持續時間。據我所知,該代碼將使顏色每秒變爲紅色,並將每1.5秒將其更改爲黑色。第二個三號會出現問題嗎?根據我的理解,這兩個事件都會嘗試同時改變顏色。我對麼? – 2014-12-03 11:32:48

+0

爲什麼你不運行它?然後閱讀各種方法調用的java文檔,看看它做了什麼。 – 2014-12-03 11:48:44

+0

對不起,我目前不在臺式電腦上,所以現在我不能嘗試,但我肯定會盡我所能。 – 2014-12-03 11:55:54