从文本字段中提取空数据。表已填充,但无法检索对象。Java/JavaFX

从文本字段中提取空数据。表已填充,但无法检索对象。Java/JavaFX,java,model-view-controller,javafx,nullpointerexception,tableview,Java,Model View Controller,Javafx,Nullpointerexception,Tableview,我在主屏幕上有两张桌子 零件表和产品表。产品由零件组成。用于零件表搜索、选择等的表功能都可以正常工作。当一个新产品被创建并添加到表中时,它似乎就在那里。然而,当我试图检索数据进行修改时,通过使用数据初始化产品字段,我得到了一个NPE。使用与零件表相同的搜索功能时,搜索功能找不到零件 列出了有问题的文件 MainScreenController.java MainScreen.fxml 我解决了自己的问题。问题最终在于我的.fxml文件ModifyProduct。没有与我试图填充的命名文本字段对应

我在主屏幕上有两张桌子

零件表和产品表。产品由零件组成。用于零件表搜索、选择等的表功能都可以正常工作。当一个新产品被创建并添加到表中时,它似乎就在那里。然而,当我试图检索数据进行修改时,通过使用数据初始化产品字段,我得到了一个NPE。使用与零件表相同的搜索功能时,搜索功能找不到零件

列出了有问题的文件

MainScreenController.java

MainScreen.fxml


我解决了自己的问题。问题最终在于我的.fxml文件ModifyProduct。没有与我试图填充的命名文本字段对应的等效fx:id。因此,尽管我已经实例化了字段,并且由于缺少可识别的名称,我的大部分逻辑工作正常,.fxml无法将数据与字段关联起来。一旦我解析了.fxml文件中的fx:id名称,数据就正确地流动了

ModifyProductController.java

ModifyProduct.fxml


只需记住匹配名称和其他标识符,并确保所有内容都指向它应该指向的其他内容。谢谢大家的帮助

你在代码中的什么地方得到了NPE?它在代码的另一部分,我无法发布。这是我第一次在SO/SE上发帖,上面说我已经超过了我的角色数。我还有另外两个文件要发布。我的修复方法是,在.fxml文件中,我尝试填充的字段没有fx:id条目。新手犯的错误。所以,一旦我更正了fx:id条目以匹配我的字段名,我就没事了。我非常想发布我的其他代码,这样人们可能会从我的错误中得到一些帮助,但由于字符计数通知,不确定如何使用!如果你把它充实起来,这可能是一个很好的答案。
/**
 * Sample Skeleton for 'MainScreen.fxml' Controller Class
 */

package jbernsd_IMS.View;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import jbernsd_IMS.MainApp;
import jbernsd_IMS.Model.Inventory;
import jbernsd_IMS.Model.Part;
import jbernsd_IMS.Model.Product;


public class MainScreenController {

 // Table and column declarations for Part table.
// fx:id partTableMain
    @FXML
    private TableView<Part> partTableMain;

// fx:ids are respective...ie partIdColumnMain, partInvColumnMain, etc.
    @FXML
    private TableColumn<Part, Integer> partIdColumnMain, partInvColumnMain;

// fx:id partNameColumnMain;
    @FXML
    private TableColumn<Part, String> partNameColumnMain;

// fx:id partCostColumnMain
    @FXML
    private TableColumn<Part, Double> partCostColumnMain;

// Table and column declarations for Product table.
// fx:id productTableMain
    @FXML
    private TableView<Product> productTableMain;

// fx:ids are respective...ie productIdColumnMain, productInvColumnMain, etc.
    @FXML
    private TableColumn<Product, Integer> productIdColumnMain, productInvColumnMain;

// fx:id productNameColumnMain
    @FXML
    private TableColumn<Product, String> productNameColumnMain;

// fx:id productCostColumnMain
    @FXML
    private TableColumn<Product, Double> productCostColumnMain;

// fx:ids are respective...ie addPartButtonMain, modPartButtonMain, etc.
    @FXML
    private Button addPartButtonMain, modPartButtonMain, delPartButtonMain, searchPartButtonMain,
       addProductButtonMain, modProductButtonMain, delProductButtonMain, searchProductButtonMain,
            exitButton;

// fx:ids are respective...ie searchPartFieldMain, searchProductFieldMain, etc.
    @FXML
    private TextField searchPartFieldMain, searchProductFieldMain;

    private boolean okClicked = false;

// Reference to the main application...
    private MainApp mainApp;    

