2017-11-23 1 views
3

1秒ごとに値が減少するカウンタを作成したいのですが、コードを実行するとTextFieldにcorret値が現れることがあります。 NetBeans Consoleにはいくつかの奇妙なエラーがあります。JavaFX 8 - 新しいスレッドでカウンタを作成すると副次的な影響があります

誰もがこれを手伝ってくれますか? 私はちょうどコードのいくつかの変更を加えたが、私はそれに運がない。ここで

コードです:

package javafx_contador; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.scene.control.TextField; 
import javafx.scene.text.Font; 
import javafx.scene.text.FontWeight; 
import javafx.stage.Stage; 
import javafx.stage.WindowEvent; 
import javafx.geometry.Pos; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class JavaFX_Contador extends Application 
{ 
    TextField tf; 
    Thread1 contador; 

    @Override 
    public void start(Stage stage) 
    { 
    tf = new TextField(); 
    tf.setEditable(false); 
    tf.setMaxWidth(100); 
    tf.setAlignment(Pos.CENTER); 
    tf.setLayoutX(160); 
    tf.setLayoutY(140); 
    tf.setFont(Font.font("Cambria", FontWeight.BOLD, 20)); 

    Pane pane = new Pane(); 
    pane.setStyle("-fx-background: green;"); 
    pane.getChildren().add(tf); 

    Scene scene = new Scene(pane, 400, 300); 

    stage.setResizable(false); 
    stage.setTitle("JavaFX (Contador)"); 
    stage.setScene(scene); 
    stage.show(); 

    pane.requestFocus(); 

    stage.setOnCloseRequest((WindowEvent we) -> 
    { 
     System.out.println("A Aplicação vai encerrar."); 
     Platform.exit(); 
     System.exit(0); 
    }); 

    contador = new Thread1(); 
    contador.start(); 
    } 


    public class Thread1 extends Thread 
    { 
    int tempo = 60; 

    @Override 
    public void run() 
    { 
     tf.setText(Integer.toString(tempo)); 
     while (tempo > 0) 
     { 
     try 
     { 
      Thread1.sleep(1000); 
     } 
     catch (InterruptedException ex) 
     { 
      Logger.getLogger(JavaFX_Contador.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     tempo--; 
     tf.setText(Integer.toString(tempo)); 
     } 
     System.out.println("Terminou o tempo!"); 
    } 
    } 


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

私は「のThread.sleep」せずにコードをしたが、代わりに、私は「PauseTransition」を使用しますが、一つの問題があると、カウンタがで停止-1でもメッセージの後に"終わりのテンポ!"コンソールに表示されます。私が持っている 「しばらく(テンポ> 0)」0

package javafx_contador; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.scene.control.TextField; 
import javafx.scene.text.Font; 
import javafx.scene.text.FontWeight; 
import javafx.stage.Stage; 
import javafx.stage.WindowEvent; 
import javafx.geometry.Pos; 
import javafx.animation.PauseTransition; 
import javafx.util.Duration; 

public class JavaFX_Contador extends Application 
{ 
    int tempo = 60; 
    TextField tf; 
    Thread1 contador; 

    @Override 
    public void start(Stage stage) 
    { 
    tf = new TextField(Integer.toString(tempo)); 
    tf.setEditable(false); 
    tf.setMaxWidth(100); 
    tf.setAlignment(Pos.CENTER); 
    tf.setLayoutX(160); 
    tf.setLayoutY(140); 
    tf.setFont(Font.font("Cambria", FontWeight.BOLD, 20)); 

    Pane pane = new Pane(); 
    pane.setStyle("-fx-background: green;"); 
    pane.getChildren().add(tf); 

    Scene scene = new Scene(pane, 400, 300); 

    stage.setResizable(false); 
    stage.setTitle("JavaFX (Contador)"); 
    stage.setScene(scene); 
    stage.show(); 

    pane.requestFocus(); 

    stage.setOnCloseRequest((WindowEvent we) -> 
    { 
     System.out.println("A Aplicação vai encerrar."); 
     Platform.exit(); 
     System.exit(0); 
    }); 

    contador = new Thread1(); 
    contador.start(); 
    } 


    public class Thread1 extends Thread 
    { 
    @Override 
    public void run() 
    { 
     PauseTransition pausa = new PauseTransition(Duration.millis(1000)); 

     pausa.setOnFinished(e -> 
     { 
     tempo--; 
     tf.setText(Integer.toString(tempo)); 
     }); 

     while (tempo > 0) 
     pausa.play(); 

     System.out.println("Terminou o tempo!"); 
    } 
    } 


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

ようPlatform.runLaterを用いてメインUIスレッド。これは次のように役立ちます:['Platform.runLater'](https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable-)と[' Task'](https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)を参照してください。 – fabian

答えて

1

Thread.Sleep();を使用していないブロックのJavaFXアプリケーションのスレッドを実行した値に達したときに使用し、それはそのため、停止しない理由を私は理解していませんあなたの目標

例達成するjavafx.concurrent.Taskまたはjavafx.animation.PauseTransition

Task task = new Task() { 
     @Override 
     public Void call() { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    }; 

    task.setOnSucceeded((e) -> { 
     // 
     // YOUR UI CHANGES GOES HERE 
     // 
    }); 
    new Thread(task).start(); 

を---- ---------------- OR --------------------

PauseTransition pause = new PauseTransition(Duration.millis(1000)); 
    pause.setOnFinished(e -> { 
     // 
     // YOUR UI CHANGES GOES HERE 
     // 
    }); 
    pause.play(); 
+0

Thread.Sleepの代わりにPauseTransitionを試しましたが、まだ問題があります。カウンタは-1に達したときに停止し、0になったときは停止しません。なぜこのようなことが起こるのか分かりません。 –

0

あなたはブロックを回避することができますのみJavaFXアプリケーション・スレッドからGUIを更新し、この

Platform.runLater(new Runnable() { 
      @Override 
public void run() { 
tf.setText(Integer.toString(tempo)); 
this.sleep(1000); 
} 
+0

私はPlatform.runLaterをコードに実装しようとしましたが、実行することができませんでした!あなたは私にそれをする方法を教えてくれますか? –

+1

これはどのようにしてFXアプリケーションスレッドをブロックしないようにしますか? FXアプリケーションスレッドで 'Thread.sleep(...) 'を明示的に*呼んでいます。 –

+0

Platform.runLaterは、アンドロイドのループャーのようなものです。これは、イベントキューに入れるメソッドから呼び出すことができ、呼び出し時に実行されます。詳細は[こちら](https://docs.oracle.com/javase/8/javafx)です。 /api/javafx/application/Platform.html#runLater-java.lang.Runnable-) – captainchhala

関連する問題