【问题标题】:Java: SetText inside a threadJava:线程内的 SetText
【发布时间】:2014-07-29 14:05:14
【问题描述】:

谁能帮帮我:

我有一些 TextFields 我想用作计时器(或时钟),所以我将文本设置在我在控制器类中调用的线程中。

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

我不知道为什么我在运行我的代码后得到一个 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)

请帮助并提前致谢

【问题讨论】:

  • 你班级的字段为空。你必须这样写:TextField dayText = new TextField();
  • 也许这会有所帮助:stackoverflow.com/questions/15304203/…
  • 感谢您的评论。我忘了提到我确实尝试过,但它也不起作用。因为我使用一个 FXML 文件来实例化我的 texFields,所以我不会在我的控制器中再次实例化它们,如果我错了,请纠正我。再次感谢。
  • 不要让你的控制器扩展线程!!!
  • 完全不要使用线程。相反,请使用此处建议的时间线:stackoverflow.com/questions/9966136/…

标签: java multithreading javafx settext


【解决方案1】:

您可以使用 TimeLine 和 KeyFrames。只需将showTime() 替换为您自己的代码即可。 并且不要扩展线程。

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

}

【讨论】:

    【解决方案2】:

    我建议在传递 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
            }
    
        }
    

    您还可以使用this 将您的控制器作为 someThread 的参数传递,并将您的TextFields 公开,以便 someThread 可以访问它们。

    【讨论】:

    • 另外:我注意到您的错误指向MainWindowController.java:208,但我只看到 69 行。您是否有意删除了部分代码?
    • 是的,我确实删除了一些行以使其更清晰,我只保留了我需要的内容,并且删除了所有与我想做的任务无关的内容
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 2016-12-09
    相关资源
    最近更新 更多