JavaFX - 切换到新场景时的 NullPointerException



当我尝试从主屏幕(即 TableView(转到另一个包含文本框的场景时,我收到 NullPointer 异常。所有的fxml对象都被考虑在内,当我删除setCellFactory值时,它会转换,但没有显示任何项目。

我试图遵循: 1. 映射所有 fxml 项以确保它不为空。 2.将所有产品显示功能分离到单独的类别。

主.java

package shoppingcart;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
public class Main extends Application {
//Initializing Main Window
Stage mainWindow;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
mainWindow = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("shoppingcart.fxml"));
mainWindow.setScene(new Scene(root));
mainWindow.show();
}
}

产品.java

package shoppingcart;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Products {
//Variables used to populated Shopping Cart Table
private SimpleStringProperty itemName;
private SimpleStringProperty itemPriority;
private SimpleIntegerProperty itemQty;
private SimpleDoubleProperty itemPrice;
public Products(String itemName, double itemPrice, String itemPriority, int itemQty) {
this.itemName = new SimpleStringProperty(itemName);
this.itemPrice = new SimpleDoubleProperty(itemPrice);
this.itemPriority = new SimpleStringProperty(itemPriority);
this.itemQty = new SimpleIntegerProperty(itemQty);
}
public String getItemName() {
return itemName.get();
}
public void setItemName(String itemName) {
this.itemName = new SimpleStringProperty(itemName);
}
public String getItemPriority() {
return itemPriority.get();
}
public void setItemPriority(String itemPriority) {
this.itemPriority = new SimpleStringProperty(itemPriority);
}
public int getItemQty() {
return itemQty.get();
}
public void setItemQty(int itemQty) {
this.itemQty = new SimpleIntegerProperty(itemQty);
}
public double getItemPrice() {
return itemPrice.get();
}
public void setItemPrice(double itemPrice) {
this.itemPrice = new SimpleDoubleProperty(itemPrice);
}
public String toString() {
return String.format("%s %s", itemName, itemPriority);
}
}

控制器.java

package shoppingcart;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
//Capturing textfields used on Form
@FXML
private TextField productName;
@FXML
private TextField productQty;
@FXML
private TextField productPrice;
@FXML
private TextField productPriority;
@FXML
private AnchorPane productPage;
@FXML
private Button productAdd;
@FXML
private Button productHome;
@FXML
private Text labelitemName;
@FXML
private Text labelitemPriority;
@FXML
private Text labelitemQty;
@FXML
private Text labelitemPrice;
//Table used for Shopping Cart
@FXML
private TableView<Products> item_Table;
@FXML
private TableColumn<Products, String> item_Priority;
@FXML
private TableColumn<Products, String> item_Name;
@FXML
private TableColumn<Products, Integer> item_Qty;
@FXML
private TableColumn<Products, Double> item_Price;
//The Initializer used to load data prior to loading view.
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
item_Priority.setCellValueFactory(new PropertyValueFactory<Products, String>("ItemPriority"));
item_Name.setCellValueFactory(new PropertyValueFactory<Products, String>("ItemName"));
item_Qty.setCellValueFactory(new PropertyValueFactory<Products, Integer>("ItemQty"));
item_Price.setCellValueFactory(new PropertyValueFactory<Products, Double>("ItemPrice"));
item_Table.setItems(getProduct());
System.out.println("Loading user data.");
}
// Method used to get the list of products
public ObservableList<Products> getProduct() {
ObservableList<Products> products = FXCollections.observableArrayList();
products.add(new Products("Orange", 2.00, "1", 1));
return products;
}
public void addItems(ActionEvent event) throws IOException {
Parent addItem_page = FXMLLoader.load(getClass().getResource("addItem.fxml"));
Scene addItem_scene = new Scene(addItem_page);
Stage addItem_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
addItem_stage.setScene(addItem_scene);
addItem_stage.show();
System.out.println("Displaying information to console: Ensuring the addItem method worked as expected.");
}
public void handleitemAdd() {
System.out.println("Added item to cart test");
}
public void handleitemReturnCart(ActionEvent event) throws IOException {
Parent shoppingCart_page = FXMLLoader.load(getClass().getResource("shoppingcart.fxml"));
Scene shoppingCart_scene = new Scene(shoppingCart_page);
Stage shoppingCart_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
shoppingCart_stage.setScene(shoppingCart_scene);
shoppingCart_stage.show();
System.out.println("Displaying information to console: Ensuring that user returned to main page");
}
public void handleitemDelete (ActionEvent event) throws IOException {
System.out.println("Displaying information to console: Deleting Selected Item");
}
}

