简体   繁体   English

Java:线程内的SetText

[英]Java: SetText inside a thread

Can anyone please help me with this: 谁能帮我这个忙:

I have some TextFields that i want to use as a timer (or a clock) so i set the text in a thread that i call inside my controller class. 我有一些TextField想要用作计时器(或时钟),因此我在控制器类内部调用的线程中设置了文本。

package application;

import java.net.URL;
import java.util.ResourceBundle;

import org.joda.time.DateTime;

import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import jdk.nashorn.internal.runtime.FindProperty;

public class MainWindowController extends Thread implements Initializable{

@FXML
private TextField dayText;

@FXML
private TextField monthText;

@FXML
private TextField yearText;

@FXML
private TextField hoursText;

@FXML
private TextField minutesText;

@FXML
private TextField secondsText;

@FXML
private TextField julianDayText;

@Override
public void initialize(URL arg0, ResourceBundle arg1) {

    this.start();

}

@Override
public void run() {

        while(true){

            DateTime d = new DateTime(System.currentTimeMillis());

            dayText.setText(String.valueOf(d.getDayOfMonth()));
            monthText.setText(String.valueOf(d.getMonthOfYear()));
            yearText.setText(String.valueOf(d.getYear()));

            hoursText.setText(String.valueOf(d.getHourOfDay()));
            minutesText.setText(String.valueOf(d.getMinuteOfHour()));
            secondsText.setText(String.valueOf(d.getSecondOfMinute()));
        }
    }   
}

I don't know why i get a NullPointerException after running my code (it works for a little bit then it crashes) : 我不知道为什么在运行我的代码后会得到NullPointerException(它工作了一段时间然后崩溃了):

Exception in thread "Thread-4" java.lang.NullPointerException
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:339)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1116)
at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1120)
at javafx.scene.control.TextInputControl$TextProperty.set(TextInputControl.java:1056)
at javafx.scene.control.TextInputControl.setText(TextInputControl.java:279)
at application.MainWindowController.run(MainWindowController.java:208)

Please Help and thanks in advance 请帮助并提前感谢

You can use TimeLine And KeyFrames. 您可以使用时间线和关键帧。 Just replace showTime() with your own code. 只需将showTime()替换为您自己的代码即可。 and do not extend thread. 并且不要扩展线程。

public class FXMLTimeController implements Initializable {

    @FXML
    private TextField txtTime;

    //timeline
    private Timeline timeline;

    private void showTime() {
        txtTime.setText((new Date()).toString());
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.setAutoReverse(false);

        timeline.getKeyFrames().add(
                new KeyFrame(Duration.seconds(1),
                        new EventHandler<ActionEvent>() {
                            @Override public void handle(ActionEvent event) {
                                showTime();
                            }
                        }));
        timeline.play();
    }

}

I would suggest calling Platform.runLater(Runnable runnable) in initialize() while passing in JavaFX's TextField fields, instead of making your controller extend Thread, since JavaFX uses the controller for itself. 我建议在传递JavaFX的TextField字段时在initialize()中调用Platform.runLater(Runnable runnable) ,而不要让您的控制器扩展Thread,因为JavaFX本身就使用了控制器。

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        Platform.runLater(
            new someThread(dayText, monthText, yearText,
            hoursText, minutesText, secondsText));
    }

    public class someThread implements Runnable {

        public someThread(TextField... textFields) {
            // Create local variables
        }

        @Override
        public void run() {
            // while (true) loop goes here
        }

    }

You could also use this to pass in your controller as a parameter for someThread and make your TextField s public so they can be accessed by someThread. 您也可以使用this方法将控制器作为someThread的参数传入,并使TextField公开,以便someThread可以访问它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM