JavaFX - NullPointerException при переключении на новую сцену - PullRequest
1 голос
/ 30 сентября 2019

Когда я пытаюсь перейти с главного экрана, который является TableView, к другой сцене, содержащей текстовые поля, я получаю исключение NullPointer. Все объекты fxml учитываются, и когда я удаляю значения setCellFactory, они переходят, но элементы не отображаются.

Я попытался сделать следующее: 1. Отобразил все элементы fxml, чтобы убедиться, что это не так. значение NULL. 2. Разделить все функции отображения продукта на отдельные классы.

Main.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();
            }
        }

Products.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);
            }
        }

Controller.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>

shoppingCart.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)

1 Ответ

0 голосов
/ 30 сентября 2019

Вы используете один и тот же контроллер для addItem.fxml и shoppingcart.fxml

Проверьте оба свои тега fx:controller, вы увидите, что они оба указывают на один и тот же контроллер.

Для shoppingcart.fxml это работает, потому что контроллер создан для этого файла fxml. Но для файла addItem.fxml создается другой экземпляр Controller, и в этом файле fxml элементы item_Priority (и друзья) не определены, поэтому они не внедряются в контроллер.

Есть два решения:

  1. создать AddItemController для специальной обработки addItem.fxml и переместить туда всю эту логику, или ...
  2. в initialize метод, проверьте, если itemTable не является нулем, и сделайте что-нибудь в этом случае

    @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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...