javafx应用程序中的计时器

时间:2018-04-12 20:44:19

标签: javafx timer controller fxml

我试图显示一个计时器,在点击开始按钮后计算并显示标签中的秒数,但我没有得到所需的输出。这是我的控制器和FXML文件的代码...

public class FXMLDocumentController implements Initializable {

    @FXML
    private static final Integer STARTTIME = 0;
    private Timeline timeline;
    private Label timerLabel = new Label();
    private IntegerProperty timeSeconds = new SimpleIntegerProperty(STARTTIME);
    Button button = new Button();


    public void handle(ActionEvent event) {
        if (timeline != null) {
            timeline.stop();
        }
        timeSeconds.set(STARTTIME);
        timeline = new Timeline();

        timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(STARTTIME+1),
                                    new KeyValue(timeSeconds, 0)));
        timeline.playFromStart();
        timerLabel.textProperty().bind(timeSeconds.asString());

    }



     public void initialize(URL url, ResourceBundle rb) {
         // TODO

     }    

}

这是我的FXML代码..

<Button fx:id="button" layoutX="120.0" layoutY="40.0" 
        mnemonicParsing="false" text="Start Timmer" onAction="#handle" />
<Label layoutX="132.0" layoutY="92.0" prefHeight="17.0" prefWidth="65.0" 
       textFill="#f20b0b">
    <font>
        <Font size="24.0" />
    </font>
</Label>

1 个答案:

答案 0 :(得分:1)

您没有正确使用Timeline

KeyFrame的持续时间是执行更新时从动画开始的偏移量。多次点击你的按钮都会添加在动画开始后运行1秒的KeyFrame

此外,使用KeyValue会将当前值的值插入传递给KeyValue的值。如果新值与旧值相同,这没有多大意义。

您应该使用EventHandler<ActionEvent>来更新属性。

此外,button字段应由FXMLLoader注入。这要求字段为public或使用@FXML注释。

<Button fx:id="button" layoutX="120.0" layoutY="40.0" 
        mnemonicParsing="false" text="Start Timmer" onAction="#handle" />
<Label fx:id="timerLabel" layoutX="132.0" layoutY="92.0" prefHeight="17.0" prefWidth="65.0" 
       textFill="#f20b0b">
    <font>
        <Font size="24.0" />
    </font>
</Label>
public class FXMLDocumentController implements Initializable {

    private static final int STARTTIME = 0;
    private Timeline timeline;
    private final IntegerProperty timeSeconds = new SimpleIntegerProperty(STARTTIME);

    @FXML
    private Label timerLabel;
    @FXML
    private Button button;

    private void updateTime() {
        // increment seconds
        int seconds = timeSeconds.get();
        timeSeconds.set(seconds+1);
    }

    public void handle(ActionEvent event) {
        button.setDisable(true); // prevent starting multiple times
        timeline = new Timeline(new KeyFrame(Duration.seconds(1), evt -> updateTime())); 
        timeline.setCycleCount(Animation.INDEFINITE); // repeat over and over again
        timeSeconds.set(STARTTIME);
        timeline.play();
    }

    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        timerLabel.textProperty().bind(timeSeconds.asString());
    }    

}