addItem.fxml


<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<?import javafx.scene.text.Text?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="" fx:id="productPage" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/2.2" fx:controller="shoppingcart.Controller">
<children>
<TextField id="" fx:id="productName" layoutX="235.0" layoutY="118.0" prefWidth="200.0"/>
<TextField id="" fx:id="productPrice" layoutX="235.0" layoutY="222.0" prefWidth="200.0"/>
<TextField id="" fx:id="productQty" layoutX="235.0" layoutY="175.0" prefWidth="200.0"/>
<TextField id="" fx:id="productPriority" layoutX="235.0" layoutY="64.0" prefWidth="200.0"/>
<Text id="" fx:id="labelitemName" layoutX="85.0" layoutY="144.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Item Name:"/>
<Text id="" fx:id="labelitemQty" layoutX="111.0" layoutY="207.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Item Qty:"/>
<Text id="" fx:id="labelitemPriority" layoutX="79.0" layoutY="90.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Item Priority:"/>
<Text id="" fx:id="labelitemPrice" layoutX="97.0" layoutY="251.0" scaleX="1.0" scaleY="0.9999961759667156"
strokeType="OUTSIDE" strokeWidth="0.0" text="Item Price:"/>
<Button id="itemsAdd" fx:id="productAdd" layoutX="235.0" layoutY="287.0" onAction="#handleitemAdd" text="ADD"/>
<Button id="returnCartHome" fx:id="productHome" layoutX="344.0" layoutY="287.0" mnemonicParsing="false"
onAction="#handleitemReturnCart" text="Return to Cart"/>
</children>
</AnchorPane>

购物车.fxml


<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.*?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/2.2" fx:controller="shoppingcart.Controller">
<Button fx:id="itemsAdd" layoutX="29.0" layoutY="352.0" onAction="#addItems" text="Add Items to Cart"/>
<TableView fx:id="item_Table" layoutX="29.0" layoutY="64.0" prefHeight="272.0" prefWidth="542.0"
tableMenuButtonVisible="true">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
<columns>
<TableColumn editable="false" prefWidth="75.0" text="Priority" fx:id="item_Priority"/>
<TableColumn editable="false" prefWidth="75.0" text="Item Name" fx:id="item_Name"/>
<TableColumn editable="false" prefWidth="75.0" text="Item Qty" fx:id="item_Qty"/>
<TableColumn editable="false" prefWidth="75.0" text="Price" fx:id="item_Price"/>
</columns>
</TableView>
<Text layoutX="44.0" layoutY="43.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Shopping Cart Application"
wrappingWidth="513.0000000000001">
<font>
<Font size="44.0"/>
</font>
</Text>
<Button id="itemsDelete" layoutX="312.0" layoutY="352.0" mnemonicParsing="false" onAction="#handleitemDelete"
text="Delete Selected Item"/>
</AnchorPane>
Caused by: java.lang.NullPointerException
at assignment_3/shoppingcart.Controller.initialize(Controller.java:74)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)

您对addItem.fxmlshoppingcart.fxml使用相同的控制器

检查您的两个fx:controller标签,您会发现它们都指向同一个控制器。

对于shoppingcart.fxml,它之所以有效,是因为控制器是为该 fxml 文件制作的。但是对于addItem.fxml文件,将创建Controller的另一个实例,并且在该 fxml 文件中,未定义item_Priority(和友元(的元素,因此它们不会注入控制器中。

有两种解决方案:

  1. 创建一个专门处理addItem.fxmlAddItemController并将所有这些逻辑移动到那里,或者......
  2. initialize方法中,检查itemTable是否不为 null 并在这种情况下执行某些操作

    @Override public void initialize(URL url, ResourceBundle resourceBundle) {
    if (item_Table != null) {
    item_Priority.setCellValueFactory(new PropertyValueFactory<Products, String>("ItemPriority"));
    item_Name.setCellValueFactory(new PropertyValueFactory<Products, String>("ItemName"));
    item_Qty.setCellValueFactory(new PropertyValueFactory<Products, Integer>("ItemQty"));
    item_Price.setCellValueFactory(new PropertyValueFactory<Products, Double>("ItemPrice"));
    item_Table.setItems(getProduct());
    }
    }
    

为了便于使用,我肯定会使用解决方案1。

相关内容

最新更新