    /**
     * The MainScreenController (MSC) no-argument Constructor
     * The constructor is called before the initialize() method.
     */
    public MainScreenController() {
    }

    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        partIdColumnMain.setCellValueFactory(cellData -> cellData.getValue().partIdProperty().asObject());
        partNameColumnMain.setCellValueFactory(cellData -> cellData.getValue().partNameProperty());
        partInvColumnMain.setCellValueFactory(cellData -> cellData.getValue().partInvProperty().asObject());
        partCostColumnMain.setCellValueFactory(cellData -> cellData.getValue().partCostProperty().asObject());



        productIdColumnMain.setCellValueFactory(cellData -> cellData.getValue().productIdProperty().asObject());
        productNameColumnMain.setCellValueFactory(cellData -> cellData.getValue().productNameProperty());
        productInvColumnMain.setCellValueFactory(cellData -> cellData.getValue().productInvProperty().asObject());
        productCostColumnMain.setCellValueFactory(cellData -> cellData.getValue().productCostProperty().asObject());

    }
//    setText(String.format("%0.2f", value.doubleValue()));
    /**
     * Is called by the main application to give reference to itself.
     * 
     * @param mainApp
     */
    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;
        // Add observable list data to the table
        partTableMain.setItems(Inventory.getAllParts());
        productTableMain.setItems(Inventory.getProducts());
    }

// onAction="#handleNewPart"
    @FXML
    private void handleNewPart() {
        okClicked = mainApp.showAddPartScreen();
    }
// onAction="#handleNewProduct"
    @FXML
    private void handleNewProduct() {
        okClicked = mainApp.showAddProductScreen();
    }

