简体   繁体   中英

Pulling null data from text fields. Table is populated, but can't retrieve objects. Java / JavaFX

I have two tables on the main screen that I'm working with.

The Parts table and The Products table. Products are comprised of Parts. The table functionality for the Parts table (searching, selecting, etc) all works fine. When a new product is created and added to the table, it seems to be there. However, when I try to retrieve data for modification, by way of initializing the Product fields with data, I get a NPE. When using the search functionality, identical to the Part table, the search functionality does not find the part.

Listed are the files in question...

MainScreenController.java

/**
 * 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;
        }
    }
}

MainScreen.fxml

<?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>

I resolved my own issue. The issue ultimately lay in my .fxml file, "ModifyProduct". There were no fx:id equivalents to correspond with the named text fields I was trying to populate. So even though I had instantiated the fields, and most of my logic was working correctly, due to the lack of identifiable names, the .fxml simply couldn't correlate the data to the fields. Once I resolved the fx:id names in my .fxml file, the data flowed correctly...

ModifyProductController.java

/*
 * 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 **** -------------------------------------------------         
}

ModifyProduct.fxml

<?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>

Just gotta remember to match names and other identifiers, and make sure that everything points to everything else that it's supposed to. Thanks everyone for your help!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM