【发布时间】:2018-05-01 13:18:45
【问题描述】:
我是一个初学者,我正在尝试构建一个简单的字典应用程序。
我有一个控制器类,它有一个按钮可以打开一个新对话框来输入各种详细信息。
对话框由一个单独的控制器控制,这是我遇到问题的地方,我的 FXML 元素被赋予了 null 值,因此当我运行代码时出现 nullpointerexception。我已经用@FXML 注释了FXML 变量,并检查了fxml 文件中的fx:id 是否与java 文件的匹配。
这是 Controller.java 代码:
package sample;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.BorderPane;
import javafx.scene.control.Dialog;
import java.io.IOException;
import java.util.Optional;
public class Controller {
@FXML
private BorderPane mainBorderPane;
@FXML
private DialogController controller = new DialogController();
@FXML
public void initialize(){
}
@FXML
public void newItemDialog(){
Dialog <ButtonType> dialog = new Dialog<>();
dialog.initOwner(mainBorderPane.getScene().getWindow());
dialog.setTitle("Insert Word");
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("newDialog.fxml"));
try{
dialog.getDialogPane().setContent(fxmlLoader.load());
}catch(IOException e) {
e.printStackTrace();
return;
}
dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
Optional<ButtonType> result = dialog.showAndWait();
if(result.isPresent() && result.get() == ButtonType.OK){
boolean results = controller.processResults();
}else{
System.out.println("Cancelled");
return;
}
}
}
这是 DialogController.java 代码:
package sample;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import sample.control.Data;
import java.io.IOException;
import java.util.Optional;
public class DialogController {
@FXML
private TextField nameField;
@FXML
private TextField descriptionField;
@FXML
private TextField typeField;
@FXML
private TextField sentenceField;
@FXML
public boolean processResults() {
String name = nameField.getText();
String description = descriptionField.getText();
String type = typeField.getText();
String sentence = sentenceField.getText();
return Data.getInstance().addWord(name,type,description,sentence);
}
}
这里是 sample.fxml 代码:
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ListView?>
<?import java.lang.String?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>
<BorderPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml"
fx:id ="mainBorderPane">
<top>
<MenuBar>
<Menu fx:id="fileButton" text="File">
<MenuItem fx:id="newButton" onAction="#newItemDialog" text="New"/>
<MenuItem fx:id="updateButton" text="Update"/>
<MenuItem fx:id="deleteButton" text="Delete"/>
<MenuItem fx:id="saveButton" text="Save"/>
</Menu>
<Menu fx:id="viewButton" text="View">
<MenuItem text="Dark Mode"/>
</Menu>
</MenuBar>
</top>
<left>
<ListView fx:id="wordListView" BorderPane.alignment="TOP_LEFT" prefHeight="Infinity" prefWidth="250">
</ListView>
</left>
<center>
<VBox>
<TextArea fx:id = "wordDetails" prefWidth="Infinity" prefHeight="400">
</TextArea>
<TextArea prefWidth="Infinity" prefHeight="200">
</TextArea>
</VBox>
</center>
</BorderPane>
这里是 newDialog.fxml 代码:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.DialogPane?>
<DialogPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="sample.DialogController"
prefHeight="400.0" prefWidth="600.0">
<headerText>
Enter A Word
</headerText>
<content>
<VBox>
<TextField fx:id="nameField" promptText="Enter the word"/>
<TextField fx:id="typeField" promptText="Enter the type"/>
<TextField fx:id="descriptionField" promptText="Enter a description"/>
<TextField fx:id="sentenceField" promptText="Enter a sentence"/>
</VBox>
</content>
提前致谢!
【问题讨论】:
-
每个
Controller都应该有自己的FXML文件 -
简单地创建一个控制器实例不会导致 fxml 中的任何字段使用此控制器的类名作为
fx:controller属性的值被注入到新创建的控制器实例中。