一旦按下按钮并将其显示在屏幕上,下面的JavaFx程序应该会在计算机上获取当前IP地址。我已经完成了所有工作,但是从扩展Task的类中更新文本时遇到了问题

MainApp.java

public class MainApp extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/Scene.fxml"));

        Scene scene = new Scene(root);
        scene.getStylesheets().add("/styles/Styles.css");

        stage.setAlwaysOnTop(true);
        stage.setTitle("IP Viewer");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}


我的FXMLController

public class FXMLController implements Initializable {

    @FXML
    private void handleButtonAction(ActionEvent event) {

        Task<Void> task = new IpTask();;

        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();

    }

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


IpTask:它获取当前IP地址并尝试更新UI,但是在java.lang.NullPointerException上出现一个textIp.setText异常

public class IpTask extends Task<Void> {

    @FXML
    private Text textIp;

    @Override
    protected Void call() throws Exception {
        Common common = new Common();
        Ip ip = common.getIp();
        System.out.println("You clicked me!");
        return null;
    }

    @Override
    protected void failed() {
        System.out.println("Failed!");
    }

    @Override
    protected void succeeded() {
        System.out.println("Updated");
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                textIp.setText("JUST TO SEE IF THE TEXT GETS SET");
            }
        });
    }
}


下面是我的Scene.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="com.limitedenterprisesinc.ipviewer.FXMLController">
    <children>
        <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
        <!-- <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" /> -->
        <javafx.scene.text.Text layoutX="126" layoutY="140" fx:id="textIp"/>
    </children>
</AnchorPane>


如何从IpTask类更新textIp文本字段?

最佳答案

字段被注入到与FXMLLoader一起使用的控制器实例中。 IpTask不用作控制器,因此不会向该字段注入任何内容。

将字段注入控制器,并将其传递给IpTask。而且,您不必在Platform.runLater方法中使用succeeded,因为它是在JavaFX应用程序线程上调用的。

public class FXMLController implements Initializable {

    @FXML
    private Text textIp;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        Task<Void> task = new IpTask(textIp);

        Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();
    }

    ...
}




public class IpTask extends Task<Void> {

    private final Text textIp;

    public IpTask(Text textIp) {
        if (textIp == null) {
            throw new IllegalArgumentException();
        }
        this.textIp = textIp;
    }

    ...

    @Override
    protected void succeeded() {
        System.out.println("Updated");
        textIp.setText("JUST TO SEE IF THE TEXT GETS SET");
    }
}

07-24 15:42