我有下面的代码,其中包含一个类和一个嵌套的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();
我会得到空指针异常...为什么会发生这种情况,我看到一切都很好。我的错误是什么?
答案 0 :(得分:2)
您永远不会将控制器实例连接到fxml。
使用setController
为FXMLLoader
设置控制器类。
此外,您需要以某种方式将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();