// onAction="#handleModPart"    
    @FXML
    private void handleModPart(ActionEvent e)  {

        Inventory.selectedPart = partTableMain.getSelectionModel().getSelectedItem();
        Part selectedPart = Inventory.selectedPart;

        if(selectedPart != null) {

            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("Selection Confirmation");
            alert.setHeaderText("Please confirm the part you selected...");
            alert.setContentText("You have selected: \n\n"
                    + "Part ID: \t\t" + selectedPart.partIdProperty().getValue() + "\n"
                    + "Part Name: \t" + selectedPart.partNameProperty().getValueSafe() + "\n\n");            
            alert.showAndWait()
                    .filter(response -> response == ButtonType.OK)
                    .ifPresent(response -> mainApp.showModPartScreen());

            okClicked = true;

        } else {                                                          //                                       //
                // Nothing selected...                                                                                 
                Alert alert = new Alert(Alert.AlertType.WARNING);                                                      
                alert.setTitle("No selection");                                                                        
                alert.setHeaderText("No part selected");                                                               
                alert.setContentText("Please select a part in the table.");                                            
                alert.showAndWait()
                        .filter(response -> response == ButtonType.OK)
                        .ifPresent(response -> alert.close());

                okClicked = false;
        }
    }

    // onAction="#handleModProduct"    
    @FXML
    private void handleModProduct(ActionEvent e) {
//        productTableMain.setOnMouseClicked((MouseEvent event) -> {
//            if(event.getButton().equals(MouseButton.PRIMARY)) {}
//        });

        Inventory.selectedProduct = productTableMain.getSelectionModel().getSelectedItem();
        Product selectedProduct = Inventory.selectedProduct;

        if(selectedProduct != null) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("Selection Confirmation");
            alert.setHeaderText("Please confirm the product you selected...");
            alert.setContentText("You have selected: \n\n"
                    + "Product ID: \t\t" + selectedProduct.productIdProperty().getValue() + "\n"
                    + "Product Name: \t" + selectedProduct.productNameProperty().getValueSafe() + "\n\n");
            alert.showAndWait()
                    .filter(response -> response == ButtonType.OK)
                    .ifPresent(response -> mainApp.showModProductScreen());
            okClicked = true;

        } else {                                                          //                                       //
                // Nothing selected...                                                                                 
                Alert alert = new Alert(Alert.AlertType.WARNING);                                                      
                alert.setTitle("No selection");                                                                        
                alert.setHeaderText("No products selected");                                                               
                alert.setContentText("Please select a product in the table.");                                            
                alert.showAndWait()
                        .filter(response -> response == ButtonType.OK)
                        .ifPresent(response -> alert.close());
                okClicked = false;
        }                                                                                                          
    }

        // fx:id foundMe
    @FXML
    private void foundMe() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Easter Egg!! (Illegal after 9/11)");
        alert.setHeaderText("Congratulations!!!");
        alert.setContentText("Congratulations!! You found my Easter Egg!!!  :) ");
        alert.showAndWait();
    }


    @FXML
    private void handleClose(ActionEvent e) {
        Platform.exit();        
    }

    /**
     * Called when the user clicks on the delete button.
     */

    @FXML
    private void handleDelete(ActionEvent e) {                                                                     

        Part selectedPart = partTableMain.getSelectionModel().getSelectedItem();                                   

            if(selectedPart != null) {                                                                                 
                // Confirm deletion                                                                                    
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);                                                 
                alert.setTitle("Confirm Deletion");                                                                    
                alert.setHeaderText("Deleting...");                                                                    
                alert.setContentText("Are you sure you want to delete the part? \n\n"
                        + "Part ID: \t\t" + selectedPart.partIdProperty().getValue() + "\n"
                        + "Part Name: \t" + selectedPart.partNameProperty().getValueSafe()); 
                alert.showAndWait()                                                                                    
                        .filter(response -> response  ==  ButtonType.OK)                                                 
                        .ifPresent(response -> Inventory.getAllParts().remove(selectedPart));                             

                // Update partTableMain                                                                                
                partTableMain.setItems(Inventory.getAllParts());

            } else {
                // Nothing selected...                                                                                 
                Alert alert = new Alert(Alert.AlertType.WARNING);                                                      
                alert.setTitle("No selection");                                                                        
                alert.setHeaderText("No part selected");                                                               
                alert.setContentText("Please select a part in the table.");                                            
                alert.showAndWait();
        }                                                                                                          
    }


     @FXML
    private void handleDeleteProd(ActionEvent e) {                                                                     

        Product selectedProduct = productTableMain.getSelectionModel().getSelectedItem();                                   

            if(selectedProduct != null) {                                                                                 
                // Confirm deletion                                                                                    
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);                                                 
                alert.setTitle("Confirm Deletion");                                                                    
                alert.setHeaderText("Deleting...");                                                                    
                alert.setContentText("Are you sure you want to delete the product? \n\n"
                        + "Part ID: \t\t" + selectedProduct.productIdProperty().getValue() + "\n"
                        + "Part Name: \t" + selectedProduct.productNameProperty().getValueSafe()); //
                alert.showAndWait()                                                                                    
                        .filter(response -> response  ==  ButtonType.OK)                                                 
                        .ifPresent(response -> Inventory.getProducts().remove(selectedProduct));                             

                // Update partTableMain                                                                                
                productTableMain.setItems(Inventory.getProducts());

            } else {                                                          //                                       //
                // Nothing selected...                                                                                 
                Alert alert = new Alert(Alert.AlertType.WARNING);                                                      
                alert.setTitle("No selection");                                                                        
                alert.setHeaderText("No product selected");                                                               
                alert.setContentText("Please select a product in the table.");                                            
                alert.showAndWait();
        }                                                                                                          
    }

    @FXML
    private void searchPartTable() {
        String searchItem = searchPartFieldMain.getText();
        if(isSearchInputValid(searchItem)) {        
            FilteredList<Part> searchPartResults = searchParts(searchItem);
            SortedList<Part> sortedParts = new SortedList<>(searchPartResults);
            sortedParts.comparatorProperty().bind(partTableMain.comparatorProperty());
            partTableMain.setItems(sortedParts);
            searchPartFieldMain.clear();
        }
    }
    private FilteredList<Part> searchParts (String s) {
        return Inventory.getAllParts().filtered(p -> p.getPartName().toLowerCase().contains(s.toLowerCase()));
    }


    @FXML
    void searchProductTable() {        
        String searchItem = searchProductFieldMain.getText();

        if(isSearchInputValid(searchItem)) {
            FilteredList<Product> searchProductResults = searchProducts(searchItem);
            SortedList<Product> sortedProducts = new SortedList<>(searchProductResults);
            sortedProducts.comparatorProperty().bind(productTableMain.comparatorProperty());
            productTableMain.setItems(sortedProducts);
        }
    }
    public FilteredList<Product> searchProducts (String s) {
        return Inventory.getProducts().filtered(p -> p.getProductName().contains(s.substring(0, 1).toUpperCase()
                                                                               + s.substring(1).toLowerCase()));
    } 


    public boolean isSearchInputValid(String searchItem) {

        ObservableList<Part> list = FXCollections.observableArrayList(Inventory.getAllParts());

        String errorMessage = "";
        String partName;

        if(Inventory.getAllParts().isEmpty()) {
            errorMessage += "Inv: \t\t There are no parts in inventory to search. \n\n";
        }

        if(!searchItem.equalsIgnoreCase("")) {
            int count = 0;
            for(Part p:Inventory.getAllParts()) {
                String name = p.partNameProperty().getValueSafe();

                if(!searchItem.equalsIgnoreCase(name)  || searchItem.equals(null)) {
                    count++;

                    if(count == Inventory.getAllParts().size()) {
                    errorMessage += "Inv: \t\t The search item, " + "\"" + searchItem + "\"" + " does not match \n" 
                            + "\t\t any known items in the inventory. \n\n"
                            + "\t\t The item cannot be found, or it does not exist. \n";
                    }
                } 
            }
        }

        if(errorMessage.length() == 0) {    
            return true;

        } else {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Error");
            alert.setHeaderText("Data Error Exists");
            alert.setContentText(errorMessage);
            alert.showAndWait();

            return false;
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jbernsd_IMS.View.MainScreenController">
   <children>
      <Rectangle fx:id="borderPartsMAIN" arcHeight="10.0" arcWidth="10.0" fill="TRANSPARENT" height="280.0" layoutX="25.0" layoutY="56.0" stroke="#979797" strokeLineCap="BUTT" strokeLineJoin="ROUND" strokeType="OUTSIDE" strokeWidth="2.0" width="366.0" />
      <Label fx:id="labelInvMgmtSysMAIN" layoutX="18.0" layoutY="15.0" text=" Inventory Management System">
         <font>
            <Font name="Calibri Italic" size="24.0" />
         </font>
      </Label>

      <!-- Parts section begins here -->
      <TableView fx:id="partTableMain" layoutX="35.0" layoutY="95.0" prefHeight="188.0" prefWidth="344.0">
        <columns>            
            <TableColumn fx:id="partIdColumnMain" prefWidth="54.0" text="Part ID">
                <cellValueFactory>
                    <PropertyValueFactory property="partID" />
                </cellValueFactory>
            </TableColumn>

            <TableColumn fx:id="partNameColumnMain" prefWidth="71.0" text="Part Name">
                <cellValueFactory>
                    <PropertyValueFactory property="partName" />
                </cellValueFactory>
            </TableColumn>

            <TableColumn fx:id="partInvColumnMain" minWidth="0.0" prefWidth="97.0" text="Inventory Level">
                <cellValueFactory>
                    <PropertyValueFactory property="partInv" />
                </cellValueFactory>
            </TableColumn>

            <TableColumn fx:id="partCostColumnMain" prefWidth="121.0" text="Price/Cost per Unit">
                <cellValueFactory>
                    <PropertyValueFactory property="partCost" />
                </cellValueFactory>
            </TableColumn>
        </columns>

      </TableView>
      <!-- Parts sections ends here -->

      <Label fx:id="labelPartsPrtsMAIN" layoutX="36.0" layoutY="58.0" text="Parts">
         <font>
            <Font name="Calibri Italic" size="24.0" />
         </font>
      </Label>
      <Button fx:id="searchPartButtonMain" layoutX="179.0" layoutY="63.0" mnemonicParsing="false" onAction="#searchPartTable" text="Search">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font></Button>
      <TextField fx:id="searchPartFieldMain" layoutX="241.0" layoutY="63.0" prefHeight="25.0" prefWidth="136.0" />
      <HBox layoutX="169.0" layoutY="294.0" spacing="15.0">
         <children>
            <Button fx:id="addPartButtonMain" mnemonicParsing="false" onAction="#handleNewPart" prefHeight="30.0" prefWidth="60.0" text="Add">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
            <Button fx:id="modPartButtonMain" mnemonicParsing="false" onAction="#handleModPart" prefHeight="30.0" prefWidth="60.0" text="Modify">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
            <Button fx:id="delPartButtonMain" mnemonicParsing="false" onAction="#handleDelete" prefHeight="30.0" prefWidth="60.0" text="Delete">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
         </children>
      </HBox>
      <!-- Parts section ends here -->

      <!-- Products section begins here -->
      <Rectangle fx:id="borderProdsMAIN" arcHeight="10.0" arcWidth="10.0" fill="TRANSPARENT" height="280.0" layoutX="410.0" layoutY="56.0" stroke="#979797" strokeLineCap="BUTT" strokeLineJoin="ROUND" strokeType="OUTSIDE" strokeWidth="2.0" width="370.0" />
      <TableView fx:id="productTableMain" layoutX="420.0" layoutY="95.0" prefHeight="188.0" prefWidth="344.0">
         <columns>
            <TableColumn fx:id="productIdColumnMain" prefWidth="54.0" text="Prod ID" />
            <TableColumn fx:id="productNameColumnMain" prefWidth="71.0" text="Prod Name" />
            <TableColumn fx:id="productInvColumnMain" minWidth="0.0" prefWidth="97.0" text="Inventory Level" />
            <TableColumn fx:id="productCostColumnMain" prefWidth="121.0" text="Price/Cost per Unit" />
         </columns>
      </TableView>
      <Label fx:id="labelProdsMAIN" layoutX="421.0" layoutY="58.0" text="Products">
         <font>
            <Font name="Calibri Italic" size="24.0" />
         </font>
      </Label>
      <Button fx:id="searchProductButtonMain" layoutX="564.0" layoutY="63.0" mnemonicParsing="false" onAction="#searchProductTable" text="Search">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font></Button>
      <TextField fx:id="searchProductFieldMain" layoutX="626.0" layoutY="63.0" prefHeight="25.0" prefWidth="136.0" />
      <HBox layoutX="554.0" layoutY="294.0" spacing="15.0">
         <children>
            <Button fx:id="addProductButtonMain" mnemonicParsing="false" onAction="#handleNewProduct" prefHeight="30.0" prefWidth="60.0" text="Add">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
            <Button fx:id="modProductButtonMain" mnemonicParsing="false" onAction="#handleModProduct" prefHeight="30.0" prefWidth="60.0" text="Modify">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
            <Button fx:id="delProductButtonMain" mnemonicParsing="false" onAction="#handleDeleteProd" prefHeight="30.0" prefWidth="60.0" text="Delete">
               <font>
                  <Font name="Calibri Italic" size="12.0" />
               </font></Button>
         </children>
      </HBox>
      <Button fx:id="foundMe" layoutX="309.0" layoutY="109.0" mnemonicParsing="false" onAction="#foundMe" prefHeight="2.0" prefWidth="2.0" textFill="TRANSPARENT" AnchorPane.bottomAnchor="288.0" AnchorPane.leftAnchor="309.0" AnchorPane.rightAnchor="489.0" AnchorPane.topAnchor="109.0">
         <font>
            <Font size="2.0" />
         </font>
      </Button>
      <Button fx:id="exitButton" layoutX="370.0" layoutY="356.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#handleClose" prefHeight="30.0" prefWidth="60.0" text="Exit">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font></Button>
      <!-- Products section ends here -->
   </children>
</AnchorPane>
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package jbernsd_IMS.View;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import jbernsd_IMS.MainApp;
import jbernsd_IMS.Model.*;

/**
 *
 * @author JJ_2
 */
public class ModifyProductController {

    private IntegerProperty partIdMP;
    private IntegerProperty partNumberMP;
    private StringProperty partNameMP;
    private IntegerProperty partInvMP;
    private IntegerProperty partCostMP;


    public ModifyProductController() {        
    }
    private MainApp mainApp;

    private Label productIdLbl, productNameLbl, productInvLbl, productCostLbl, maxLbl, minLbl;

    @FXML
    private TextField productIdField, productNameField, productInvField, productCostField, minField, maxField, searchFieldModProds;

    private final ObservableList<Part> importedParts = FXCollections.observableArrayList(Inventory.getAllParts());

    private final ObservableList<Part> productParts = FXCollections.observableArrayList();


    // Parts to add
    // fx:id partTableAdd
    @FXML
    private TableView<Part> partTableAdd;   // Stores the found parts to add to the product.

    @FXML
    private TableColumn<Part, Integer> partIdColumnAdd, partInvColumnAdd;    // Holds the part ID and part Inv.

    @FXML
    private TableColumn<Part, String> partNameColumnAdd;   // Holds the part Name.

    @FXML
    private TableColumn<Part, Double> partCostColumnAdd;   // Holds the manufacturing cost of specified part.


    // Parts to remove
    // fx:id partTableDel
    @FXML
    private TableView<Part> partTableDel;   // Stores the found parts to delete from the product.

    @FXML
    private TableColumn<Part, Integer> partIdColumnDel, partInvColumnDel;    // Holds the part ID and part Inv.

    @FXML
    private TableColumn<Part, String> partNameColumnDel;   // Holds the part Name.

    @FXML
    private TableColumn<Part, Double> partCostColumnDel;   // Holds the manufacturing cost of specified part.

    @FXML
    private Stage dialogueStage;

    @FXML
    private boolean saveClicked = false;

    @FXML
    private boolean addClicked = false;

    public ObservableList<Part> getProdParts() {
        return productParts;
    }

    private Product draftProduct;



    public Inventory inv;

    public MainScreenController msc;
    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {

    // Set text fields.
        setTextFields();       

    // part table (top)        
        partIdColumnAdd.setCellValueFactory(cellData -> cellData.getValue().partIdProperty().asObject());
        partNameColumnAdd.setCellValueFactory(cellData -> cellData.getValue().partNameProperty());
        partInvColumnAdd.setCellValueFactory(cellData -> cellData.getValue().partInvProperty().asObject());
        partCostColumnAdd.setCellValueFactory(cellData -> cellData.getValue().partCostProperty().asObject());
        partTableAdd.setItems(importedParts);

    // part table (bottom)
        partIdColumnDel.setCellValueFactory(cellData -> cellData.getValue().partIdProperty().asObject());
        partNameColumnDel.setCellValueFactory(cellData -> cellData.getValue().partNameProperty());
        partInvColumnDel.setCellValueFactory(cellData -> cellData.getValue().partInvProperty().asObject());
        partCostColumnDel.setCellValueFactory(cellData -> cellData.getValue().partCostProperty().asObject());


    }

    /**
     * Returns true if the user clicked OK, false otherwise.
     * 
     * @return
     */
    public boolean isSaveClicked() {
        return saveClicked;
    }

    public boolean isAddClicked() {
        return addClicked;
    }

    /**
     * Called when the user clicks Add.
     */
    @FXML
    private void handleAdd() {

         Part selectedPart = partTableAdd.getSelectionModel().getSelectedItem();
         if (selectedPart != null) {
             productParts.add(selectedPart);
             partTableDel.getItems().add(selectedPart);
         }
        else {//part not selected
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("No Selection");
            alert.setHeaderText("No part is selected");
            alert.setContentText("Please select a part from the top table.");
            alert.showAndWait();
        }
     }

    /**
     * Sets the stage of this dialogue
     * 
     * @param dialogueStage 
     */
    @FXML
    public void setDialogueStage(Stage dialogueStage) {
        this.dialogueStage = dialogueStage;
    }

    // References MainApp
    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;
    }

    public void setTextFields() {
        try {
            productIdField.setText(Integer.toString(Inventory.selectedProduct.getProductId()));
            productNameField.setText(Inventory.selectedProduct.getProductName());
            productInvField.setText(Integer.toString(Inventory.selectedProduct.getProductInv()));
            productCostField.setText(Double.toString(Inventory.selectedProduct.getProductCost()));
            maxField.setText(Integer.toString(Inventory.selectedProduct.getMax()));
            minField.setText(Integer.toString(Inventory.selectedProduct.getMin()));

        } catch (NullPointerException e) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setTitle("Data Not Found");
            alert.setHeaderText("Cannot find the requested data...");
            alert.setContentText("The requested data is not being passed \n"+
                                 "correctly.  Check your code for data \n"+
                                 "flow errors. \n\n" +
                                productIdField.getText()+ "\n" +
                                productNameField.getText()+ "\n" +
                                productInvField.getText()+ "\n" +
                                productCostField.getText()+ "\n" +
                                maxField.getText()+ "\n" +
                                minField.getText());
            alert.showAndWait();
        }
    }

    @FXML
    public void handleSave() {

        if(isInputValid()) {

                draftProduct.setProductId(Integer.parseInt(productIdField.getText()));
                draftProduct.setProductName(productNameField.getText());
                draftProduct.setProductInv(Integer.parseInt(productInvField.getText()));
                draftProduct.setProductCost(Double.parseDouble(productCostField.getText()));
                draftProduct.setMax(Integer.parseInt(maxField.getText()));
                draftProduct.setMin(Integer.parseInt(minField.getText()));

                mainApp.getProductData().add(draftProduct);

            }

            dialogueStage.close();

        }


    /**
     * Called when the user clicks cancel.
     */
    @FXML
    private void handleCancel() {
        dialogueStage.close();
    }

    //------------------Working code, **** DO NOT DELETE **** -----------------------------------------------
    private boolean isInputValid() {
        String errorMessage = "";

        // NO check needed for partID as it's auto-generated.

        if(productNameField.getText().isEmpty() || productNameField.getText().matches("\\d+")) {
            errorMessage += "Name: \t\t\t No valid product name!\n"
                         + "\t\t\t\t Only letters are allowed. \n\n";
        }

        if(productInvField.getText().isEmpty() || !productInvField.getText().matches("\\d+")) {

            errorMessage += "Inv: \t\t\t\t No valid inventory level!\n"
                        + "\t\t\t\t Only numbers are allowed. \n\n";

            } else if(productInvField.getText().compareToIgnoreCase(maxField.getText()) > 0) {
                    errorMessage += "Inv: \t\t\t\t Inv cannot exceed Max. \n\n";

            } else if(productInvField.getText().compareToIgnoreCase(minField.getText()) < 0) {
                    errorMessage += "Inv: \t\t\t\t Inv cannot deceed Min. \n\n";  
        }

        if(productCostField.getText().isEmpty() || !productCostField.getText().matches("\\d+\\.\\d+\\d+")) {
            errorMessage += "Price/Cost: \t\t No valid cost figures!\n"
                        + "\t\t\t\t Only numbers are allowed. \n\n";
        }

        if(maxField.getText().isEmpty() || !maxField.getText().matches("\\d+")) {
                errorMessage += "Max: \t\t\t No valid maximum!\n"
                        + "\t\t\t\t Only numbers are allowed. \n\n";

            } else if(maxField.getText().compareToIgnoreCase(minField.getText()) < 0) {
                errorMessage += "Max: \t\t\t Max may not deceed Min. \n\n";                        
        }

        if(minField.getText().isEmpty() || !minField.getText().matches("\\d+")) {
                errorMessage += "Min: \t\t\t No valid minimum!\n"
                        + "\t\t\t\t Only numbers are allowed. \n\n";

            } else if(minField.getText().compareToIgnoreCase(maxField.getText()) > 0) {
                errorMessage += "Min: \t\t\t Min may not exceed Max. \n\n";                        
        }

        if(partTableAdd.getItems().isEmpty()) {
            errorMessage += "Imported Parts: \t There are currently no parts imported. \n"
                    + "\t\t\t\t There must be parts imported to select\n"
                    + "\t\t\t\t for inclusion in a new product!\n\n";
        }

        if(partTableDel.getItems().isEmpty()) {
            errorMessage += "Product Parts: \t\t There are currently no parts to include. \n"
                    + "\t\t\t\t There must be parts selected to\n"
                    + "\t\t\t\t for inclusion to create a new product!\n\n";
        }

        if(errorMessage.length() == 0) {
            return true;
        } else {
            // Show the error message
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.initOwner(dialogueStage);
            alert.setTitle("Empty or Invalid Fields");
            alert.setHeaderText("Please correct the empty or invalid fields");
            alert.setContentText(errorMessage);

            alert.show();

            return false;
        }
    }
    //------------------Working code, **** DO NOT DELETE **** -----------------------------------------------

   @FXML
    public void searchImportedParts() {

        String searchItem = searchFieldModProds.getText();

        FilteredList<Part> searchPartResults = searchPartsList(searchItem);
        SortedList<Part> sortedParts = new SortedList<>(searchPartResults);
        sortedParts.comparatorProperty().bind(partTableAdd.comparatorProperty());
        partTableAdd.setItems(sortedParts);

    }

    public FilteredList<Part> searchPartsList (String s) {
        return Inventory.getAllParts().filtered(p -> p.getPartName().toLowerCase().contains(s.toLowerCase()));
    }

    /**
     * Called when the user clicks on the delete button.
     */
    @FXML//------------------Working code, **** DO NOT DELETE **** -----------------------------------------------
    private void handleDelete(ActionEvent e) {                                                                     

        Part selectedPart;
        selectedPart = partTableDel.getSelectionModel().getSelectedItem();

        if(selectedPart != null) {                                                                                 
                // Confirm deletion                                                                                    
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);                                                 
                alert.setTitle("Confirm Deletion");                                                                    
                alert.setHeaderText("Deleting...");                                                                    
                alert.setContentText("Are you sure you want to delete the part: " + "\'" + selectedPart.getPartName() + "\'" + "?"); //
                alert.showAndWait()                                                                                    
                        .filter(response -> response  ==  ButtonType.OK)                                                 
                        .ifPresent(response -> Inventory.getDelParts().remove(selectedPart));                             

                // Update productTableMain                                                                                
                partTableDel.setItems(Inventory.getDelParts());

            }else {                                                          //                                       //
                // Nothing selected...                                                                                 
                Alert alert = new Alert(Alert.AlertType.WARNING);                                                      
                alert.setTitle("No selection");                                                                        
                alert.setHeaderText("No product selected");                                                               
                alert.setContentText("Please select a product in the table.");                                            
                alert.showAndWait();
            }                                                                                                          
    }   //------------------Working code, **** DO NOT DELETE **** -------------------------------------------------         
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Rectangle?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jbernsd_IMS.View.ModifyProductController">
   <children>
      <Rectangle arcHeight="20.0" arcWidth="20.0" fill="TRANSPARENT" height="480.0" layoutX="10.0" layoutY="10.0" stroke="#979797" strokeType="OUTSIDE" strokeWidth="2.0" width="780.0" />
      <TableView fx:id="partTableAdd" layoutX="386.0" layoutY="103.0" prefHeight="108.0" prefWidth="349.0">
        <columns>
          <TableColumn prefWidth="75.0" text="Part ID:" />
          <TableColumn prefWidth="75.0" text="Part Name" />
            <TableColumn prefWidth="102.0" text="Inventory Level" />
            <TableColumn prefWidth="96.0" text="Price per Unit" />
        </columns>
      </TableView>
      <TableView fx:id="partTableDel" layoutX="386.0" layoutY="290.0" prefHeight="108.0" prefWidth="349.0">
         <columns>
            <TableColumn prefWidth="75.0" text="Part ID:" />
            <TableColumn prefWidth="75.0" text="Part Name" />
            <TableColumn prefWidth="102.0" text="Inventory Level" />
            <TableColumn prefWidth="96.0" text="Price per Unit" />
         </columns>
      </TableView>
      <Button fx:id="addBtn" layoutX="665.0" layoutY="221.0" mnemonicParsing="false" onAction="#handleAdd" prefHeight="30.0" prefWidth="70.0" text="Add">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </Button>
      <Button fx:id="delBtn" layoutX="665.0" layoutY="408.0" mnemonicParsing="false" onAction="#handleDelete" prefHeight="30.0" prefWidth="70.0" text="Delete">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font></Button>
      <Button fx:id="cancelBtn" layoutX="466.0" layoutY="446.0" mnemonicParsing="false" onAction="#handleCancel" prefHeight="30.0" prefWidth="70.0" text="Cancel">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </Button>
      <Button fx:id="saveBtn" layoutX="376.0" layoutY="446.0" mnemonicParsing="false" onAction="#handleSave" prefHeight="30.0" prefWidth="70.0" text="Save">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </Button>
      <TextField fx:id="searchFieldModProds" layoutX="536.0" layoutY="63.0" prefHeight="25.0" prefWidth="199.0">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Button fx:id="searchBtn" layoutX="456.0" layoutY="61.0" mnemonicParsing="false" onAction="#searchImportedParts" prefHeight="30.0" prefWidth="70.0" text="Search">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </Button>
      <TextField fx:id="idField" layoutX="98.0" layoutY="132.0" prefHeight="44.0" prefWidth="149.0" promptText="Auto Gen - Disabled">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelIdModProd" layoutX="29.0" layoutY="144.0" text="ID">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="nameField" layoutX="98.0" layoutY="182.0" prefHeight="44.0" prefWidth="149.0" promptText="Product Name">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelNameModProds" layoutX="29.0" layoutY="194.0" text="Name">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="invField" layoutX="98.0" layoutY="232.0" prefHeight="44.0" prefWidth="70.0" promptText="Inv">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelInvModProds" layoutX="29.0" layoutY="244.0" text="Inv">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="priceField" layoutX="98.0" layoutY="282.0" prefHeight="44.0" prefWidth="70.0" promptText="Price">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelPriceModProds" layoutX="29.0" layoutY="294.0" text="Price">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="maxField" layoutX="98.0" layoutY="332.0" prefHeight="44.0" prefWidth="70.0" promptText="Max">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelMaxModProds" layoutX="29.0" layoutY="344.0" text="Max">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="minField" layoutX="228.0" layoutY="332.0" prefHeight="44.0" prefWidth="70.0" promptText="Min">
         <font>
            <Font name="Calibri Italic" size="12.0" />
         </font>
      </TextField>
      <Label fx:id="labelMinModProds" layoutX="185.0" layoutY="344.0" text="Min">
         <font>
            <Font name="Calibri Italic" size="14.0" />
         </font>
      </Label>
      <Label fx:id="labelModifyPart" layoutX="34.0" layoutY="53.0" text="Modify Products">
         <font>
            <Font name="Calibri Bold Italic" size="24.0" />
         </font>
      </Label>
   </children>
</AnchorPane>