2014-11-02 2 views
0

Так что это метод, который я использую сейчас, чтобы сделать обратный отсчет.Таймер и вычисления имеют несколько экземпляров, запущенных

/** 
    * Starts the count-down 
    * Triggers the handleFinish method 
    * Sets the user under time pressure, which actually is a good way to provocate the user to start over again, to beat the score already achieved 
    */ 
    public void startCountDown() { 
     countDownText.setVisible(true); 
     timer.schedule(new TimerTask() { 
      @Override 
      public void run() { 
       Platform.runLater(new Runnable() { 
        public void run() { 
         if(hasFinished) 
          return; 
         countDown--; 
         countDownText.setText("Time left:" + countDown); 

         if (countDown < 1) 
          handleFinish(); 
        } 
       }); 
      } 
     }, 1000, 1000); //Every 1 second 
    } 

метод handleFinish метод

/** 
* Action after the timer runs out 
* Disables the button, and sets a new highscore if the achieved score is greater than the current highscore 
* @param highScore 
*/ 

public void handleFinish() { 
    mainButton.setDisable(true); 
    mainButton.setText("Disabled."); 
    if(score > highScore) { 
     highScore = score; 
     saveData(); 
     notificationText.setText("Notification: New highscore! " + highScore); 
     notificationText.setVisible(true); 
     resetStats(); 
     countDownText.setVisible(false); 
     System.out.println("New Highscore"); 
     return; 
    } else { 
    appearDialogue("You didn't beat your highscore! :(Try it again!"); 
    resetStats(); 
    } 
    hasFinished = true; 

} 

resetStats

/** 
* Resets the stats 
* Changes the text of the button, sets the boolean and int @param hasStarted/ @param score to default (false) (0) 
* Sets the position of the button to the default one 
*/ 
public void resetStats() { 
    timer.purge(); 
    mainButton.setText("Click to start.."); 
    hasStarted = false; 
    score = 0; 
    mainButton.setLayoutX(201); 
    mainButton.setLayoutY(157); 
    countDown = 20; 
    scoreText.setVisible(false); 
    mainButton.setDisable(false); 
    System.out.println("STATS RESET"); 
} 

calculatePosition также таймер (TimerTask)

Моя проблема в настоящее время, что они начинают "многопоточность" , как и все больше экземпляров объектов. (Например, вместо одного таймера, отсчитывающего счет, выполняется 2 экземпляра, поэтому - 2 секунды каждые 1 секунду). То же самое происходит с задачей расчета позиции.

instance.purge(); 

продувка просто сбрасывает таймер , если я использую

instance.cancel(); 

он выдает эту ошибку у меня:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source) 
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source) 
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) 
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) 
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source) 
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source) 
    at javafx.event.Event.fireEvent(Unknown Source) 
    at javafx.scene.Scene$ClickGenerator.postProcess(Unknown Source) 
    at javafx.scene.Scene$ClickGenerator.access$7900(Unknown Source) 
    at javafx.scene.Scene$MouseHandler.process(Unknown Source) 
    at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source) 
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source) 
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source) 
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source) 
    at com.sun.glass.ui.View.notifyMouse(Unknown Source) 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
    at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source) 
    at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.reflect.misc.Trampoline.invoke(Unknown Source) 
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source) 
    ... 31 more 
Caused by: java.lang.IllegalStateException: Timer already cancelled. 
    at java.util.Timer.sched(Unknown Source) 
    at java.util.Timer.schedule(Unknown Source) 
    at MainController.startCountDown(MainController.java:233) 
    at MainController.start(MainController.java:91) 
    ... 40 more 

Как-то при возникновении этой ошибки, задача calculatePosition делает работу обычно (не размножается)

Помощь приветствуется! :)

добрые пожелания, Ясин

ответ

1

Вместо того, чтобы TimerTask вы можете просто использовать Timeline. Подробнее here.

Это моя короткая версия вашей игры:

private static final Integer TOTALTIME = 20; 
private final IntegerProperty count = new SimpleIntegerProperty(TOTALTIME); 

private final Label timerLabel = new Label(); 
private final Button btn = new Button("Start countdown"); 

@Override 
public void start(Stage primaryStage) { 

    timerLabel.textProperty().bind(count.asString()); 
    timerLabel.setVisible(false); 

    final Timeline timeline = new Timeline(); 
    timeline.setCycleCount(TOTALTIME); 
    KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), e->count.set(count.get()-1)); 
    timeline.getKeyFrames().add(keyFrame); 
    timeline.setOnFinished(e->handleFinish()); 

    btn.setOnAction(e->{ 
     btn.setDisable(true); 
     timerLabel.setVisible(true); 
     timeline.playFromStart(); 
    }); 

    VBox root = new VBox(20,timerLabel,btn);   
    Scene scene = new Scene(root, 300, 250); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

private void handleFinish() { 
    timerLabel.setVisible(false); 
    btn.setDisable(false); 
    resetStats(); 
} 

private void resetStats() { 
    count.set(TOTALTIME); 
} 

Обратите внимание, что вам не нужно Platform.runLater(), так как все выполняется на потоке приложения JavaFX.

+0

Даже не работает ... – Sh0ck

+0

Вы можете быть более конкретным ... Какой JDK вы используете? Какие ошибки/исключения у вас есть? Меня устраивает. –

Смежные вопросы