2017-11-23 3 views
3

매 초마다 전달되는 카운터가 작아 지지만 코드를 실행하면 때때로 TextField에 corret 값이 나타나고 다른 시간은 복제됩니다. NetBeans Console에는 이상한 오류가 있습니다.JavaFX 8 - 새 스레드가있는 카운터를 만드는 데 보조 효과가 있음

아무도 도와 줄 수 있습니까? 방금 ​​코드에서 몇 가지 변경 사항을 만들었지 만 운이 없다. 나는 "Thread.sleep를"하지 않고 코드를 만들어 대신 내가 "PauseTransition"를 사용하지만 한 가지 문제가있다

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

는, 카운터도 메시지 이후에 -1 중지 : 여기

코드입니다 "Terminou o tempo!" 콘솔에 나타났습니다. 내가 가진 "동안 (템포> 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();를 사용하지 블록 자바 FX 애플리케이션 스레드를 수행 값에 도달하면 사용이 따라서, 멈추지 않는 이유 그래서 난 이해가 안 돼요 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(); 

---- ---------------- 또는 --------------------

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

대신 Thread.Sleep 대신 PauseTransition을 시도했지만 여전히 문제가 있습니다. 카운터는 -1에 도달했을 때 멈추고 0에 도달하지 않을 때 멈 춥니 다. 그리고 이것이 왜 발생하는지 이해하지 못합니다. –

0

당신은 차단 방지 할 수 있습니다 만 자바 FX 애플리케이션 스레드에서 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