公共类

时间:2016-10-30 15:46:33

标签: java javafx

我有下面的代码,其中包含一个类和一个嵌套的JavaFX Controller。我初始化了JavaFX Controller类,我得到了一个你可以看到它的实例。

SpeechWindow类:

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

import application.Main;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

/**
 * SpeechWindow
 *
 */
public class SpeechWindow extends Stage {

    private Container container = new Container();

    /**
     * Constructor
     */
    public SpeechWindow() {

        setTitle("SpeechResults");
        setScene(new Scene(container));
    }

    /**
     * @param text
     */
    public void appendText(String text) {
        container.appendText(text);
    }

    /**
     * 
     */
    public void clear() {
        container.clear();
    }

    public class Container extends BorderPane implements Initializable {

        @FXML
        private TextArea textArea;

        public Container() {
            // FXMLLOADER
            FXMLLoader loader = new FXMLLoader(getClass().getResource("SpeechWindow.fxml"));
            try {
                loader.load();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public void initialize(URL location , ResourceBundle resources) {
            System.out.println("Container has been initialized..");
        }

        public void appendText(String text) {
            Platform.runLater(() -> textArea.appendText(text + "\n"));
        }

        public void clear() {
            Platform.runLater(textArea::clear);
        }

    }

}

这是 FXML代码

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

<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.BorderPane?>


<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
   <center>
      <TextArea fx:id="textArea" editable="false" prefHeight="200.0" prefWidth="200.0" promptText="...no response" wrapText="true" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

尝试从主JavaFX Application类中调用它来创建SpeechWindow的实例并调用appendText();方法。出现空指针的原因是什么?

目标是:

然后我想创建一个外部类的实例并使用它。

出了什么问题:

如果我创建SpeechWindow类的实例并调用方法appendText();我会得到空指针异常...为什么会发生这种情况,我看到一切都很好。我的错误是什么?

2 个答案:

答案 0 :(得分:2)

您永远不会将控制器实例连接到fxml。

使用setControllerFXMLLoader设置控制器类。

此外,您需要以某种方式将fxml的加载结果添加到场景中。可能你应该用fx:root元素替换fxml的根元素。

顺便说一句:如果不能使用实例,如果发生这样的异常,那么简单地捕获一个异常似乎是一个坏主意......

public Container() {
    // FXMLLOADER
    FXMLLoader loader = new FXMLLoader(getClass().getResource("SpeechWindow.fxml"));

    // set controller & root
    loader.setController(this);
    loader.setRoot(this);
    try {
        loader.load();
    } catch (IOException ex) {
        // throw as cause of RuntimeException
        throw new IllegalStateException(ex);
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.BorderPane?>

<fx:root type="javafx.scene.layout.BorderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
   <center>
      <TextArea fx:id="textArea" editable="false" prefHeight="200.0" prefWidth="200.0" promptText="...no response" wrapText="true" BorderPane.alignment="CENTER" />
   </center>
</fx:root>

答案 1 :(得分:1)

在调用方法之前,您必须使用FXMLLoader.getController()方法获取Container类。

尝试致电

FXMLLoader loader = new FXMLLoader(getClass().getResource(".../SpeechWindow.fxml"));

来自SpeechWindow类,而不是Container的构造函数。然后通过

检索Container
Container container = loader.getController();