2016-02-22 66 views
-2

我製作了一個創建圖像的Java應用程序。我想將位於for循環內的代碼放在另一個for循環中,每當代碼完成並返回第一個for循環時更新stage/screen,但似乎使用setScene方法和如果我將它們放在第一個for循環內,show方法似乎沒有幫助。Java,for循環中的更新階段

對於下面的示例,我希望圓形圖自己發生,而不是單擊。我正在思考每100ms使用thread.sleep方法。

package javaFX; 

import java.awt.Dimension; 
import java.awt.Toolkit; 

import javafx.application.Application; 

import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.control.Button; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class circles extends Application { 

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
    double WIDTH = screenSize.getWidth() - 80; 
    double HEIGHT = screenSize.getHeight() - 80; 

    @Override 
    public void start(Stage primaryStage) { 
     Group root = new Group(); 
     Scene scene = new Scene(root, WIDTH, HEIGHT, Color.WHITE); 
     Canvas canvas = new Canvas(WIDTH, HEIGHT); 
     root.getChildren().add(canvas); 
     GraphicsContext graphics = canvas.getGraphicsContext2D(); 
     primaryStage.setTitle("Circles!"); 

     canvas.setOnMouseClicked(clickEvent -> { 
      for (int i = 0; i < 50; i++) { 
       double ran = Math.random() * WIDTH; 
       double nu = Math.random()*1000; 
       int ranNum = (int) nu; 
       graphics.strokeOval(ran, ran, ran, ran); 
      } 
     });  
     primaryStage.setScene(scene); 
     primaryStage.setResizable(false); 
     primaryStage.show(); 
    } 
} 
+0

請將您的代碼添加到問題中,以便人們可以理解此問題並可以爲您提供幫助。 – mindreader

+0

這是代碼。 – Subtopic

回答

0

問題解決了!使用AnimationTimer,如下所示:

import java.awt.Dimension; 
import java.awt.Toolkit; 

import javafx.animation.AnimationTimer; 
import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class Testing extends Application { 

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
    double WIDTH = screenSize.getWidth() - 80; 
    double HEIGHT = screenSize.getHeight() - 80; 

    @Override public void start(Stage primaryStage) { 
     Group root = new Group(); 
     Scene scene = new Scene(root, WIDTH, HEIGHT, Color.WHITE); 
     Canvas canvas = new Canvas(WIDTH, HEIGHT); 
     root.getChildren().add(canvas); 
     GraphicsContext graphics = canvas.getGraphicsContext2D(); 
     primaryStage.setTitle("Circles!"); 

     // canvas.setOnMouseClicked(clickEvent -> { 
     // for (int i = 0; i < 50; i++) { 
     // double ran = Math.random() * WIDTH; 
     // graphics.strokeOval(ran, ran, ran, ran); 
     // } 
     // }); 

     primaryStage.setScene(scene); 
     primaryStage.setResizable(false); 
     primaryStage.show(); 

     new AnimationTimer() { 
      @Override public void handle(long currentNanoTime) { 
       for (int i = 0; i < 50; i++) { 
        double ran = Math.random() * WIDTH; 
        graphics.strokeOval(ran, ran, ran, ran); 
       } 

       try { 
        Thread.sleep(100); 
       } catch (InterruptedException e) { 
        // Do nothing 
       } 
      } 
     }.start(); 
    } 
} 

JavaFX不會爲您更新它。使用類似while循環的問題是,JavaFX不知道你已經完成了指令(或者至少,這是我從Docs獲得的印象)並開始繪製過程。也似乎沒有手動強制重繪的東西。所以,你必須使用一個AnimationTimer。

+1

你真棒! – Subtopic

+1

你真的不應該在'AnimationTimer'內調用'Thread.sleep'(因爲這會暫時凍結JavaFX應用程序線程和你的整個應用程序,包括輸入處理和其他動畫)。相反,如果您想定期執行操作,請查看[時間軸](https://docs.oracle.com/javase/8/javafx/api/javafx/animation/Timeline.html)。 – jewelsea

+0

@jewelsea,同意。但是沒有什麼值得擔心的。凍結應用程序線程對用戶沒有影響,因爲線程沒有查找任何內容。 – ifly6