我有两个控制器。 ClientsViewController 正在调用 ClientAddWindowController ,因此后者创建了一个新阶段。我要做的是在新阶段创建客户端后,在放置该客户端的ClientsViewController上调用该方法。
我的问题是,除了ClientAddWindowController的构造方法之外,对ClientsViewController的引用还显示了nullpointer异常。我不明白为什么,因为我正在将调用者的引用传递给构造函数。当涉及到调用saveClient时,引用表明它是一个空指针。我在做什么错了?
错误
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at controllers.ClientAddWindowController.saveClient(ClientAddWindowController.java:140)
at controllers.ClientAddWindowController.lambda$initialize$0(ClientAddWindowController.java:92)
ClientsViewController.java
public class ClientsViewController implements Initializable {
// ...
@FXML private Button addClientButton;
@FXML private ClientAddWindowController clientAddWindowController;
private Client recentlyAddedClient;
@Override
public void initialize(URL location, ResourceBundle resources) {
addClientButton.setOnAction(event -> {
openClientAddWindow();
});
}
public void openClientAddWindow() {
clientAddWindowController = new ClientAddWindowController(this);
clientAddWindowController.showStage();
}
public void setRecentlyAddedClient(Client recentlyAddedClient) {
this.recentlyAddedClient = recentlyAddedClient;
}}
ClientAddWindowController.java
public class ClientAddWindowController implements Initializable {
// ...
@FXML private Button saveButton;
@FXML private Button cancelButton;
private ClientsViewController clientsViewController;
private Stage clientAddWindowStage;
public ClientAddWindowController() {}
/**
* Upon creating controller instance, load fxml file and create new stage with scene to be shown. Chosen modality
* does not allow to do actions other than in this stage.
* @param clientsViewController is a calling controller
*/
public ClientAddWindowController(ClientsViewController clientsViewController) {
this.clientsViewController = clientsViewController;
this.clientAddWindowStage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/client-add-window.fxml"));
try {
clientAddWindowStage.setTitle("Dodawanie nowego klienta");
clientAddWindowStage.initModality(Modality.APPLICATION_MODAL);
clientAddWindowStage.setScene(new Scene(loader.load()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void initialize(URL location, ResourceBundle resources) {
countryChoiceBox.getItems().addAll(new CountryList().getCountryNames());
saveButton.setOnAction(event -> saveClient());
}
/**
* Creates new client with informations based on given fields. After that passes this client to parent controller
* and closes the Stage.
*/
@FXML
public void saveClient() {
Client newClient = new Client(
"test",
"test",
"test"
);
clientsViewController.setRecentlyAddedClient(newClient);
clientAddWindowStage.close();
}
/**
* Show stage provided by creating this controller.
*/
public void showStage() {
clientAddWindowStage.show();
}}
client-add-window.fxml
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.ClientAddWindowController">
<children>
<TextField fx:id="nameField" GridPane.columnIndex="1" />
<TextField fx:id="shortNameField" layoutX="330.0" layoutY="34.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="emailField" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField fx:id="telephone1Field" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<TextField fx:id="telephone2Field" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<TextField fx:id="telephone3Field" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="nazwa" GridPane.halignment="CENTER" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="nazwa skrócona" GridPane.rowIndex="1" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="e-mail" GridPane.rowIndex="2" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="telefon" GridPane.rowIndex="3" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="telefon 2" GridPane.rowIndex="4" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="telefon 3" GridPane.rowIndex="5" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="NIP" GridPane.columnIndex="2" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="REGON" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="PESEL" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="miasto" GridPane.rowIndex="7" />
<TextField fx:id="nipField" GridPane.columnIndex="3" />
<TextField fx:id="regonField" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<TextField fx:id="peselField" GridPane.columnIndex="3" GridPane.rowIndex="2" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="ulica" GridPane.rowIndex="8" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="kod pocztowy" GridPane.rowIndex="9" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="województwo" GridPane.rowIndex="10" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="status klienta" GridPane.columnIndex="2" GridPane.rowIndex="4" />
<ChoiceBox fx:id="clientStatusChoiceBox" prefHeight="25.0" prefWidth="283.0" GridPane.columnIndex="3" GridPane.rowIndex="4" />
<TextField fx:id="cityField" GridPane.columnIndex="1" GridPane.rowIndex="7" />
<TextField fx:id="streetField" GridPane.columnIndex="1" GridPane.rowIndex="8" />
<TextField fx:id="postalCodeField" GridPane.columnIndex="1" GridPane.rowIndex="9" />
<ChoiceBox fx:id="voivodeshipChoiceBox" prefHeight="25.0" prefWidth="283.0" GridPane.columnIndex="1" GridPane.rowIndex="10" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="strona www" GridPane.rowIndex="6" />
<TextField fx:id="urlField" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<Button fx:id="downloadDataButton" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" prefHeight="25.0" prefWidth="103.0" text="Pobierz dane" GridPane.columnIndex="4" GridPane.halignment="CENTER" />
<Button fx:id="saveButton" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" onAction="#saveClient" prefHeight="25.0" prefWidth="114.0" text="Zapisz" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="15" />
<Button fx:id="cancelButton" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" prefHeight="25.0" prefWidth="114.0" text="Anuluj" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.rowIndex="15" />
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="17.0" prefWidth="382.0" text="kraj" GridPane.rowIndex="11" />
<ChoiceBox fx:id="countryChoiceBox" prefHeight="25.0" prefWidth="283.0" GridPane.columnIndex="1" GridPane.rowIndex="11" />
</children>
</GridPane>
clients-view.fxml
<SplitPane dividerPositions="0.7978789769182782" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.ClientsViewController">
<items>
<ScrollPane fitToWidth="true" minViewportWidth="480.0" prefHeight="1026.0" prefWidth="790.0">
<content>
<TableView fx:id="productsView" minWidth="-Infinity" prefHeight="1007.0" prefWidth="577.0" tableMenuButtonVisible="true">
<columns>
<TableColumn fx:id="shortNameColumn" editable="false" prefWidth="138.99996948242188" text="skrót" />
<TableColumn fx:id="nameColumn" editable="false" prefWidth="71.0" text="nazwa" />
<TableColumn fx:id="cityColumn" editable="false" prefWidth="178.0" text="miasto" />
<TableColumn fx:id="streetColumn" editable="false" prefWidth="119.0" text="ulica" />
<TableColumn fx:id="voivodeshipColumn" prefWidth="75.0" text="województwo" />
<TableColumn fx:id="nipColumn" editable="false" prefWidth="75.0" text="nip" />
<TableColumn fx:id="emailColumn" prefWidth="75.0" text="e-mail" />
<TableColumn fx:id="telephone1Column" editable="false" prefWidth="75.0" text="telefon" />
<TableColumn fx:id="statusColumn" editable="false" prefWidth="75.0" text="status" />
<TableColumn fx:id="peselColumn" prefWidth="75.0" text="pesel" visible="false" />
<TableColumn fx:id="regonColumn" prefWidth="75.0" text="regon" />
<TableColumn fx:id="urlColumn" prefWidth="75.0" text="strona www" visible="false" />
<TableColumn fx:id="telephone2Column" prefWidth="75.0" text="telefon 2" visible="false" />
<TableColumn fx:id="telephone3Column" prefWidth="75.0" text="telefon 3" visible="false" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</content>
</ScrollPane>
<GridPane alignment="CENTER" prefHeight="1009.0" prefWidth="807.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button fx:id="addClientButton" alignment="CENTER" mnemonicParsing="false" text="Dodaj klienta" GridPane.halignment="CENTER" />
<Button fx:id="testButton" mnemonicParsing="false" text="Button" GridPane.halignment="CENTER" GridPane.rowIndex="1" />
</children>
</GridPane>
</items>
</SplitPane>
项目结构
答案 0 :(得分:0)
现在请检查两件事: 1.例如,通过添加以下内容来检查FXML文件的位置:
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/client-add-window.fxml"));
行:
System.out.println(loader.getLocation());
并确保输入正确的地址。
答案 1 :(得分:0)
fxml文件中使用的Controller类由JavaFX在View加载时创建。 不要自己创建它们。因此,您必须稍微重组应用程序。我正在尝试引导您:
将阶段引用从ClientAddWindowController
移动到ClientsViewController
。以下是ClientsViewController
中的重要内容:
public class ClientsViewController implements Initializable {
@FXML
private Button addClientButton;
private Stage clientAddWindowStage;
@Override
public void initialize(URL location, ResourceBundle resources) {
addClientButton.setOnAction(event -> openClientAddWindow());
try {
clientAddWindowStage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/client-add-window.fxml"));
clientAddWindowStage.setTitle("Dodawanie nowego klienta");
clientAddWindowStage.initModality(Modality.APPLICATION_MODAL);
clientAddWindowStage.setScene(new Scene(loader.load()));
// get the controller and set this so the other controller can control it
ClientAddWindowController controller = loader.getController();
controller.setClientsViewController(this);
} catch (IOException e) {
e.printStackTrace();
}
}
public void openClientAddWindow() {
clientAddWindowStage.show();
}
public void closeClientAddWindow() {
clientAddWindowStage.close();
}
}
现在,ClientAddWindowController
的重要部分删除了该阶段并为ClientsViewController
创建了一个二传手:
public class ClientAddWindowController implements Initializable {
@FXML
private Button saveButton;
private ClientsViewController clientsViewController;
@Override
public void initialize(URL location, ResourceBundle resources) {
saveButton.setOnAction(event -> saveClient());
}
public void setClientsViewController(ClientsViewController clientsViewController) {
this.clientsViewController = clientsViewController;
}
@FXML
public void saveClient() {
// ...
clientsViewController.closeClientAddWindow();
}
}
希望可以帮到您。