zoukankan      html  css  js  c++  java
  • HW3 纠结的心得

    改好的controller

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.File;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.List;
    
    import hw3.Female;
    import hw3.Male;
    import hw3.NutriProfiler;
    import hw3.Model;
    import hw3.Product;
    import hw3.InvalidProfileException;
    import hw3.NutriByte;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    
    public class Controller {
    
        //clear up all data from the previous user interaction
        class NewMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //initialize the panel first
                NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
                NutriByte.view.initializePrompts();
    
                //clear the charts
                NutriByte.view.productsComboBox.getItems().clear();
                NutriByte.view.nutriChart.clearChart();
                NutriByte.view.recommendedNutrientsTableView.getItems().clear();
    
                //clear the TableView when it is not null
                if (NutriByte.person != null) 
                    if (!NutriByte.person.recommendedNutrientsList.isEmpty())
                        NutriByte.view.productNutrientsTableView.getItems().clear();
                NutriByte.view.dietProductsTableView.getItems().clear();
    
                //clear the text field
                NutriByte.view.productSearchTextField.clear();
                NutriByte.view.nutrientSearchTextField.clear();
                NutriByte.view.ingredientSearchTextField.clear();
                NutriByte.view.dietServingSizeTextField.clear();
                NutriByte.view.dietHouseholdSizeTextField.clear();
                NutriByte.view.productIngredientsTextArea.clear();
    
                //format the servingSizeLabel and the householdSizeLabel
                DecimalFormat decimalFormat = new DecimalFormat("0.00");
                NutriByte.view.servingSizeLabel.setText(decimalFormat.format(0));
                NutriByte.view.householdSizeLabel.setText(decimalFormat.format(0));
    
                //clear the person and the nutrient information
                if (NutriByte.person != null)
                    if (!NutriByte.person.recommendedNutrientsList.isEmpty()) {
                        //clear the ComboBox
                        NutriByte.view.genderComboBox.setPromptText("");
                        NutriByte.view.physicalActivityComboBox.setPromptText("");
    
                        //clear the former list
                        NutriByte.person.recommendedNutrientsList.clear();
                        NutriByte.person.dietProductsList.clear();
    
                        //set the items onto the TableView
                        NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                        NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                        NutriByte.view.productNutrientsTableView.getItems().clear();
                    }
            }
        }
    
        //open up a new menu
        class OpenMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //open up a new FileChooser
                FileChooser fc = new FileChooser();
                fc.setTitle("Select file");
                fc.setInitialDirectory(new File("profiles/"));
    
                //add all the file's extensions
                fc.getExtensionFilters().addAll(
                        new ExtensionFilter("CSV Files", "*.csv"),
                        new ExtensionFilter("XML Files", "*.xml"),
                        new ExtensionFilter("All Files", "*.*"));
    
                //open up a new file
                File file = fc.showOpenDialog(new Stage());
    
                //only open when file is not null
                if (file == null) {
                    return;
                }else if (file != null){
    
                    //judge whether a file can be opened or not
                    boolean canOpen = false;
                    canOpen = NutriByte.model.readProfiles(file.getPath());
    
                    //if not, throw exception
                    if (!canOpen) {
                        try {
                            throw (new InvalidProfileException("Could not read profile data"));
                        } catch (InvalidProfileException e) {
                            //when the exception is caught, clear the interface and set the person to null
                            NutriByte.view.productsComboBox.getItems().clear();
                            NutriByte.view.nutriChart.clearChart();
                            NutriByte.view.newNutriProfileMenuItem.fire();
                            NutriByte.person = null;
                        }
                    }
                }
    
                //set up person's information
                if (NutriByte.person != null) {
                    NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
    
                    //format the input 
                    DecimalFormat decimalFormat = new DecimalFormat("0.00");
                    NutriByte.view.ageTextField.setText(decimalFormat.format(NutriByte.person.age));
                    NutriByte.view.weightTextField.setText(decimalFormat.format(NutriByte.person.weight) + "");
                    NutriByte.view.heightTextField.setText(decimalFormat.format(NutriByte.person.height) + "");
                    String activityLevelString = null;
    
                    //judge the activityLevelString
                    if(NutriByte.person.physicalActivityLevel == 1.0f) {
                        activityLevelString = "Sedentary";}
                    if(NutriByte.person.physicalActivityLevel == 1.1f) {
                        activityLevelString = "Low active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.25f) {
                        activityLevelString = "Active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.48f) {
                        activityLevelString = "Very active";   
                    }
    
                    //select the person's information
                    NutriByte.view.physicalActivityComboBox.getSelectionModel().select(activityLevelString);
                    NutriByte.view.ingredientsToWatchTextArea.setText(NutriByte.person.ingredientsToWatch);
    
                    //create a new person and its profile
                    if (NutriByte.person instanceof Male)
                        NutriByte.view.genderComboBox.setValue("Male");
                    if (NutriByte.person instanceof Female)
                        NutriByte.view.genderComboBox.setValue("Female");
                    NutriProfiler.createNutriProfile(NutriByte.person);
    
                    // populate the recommendedNutrientsTableView
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
    
                    // populate the dietProductsTableView
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
    
                    // populate the productCombobox
                    ObservableList<Product> temp = FXCollections.observableArrayList();
                    for (int i = 0; i < NutriByte.person.dietProductsList.size(); i++) {
                        Product product = NutriByte.person.dietProductsList.get(i);
                        String ndbNumber = product.getNdbNumber();
                        temp.add(Model.productsMap.get(ndbNumber));
                    }
    
                    //set up the productsComboBox
                    NutriByte.view.productsComboBox.setItems(temp);
                    NutriByte.view.productsComboBox.getSelectionModel().selectFirst();
    
                    //set search results
                    NutriByte.view.searchResultSizeLabel.setText(NutriByte.person.dietProductsList.size() + " products found");
    
                    //update the nutriChart
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.nutriChart.updateChart();
                }
            }
        }
    
        class AboutMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                Alert alert = new Alert(AlertType.INFORMATION);
                alert.setTitle("About");
                alert.setHeaderText("NutriByte");
                alert.setContentText(
                        "Version 3.0 
    Release 1.0
    Copyleft Java Nerds
    This software is designed purely for educational purposes.
    No commercial use intended");
                Image image = new Image(getClass().getClassLoader().getResource(NutriByte.NUTRIBYTE_IMAGE_FILE).toString());
                ImageView imageView = new ImageView();
                imageView.setImage(image);
                imageView.setFitWidth(300);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                alert.setGraphic(imageView);
                alert.showAndWait();
            }
        }
    
        //close the menu
        class CloseMenuButtonHandler implements EventHandler<ActionEvent>{
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                NutriByte.view.root.setCenter(NutriByte.view.setupWelcomeScene());
            }
        }
    
        //save the user profile
        class SaveButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
    
                //can't save when missing gender information
                if(NutriByte.view.genderComboBox.getSelectionModel().getSelectedIndex()<0){
                    new InvalidProfileException("Missing Gender Information");
                }
    
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    //initialize the 3 variables
                    float age = 0;
                    float weight = 0;
                    float height = 0;
    
                    String ageString = NutriByte.view.ageTextField.getText().trim();
    
                    //ageString empty exception
                    if (ageString == null || ageString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            return;
                        }
    
                    //ageString below zero exception and not number exception
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
    
                    //weightString empty exception
                    if (weightString == null || weightString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            return;
                        }
    
                    //weightString below zero exception and not number exception
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
                            return;
                        }
                    //heightString below zero exception and not number exception
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
    
                    //open up a FileChooser and write to its path
                    FileChooser fc = new FileChooser();
                    fc.setTitle("Save file");
                    fc.setInitialDirectory(new File("profiles/"));
                    fc.getExtensionFilters().addAll(
                            new ExtensionFilter("CSV Files", "*.csv"),
                            new ExtensionFilter("XML Files", "*.xml"),
                            new ExtensionFilter("All Files", "*.*"));
    
                    File file = fc.showSaveDialog(new Stage());
                    if (file != null)
                        try {
                            String path = file.getPath();
                            NutriByte.model.writeProfile(path);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                }
            }
        }
    
        //Search for products
        class SearchButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //clear the former searchResultsList first 
                NutriByte.model.searchResultsList.clear();
    
                //initialize the variables
                List<String> productList = new ArrayList<String>();
                List<String> nutrientList = new ArrayList<String>();
                List<String> ingredientList = new ArrayList<String>();
                String productToSearch = NutriByte.view.productSearchTextField.getText().toLowerCase();
                String nutrientToSearch = NutriByte.view.nutrientSearchTextField.getText().toLowerCase();
                String ingredientToSearch = NutriByte.view.ingredientSearchTextField.getText().toLowerCase();
                boolean productToSearchIsEmpty = (productToSearch.isEmpty());
                boolean nutrientToSearchIsEmpty = (nutrientToSearch.isEmpty());
                boolean ingredientToSearchIsEmpty = (ingredientToSearch.isEmpty());
                String nutrientCode = null;
    
                //get the nutrientCode if qualified
                for (String key : Model.nutrientsMap.keySet()) {
                    Nutrient nutrient =  Model.nutrientsMap.get(key);
                    if (nutrient.getNutrientName().toLowerCase().contains(nutrientToSearch))
                        nutrientCode = nutrient.getNutrientCode();
                }
    
                //if productToSearchIsEmpty, add all the products into the product list
                if (productToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        productList.add(ndbnumber);
                } 
    
                //else search for the certain product
                if (!productToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductName().toLowerCase().contains(productToSearch))
                            productList.add(product.getNdbNumber());
                    } 
                }
    
    
                //if nutrientToSearchIsEmpty, add all the products into the product list
                if (nutrientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        nutrientList.add(ndbnumber);
                } 
    
                //else search for the certain product
                if (!nutrientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductNutrients().containsKey(nutrientCode))
                            nutrientList.add(product.getNdbNumber());
                    }
                }
    
                //if ingredientToSearchIsEmpty, add all the products into the product list
                if (ingredientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        ingredientList.add(ndbnumber);
                }
    
                //else search for the certain product
                if (!ingredientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getIngredients().toLowerCase().contains(ingredientToSearch))
                            ingredientList.add(product.getNdbNumber());
                    } 
                }
    
                //find products that exist in 3 lists
                boolean containsInNutrientList = false;
                boolean containsInIngredientList = false;
                List<String> ndbToAdd = new ArrayList<>();
                for (int i = 0; i < productList.size(); i++) {
                    String ndb = productList.get(i);
                    if (nutrientList.contains(ndb)) containsInNutrientList = true;
                    if (ingredientList.contains(ndb)) containsInIngredientList = true;
                    if (containsInNutrientList && containsInIngredientList)
                        ndbToAdd.add(ndb);
                    containsInNutrientList = false;
                    containsInIngredientList = false;
                }
    
                //add the qualified products to the result
                if (!ndbToAdd.isEmpty())
                    for (int i = 0; i < ndbToAdd.size(); i++) {
                        String ndbNumber = ndbToAdd.get(i);
                        Product product = Model.productsMap.get(ndbNumber);
                        NutriByte.model.searchResultsList.add(product);
                    }
    
                //show the results on the productsComboBox
                NutriByte.view.searchResultSizeLabel.setText(NutriByte.model.searchResultsList.size() + " products found");
                NutriByte.view.productsComboBox.setItems(NutriByte.model.searchResultsList);
                NutriByte.view.productsComboBox.getSelectionModel().selectFirst();    
            }
        }
    
        //clear the interface
        class ClearButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
    
                //clear the result list
                NutriByte.view.productsComboBox.getSelectionModel().clearSelection();
                NutriByte.view.productNutrientsTableView.setItems(null);
                NutriByte.model.searchResultsList.clear();
    
                //clear the labels
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.dietServingUomLabel.setText("");
                NutriByte.view.dietHouseholdUomLabel.setText("");
                NutriByte.view.searchResultSizeLabel.setText("");
    
                //clear the TextField
                NutriByte.view.productIngredientsTextArea.clear();
                NutriByte.view.householdServingUom.setText("");
                NutriByte.view.servingUom.setText("");
                NutriByte.view.productSearchTextField.clear();
                NutriByte.view.ingredientSearchTextField.clear();
                NutriByte.view.nutrientSearchTextField.clear();
            }
        }
    
        //add diet to the profile
        class AddDietButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //get the two input diet size
                String inputServingSizeString = NutriByte.view.dietServingSizeTextField.getText().trim();
                String inputHouseholdSizeString = NutriByte.view.dietHouseholdSizeTextField.getText().trim();
    
                //select a product from the productsComboBox
                Product selectedProduct = NutriByte.view.productsComboBox.getValue();
    
                //new up a product
                String ndbNumber = selectedProduct.getNdbNumber();
                String productName = selectedProduct.getProductName();
                String manuf = selectedProduct.getManufacturer();
                String ingredients = selectedProduct.getIngredients();
                Product outputProduct = new Product(ndbNumber, productName, manuf, ingredients);
    
                //define the two output diet size
                float outputServingSize = 0;
                float outputHouseholdSize = 0;
                boolean inputServingSizeStringIsNull = (inputServingSizeString.equals(""));
                boolean inputHouseholdSizeStringIsNull = (inputHouseholdSizeString.equals(""));
    
                //when the inputServingSizeStringIsNull and inputHouseholdSizeStringIsNull
                if (inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) {
                    outputServingSize = selectedProduct.getServingSize();
                    outputHouseholdSize = selectedProduct.getHouseholdSize();
    
                    //handle the invalid UOM problem
                    if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                    if (selectedProduct.getServingUom().equals("none")) outputHouseholdSize = selectedProduct.getHouseholdSize();
                }
    
                //when the inputServingSizeStringIsNull and !inputHouseholdSizeStringIsNull
                if (inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull) {
                    try {
                        outputHouseholdSize = Float.parseFloat(inputHouseholdSizeString);
                        outputServingSize = outputHouseholdSize / selectedProduct.getHouseholdSize()
                                * selectedProduct.getServingSize();
    
                        //handle the invalid UOM problem
                        if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                        if (selectedProduct.getServingUom().equals("none")) outputHouseholdSize = selectedProduct.getHouseholdSize();
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietHouseholdSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
    
                //when both the two sizes are null or only input serving size is not null
                if ((!inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) || 
                        (!inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull)) {
                    try {
                        outputServingSize = Float.parseFloat(inputServingSizeString);
                        outputHouseholdSize = outputServingSize / selectedProduct.getServingSize()
                                * selectedProduct.getHouseholdSize();
                        //handle the invalid UOM problem
                        if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                        if (selectedProduct.getServingUom().equals("none")) outputHouseholdSize = selectedProduct.getHouseholdSize();
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
    
                //set the outputProduct's variables
                outputProduct.setHouseholdSize(outputHouseholdSize);
                outputProduct.setServingSize(outputServingSize);
                outputProduct.setHouseholdUom(selectedProduct.getHouseholdUom());
                outputProduct.setServingUom(selectedProduct.getServingUom());
                for(Product.ProductNutrient pn : selectedProduct.getProductNutrients().values()) {
                    outputProduct.setProductNutrients(pn);
                }
    
                //when person is not null, create a profile
                if (NutriByte.person != null) {
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.person.dietProductsList.add(outputProduct);
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    NutriByte.view.nutriChart.updateChart();
                }
    
                //when the person is null, just add a product
                if(NutriByte.person == null) {            
                    NutriByte.view.dietProductsTableView.getItems().add(outputProduct);
                    return;
                }
            }
        }
    
        //remove diet from the interface
        class RemoveDietButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //get index of the product
                int index = NutriByte.view.dietProductsTableView.getSelectionModel().getSelectedIndex(); 
    
                //if person is null, just remove the product
                if (NutriByte.person == null) {
                    NutriByte.view.dietProductsTableView.getItems().remove(index);
                } 
    
                //if person is not null
                //remove the product from the person's list and update the interface
                if (NutriByte.person != null){
                    if (NutriByte.person.dietProductsList != null)
                    NutriByte.person.dietProductsList.remove(index);
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    NutriByte.view.nutriChart.updateChart();
                    if (NutriByte.person.dietProductsList.size() == 0) {
                        NutriByte.view.nutriChart.clearChart();
                    }
                }
            }
        }
    
        //recommend nutrients for people
        class RecommendNutrientsButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //judge genderComboBox at first 
                if(NutriByte.view.genderComboBox.getSelectionModel().getSelectedIndex() < 0){
                    new InvalidProfileException("Missing Gender Information");
                }
    
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    float age = 0;
                    float weight = 0;
                    float height = 0;
                    String gender = NutriByte.view.genderComboBox.getValue();
                    String ageString = NutriByte.view.ageTextField.getText().trim();
    
                    //ageString empty exception
                    if (ageString == null || ageString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            return;
                        }
    
                    //ageString below zero exception and not number exception
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } 
                        catch (InvalidProfileException e) {
                            return;
                        }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
                    // weight empty exception
                    if (weightString == null || weightString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            return;
                        }
    
                    //weightString below zero exception and not number exception
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString == null || heightString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
    
                            return;
                        }
    
                    //heightString below zero exception and not number exception
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
    
                    //get the ingredientsToWatch
                    String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
    
                    //define the default activityLevelString
                    String activityLevelString = NutriByte.view.physicalActivityComboBox.getValue();
                    if (activityLevelString == null || activityLevelString.trim().length() == 0)
                        activityLevelString = "Sedentary";
                    float physicalActivityLevel = 1.0f;
                    if(activityLevelString.equals("Sedentary")) {
                        physicalActivityLevel = 1.0f;}
                    if(activityLevelString.equals("Low active")) {
                        physicalActivityLevel = 1.1f;   
                    }
                    if(activityLevelString.equals("Active")) {
                        physicalActivityLevel = 1.25f;   
                    }
                    if(activityLevelString.equals("Very active")) {
                        physicalActivityLevel = 1.48f;   
                    }
    
                    //create new profile for male or female
                    if (gender.toLowerCase().equals("male"))
                        NutriByte.person = new Male(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    if (gender.toLowerCase().equals("female"))
                        NutriByte.person = new Female(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                }
            }
        }
    
        //add ProductsComboBoxListener
        class ProductsComboBoxListener implements ChangeListener<Product> {
            @Override
            public void changed(ObservableValue<? extends Product> observable, Product oldValue, Product newValue) {
                {
                    if (NutriByte.view.productsComboBox.getSelectionModel().getSelectedIndex() >= 0) {
                        //get ProductNutrient for the selectedProduct
                        Product choosenProduct = NutriByte.view.productsComboBox.getValue();
                        ObservableList<Product.ProductNutrient> productNutrientList = FXCollections.observableArrayList();
                        for (Product.ProductNutrient nutrient : choosenProduct.getProductNutrients().values()) {
                            productNutrientList.add(nutrient);
                        }
    
                        //display the diet sizes
                        NutriByte.view.servingSizeLabel.setText(String.format("%.2f", choosenProduct.getServingSize()) + " "
                                + choosenProduct.getServingUom());
                        NutriByte.view.householdSizeLabel.setText(String.format("%.2f", choosenProduct.getHouseholdSize())
                                + " " + choosenProduct.getHouseholdUom());
    
                        //display the product's UOM
                        NutriByte.view.householdServingUom.setText(choosenProduct.getServingUom());
                        NutriByte.view.servingUom.setText(choosenProduct.getServingUom());
                        NutriByte.view.dietServingUomLabel.setText(choosenProduct.getServingUom());
                        NutriByte.view.dietHouseholdUomLabel.setText(choosenProduct.getHouseholdUom());
    
                        //display the ingredients and nutrients
                        NutriByte.view.productNutrientsTableView.setItems(productNutrientList);
                        NutriByte.view.productIngredientsTextArea
                        .setText("Product ingredients: " + choosenProduct.getIngredients());
                    }
                } 
            }
        }
    }
    View Code

    CSVfiler错了吗

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.List;
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    import hw3.Model;
    import hw3.Female;
    import hw3.Male;
    import hw3.NutriByte;
    import hw3.Product;
    import hw3.Person;
    import hw3.InvalidProfileException;
    
    public class CSVFiler extends DataFiler{
    
        @Override
        public boolean readFile(String filename) {
            //store the infomation from csvParser to stringbuilder
            CSVFormat csvFormat = CSVFormat.DEFAULT;
            try {
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat);
                List<CSVRecord> list = csvParser.getRecords();
                StringBuilder sb = new StringBuilder();
    
                //parse in each line and each word
                for(int i = 0; i < list.size(); i++)
                {
                    for (int j = 0; j < list.get(i).size(); j++) {
                        sb.append(list.get(i).get(j));
                        sb.append(",");
                    }
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                    sb.append("
    ");
                }
    
                //store the stringbuilder's content into the string array
                String[] csvInfo = sb.toString().split("
    ");
    
                //new up a person using the first row, return false when faile
                Person p = validatePersonData(csvInfo[0]);    
                if(p == null) {
                    return false;
                }else {
                    NutriByte.person = p;
                }
    
                //assign the products information to the people by calling validateProductData
                for (int i = 1; i < csvInfo.length; i++)
                {
                    try{
                        Product csvProduct = validateProductData(csvInfo[i]);
                        NutriByte.person.dietProductsList.add(csvProduct);
                    }catch(InvalidProfileException e) {
                        continue;
                    }    
                }
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
                return false;
            } catch (IOException e1) {
                e1.printStackTrace();
                return false;
            } catch(InvalidProfileException e1)
            {
                return false;
            }
    
            //return true is a person is created
            if(NutriByte.person != null) return true;
            return false;
        }
    
        @Override
        public void writeFile(String filename) {
            //new up a BufferedWriter
            try(BufferedWriter bufferwriter = new BufferedWriter(new FileWriter(filename));){
                if(NutriByte.person instanceof Male) {
                    bufferwriter.write("Male,");
                }else if(NutriByte.person instanceof Female) {
                    bufferwriter.write("Female,");
                }
    
                //write the person's information
                bufferwriter.write(String.format("%s,%s,%s,%s,%s%n", NutriByte.person.age, NutriByte.person.weight, 
                        NutriByte.person.height, NutriByte.person.physicalActivityLevel, 
                        NutriByte.person.ingredientsToWatch));
    
                //write the product's information
                for(int i =0; i< NutriByte.person.dietProductsList.size();i++) {
                    Product p = NutriByte.person.dietProductsList.get(i);
                    bufferwriter.write(String.format("%s,%s,%s%n", p.getNdbNumber(), p.getServingSize(), p.getHouseholdSize()));
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            }    
        }
    
        //validate a data string
        Person validatePersonData(String data)
        {
            String[]wordsInData = data.split(",");
    
            //validate gender
            if (wordsInData[0] == null || wordsInData[0].length() == 0) 
                throw (new InvalidProfileException("The profile must have gender: Female or Male as first word"));
    
            if(!wordsInData[0].trim().equals("Male") && !wordsInData[0].trim().equals("Female")) 
                throw (new InvalidProfileException("Gender invalid input"));
    
            //validate age
            try{
                Float.valueOf(wordsInData[1].trim());
            }catch(NumberFormatException e1) {
                throw (new InvalidProfileException("Invalid data for Age:" + wordsInData[1] + "
    Age must be a number"));
            }
    
            //validate weight
            try{
                Float.valueOf(wordsInData[2].trim());
            }catch(NumberFormatException e1) {
                throw (new InvalidProfileException("Invalid data for Weight:" + wordsInData[2] + "
    Weight must be a number"));
            }
    
            //validate height
            try{
                Float.valueOf(wordsInData[3].trim());
            }catch(NumberFormatException e1) {
                throw (new InvalidProfileException("Invalid data for Height:" + wordsInData[3] + "
    Height must be a number"));
            }
    
            //validate PhysicalActivityLevel
            if(Float.parseFloat(wordsInData[4].trim()) != 1.0f && 
                    Float.parseFloat(wordsInData[4].trim()) != 1.1f &&
                    Float.parseFloat(wordsInData[4].trim()) != 1.25f &&
                    Float.parseFloat(wordsInData[4].trim()) != 1.48f)
                throw (new InvalidProfileException("Invalid data for PhysicalActivityLevel:" + wordsInData[4] + "
    Must be : 1.0, 1.1, 1.25 or 1.48"));
    
            //get ingredientsToWatch and create a person
            String gender = wordsInData[0].trim();
            float age = Float.parseFloat(wordsInData[1]);
            float weight = Float.parseFloat(wordsInData[2]);
            float height = Float.parseFloat(wordsInData[3]);
            float physicalActivityLevel = Float.parseFloat(wordsInData[4]);
            String ingredientsToWatch = "";
    
            for(int j= 5; j < wordsInData.length;j++) {
                ingredientsToWatch += wordsInData[j] + ",";
            }
            if (ingredientsToWatch.length() > 1)
                ingredientsToWatch = ingredientsToWatch.substring(0, ingredientsToWatch.length()-1);
    
            //就改了个switch,别的没改
            switch(gender) {
            case "Male":
                return new Male(age, weight, height, physicalActivityLevel, ingredientsToWatch);
            case "Female":
                return new Female(age, weight, height, physicalActivityLevel, ingredientsToWatch);
            }
            return null;
        }
    
    
        Product validateProductData(String data) {
            String[] wordsInData = data.split(",");
            //validate ndbnumber
            if (!Model.productsMap.containsKey(wordsInData[0]))
                throw (new InvalidProfileException("No product found with this code: " + wordsInData[0]));
    
            //assign the former product's product number and product quantity to the latter product
            //throw exception when those information are invalid
            try {
                Float.parseFloat(wordsInData[1]);
                Product formerProduct = Model.productsMap.get(wordsInData[0]);
                //new up a product using former information
                Product latterProduct = new Product(formerProduct.getNdbNumber(),formerProduct.getProductName(),
                        formerProduct.getManufacturer(),formerProduct.getIngredients());
                //set new variables
                latterProduct.setServingSize(Float.parseFloat(wordsInData[1]));
                latterProduct.setServingUom(formerProduct.getServingUom());
                latterProduct.setHouseholdSize(Float.parseFloat(wordsInData[2]));
                latterProduct.setHouseholdUom(formerProduct.getHouseholdUom());
    
                //assign the ProductNutrient
                for(Product.ProductNutrient pn : formerProduct.getProductNutrients().values()) {
                    latterProduct.setProductNutrients(pn);
                }
    
                //return the latterProduct
                return latterProduct;
            }catch (ArrayIndexOutOfBoundsException e1) {
                throw (new InvalidProfileException("Cannot read: " + data + "
    The data must be - String, number, number - for ndb number,
    "+"serving size, household size"));
            }catch (NumberFormatException e1) {
                throw (new InvalidProfileException("Cannot read: " + data+ "
    The data must be - String, number, number - for ndb number,
    "+"serving size, household size"));
            }
        }
    }
    View Code

    自己改错顺序的红色nb

    //yuec2 Yue Cheng
    package hw3;
    
    import hw3.Controller;
    import hw3.Female;
    import hw3.Male;
    import hw3.Model;
    import hw3.NutriByte;
    import hw3.Nutrient;
    import hw3.Person;
    import hw3.Product;
    import hw3.View;
    
    import hw3.NutriProfiler;
    import hw3.RecommendedNutrient;
    import hw3.Product.ProductNutrient;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.binding.ObjectBinding;
    import javafx.beans.binding.StringBinding;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.value.ObservableValue;
    
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.TableColumn.CellDataFeatures;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.Background;
    import javafx.scene.layout.BackgroundFill;
    import javafx.scene.layout.CornerRadii;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class NutriByte extends Application{
        static Model model = new Model();   //made static to make accessible in the controller
        static View view = new View();  //made static to make accessible in the controller
        static Person person;    //made static to make accessible in the controller
    
    
        Controller controller = new Controller(); //all event handlers 
    
        /**Uncomment the following three lines if you want to try out the full-size data files */
    //         static final String PRODUCT_FILE = "data/Products.csv";
    //         static final String NUTRIENT_FILE = "data/Nutrients.csv";
    //         static final String SERVING_SIZE_FILE = "data/ServingSize.csv";
    
        /**The following constants refer to the data files to be used for this application */
    
        static final String PRODUCT_FILE = "data/Nutri2Products.csv";
        static final String NUTRIENT_FILE = "data/Nutri2Nutrients.csv";
        static final String SERVING_SIZE_FILE = "data/Nutri2ServingSize.csv";
    
        static final String NUTRIBYTE_IMAGE_FILE = "NutriByteLogo.png"; //Refers to the file holding NutriByte logo image 
        static final String NUTRIBYTE_PROFILE_PATH = "profiles";  //folder that has profile data files
        static final int NUTRIBYTE_SCREEN_WIDTH = 1015;
        static final int NUTRIBYTE_SCREEN_HEIGHT = 675;
    
        @Override
        public void start(Stage stage) throws Exception {
            model.readProducts(PRODUCT_FILE);
            model.readNutrients(NUTRIENT_FILE);
            model.readServingSizes(SERVING_SIZE_FILE );
            view.setupMenus();
            view.setupNutriTrackerGrid();
            view.root.setCenter(view.setupWelcomeScene());
            Background b = new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY));
            view.root.setBackground(b);
            Scene scene = new Scene (view.root, NUTRIBYTE_SCREEN_WIDTH, NUTRIBYTE_SCREEN_HEIGHT);
            view.root.requestFocus();  //this keeps focus on entire window and allows the textfield-prompt to be visible
            setupBindings();
            stage.setTitle("NutriByte 3.0");
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        void setupBindings() {
            view.newNutriProfileMenuItem.setOnAction(controller.new NewMenuItemHandler());
            view.openNutriProfileMenuItem.setOnAction(controller.new OpenMenuItemHandler());
            view.exitNutriProfileMenuItem.setOnAction(event -> Platform.exit());
            view.aboutMenuItem.setOnAction(controller.new AboutMenuItemHandler());
    
            view.recommendedNutrientNameColumn.setCellValueFactory(recommendedNutrientNameCallback);
            view.recommendedNutrientQuantityColumn.setCellValueFactory(recommendedNutrientQuantityCallback);
            view.recommendedNutrientUomColumn.setCellValueFactory(recommendedNutrientUomCallback);
    
            //set the call back on action
            view.productsComboBox.valueProperty().addListener(controller.new ProductsComboBoxListener());
            view.productNutrientNameColumn.setCellValueFactory(productNutrientNameCallback);
            view.productNutrientQuantityColumn.setCellValueFactory(productNutrientQuantityCallback);
            view.productNutrientUomColumn.setCellValueFactory(productNutrientUomCallback);
    
            //set the menu item on action
            view.saveNutriProfileMenuItem.setOnAction(controller.new SaveButtonHandler());
            view.closeNutriProfileMenuItem.setOnAction(controller.new CloseMenuButtonHandler());
    
            //set the button on action
            view.createProfileButton.setOnAction(controller.new RecommendNutrientsButtonHandler());
            view.searchButton.setOnAction(controller.new SearchButtonHandler());
            view.addDietButton.setOnAction(controller.new AddDietButtonHandler());
            view.removeDietButton.setOnAction(controller.new RemoveDietButtonHandler());
            view.clearButton.setOnAction(controller.new ClearButtonHandler());
    
            //add listener to recommendedNutrient binding 
            recommendedNutrientBinding.addListener((observable, oldVal, newVal)->{
                //clear the former fields
                view.productIngredientsTextArea.clear();
                if (NutriByte.person != null) 
                    if (!NutriByte.person.recommendedNutrientsList.isEmpty())
                view.productNutrientsTableView.getItems().clear();
    
                //when newVal is complete
                if(newVal != null)
                {
                    //when a person is null, assign newVal to it as soon as newVal is complete
                    if(person == null)  {
                        //calculate the information
                        person = newVal; 
                        newVal.dietNutrientsMap=person.dietNutrientsMap;
                        newVal.dietProductsList=person.dietProductsList;
    
                        //populate the chart
                        view.dietProductsTableView.getItems().clear();
                        view.nutriChart.clearChart();
                        NutriProfiler.createNutriProfile(newVal);
                    }
    
                    //when a person is not null 
                    else{
                        //calculate the information
                        newVal.dietNutrientsMap=person.dietNutrientsMap;
                        newVal.dietProductsList=person.dietProductsList;
    
                        //populate the chart
                        view.dietProductsTableView.getItems().clear();
                        view.nutriChart.clearChart();
                        NutriProfiler.createNutriProfile(newVal);     
                    }
    
                    //assign the new value
                    person = newVal;
                    view.recommendedNutrientsTableView.setItems(person.recommendedNutrientsList);
                }
    
                //when newVal is not complete, clear the charts
                else {
                    person=null;
                    view.recommendedNutrientsTableView.getItems().clear();
                }
            });
    
            //set up servingSize Binding
            StringBinding dietServingBinding = new StringBinding() {
                {
                    super.bind(view.dietServingSizeTextField.textProperty());
                }
                @Override
                protected String computeValue() {
                    
                    TextField tf = view.dietServingSizeTextField;
                    float servingSize = 0;
                    try {
                        tf.setStyle("-fx-text-inner-color: black;");
                        servingSize = Float.parseFloat(tf.getText().trim());
                        if(servingSize < 0) throw new NumberFormatException();
                    }catch (NumberFormatException e) {
                        tf.setStyle("-fx-text-inner-color: red;");
                    }
                    return String.format("%.2f", servingSize);
                }
            };
    
            //set up Household binding
            StringBinding dietHouseholdBinding = new StringBinding() {
                {
                    super.bind(view.dietHouseholdSizeTextField.textProperty());
                }
                protected String computeValue() 
                {
                    TextField tf = view.dietHouseholdSizeTextField;
                    float servingSize = 0;
                    try {
                        tf.setStyle("-fx-text-inner-color: black;");
                        servingSize = Float.parseFloat(tf.getText().trim());
                        if(servingSize < 0) throw new NumberFormatException();
                    }catch (NumberFormatException e) {
                        tf.setStyle("-fx-text-inner-color: red;");
                    }
                    return String.format("%.2f", servingSize);
                }
            };
    
            //add listener to the dietServingSize to get read font
            view.dietServingSizeTextField.textProperty().addListener((observable,oldVal,newVal)->{
                if(newVal!=null)
                {
                    view.ageTextField.setStyle("-fx-text-inner-color: black;");
                    try {
                        Float.parseFloat(newVal);
                    }catch (NumberFormatException e) {
                        view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
            });
    
            //add listener to dietHouseholdSizeTextField to get read font
            view.dietHouseholdSizeTextField.textProperty().addListener((observable,oldVal,newVal)->{
                if(newVal!=null)
                {
                    view.ageTextField.setStyle("-fx-text-inner-color: black;");
                    try {
                        Float.parseFloat(newVal);
                    }catch (NumberFormatException e) {
                        view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
            });
            dietServingBinding.addListener((observable,oldVal,newVal)->{
            });
            dietHouseholdBinding.addListener((observable,oldVal,newVal)->{
            });
        }
    
        //set up recommendedNutrientBinding
        ObjectBinding<Person> recommendedNutrientBinding = new ObjectBinding<Person>() {
            {
                super.bind(view.genderComboBox.valueProperty(),view.ageTextField.textProperty(),
                        view.weightTextField.textProperty(),view.heightTextField.textProperty(),view.physicalActivityComboBox.valueProperty());
            }
            
            @Override
            protected Person computeValue() {
                
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    String activityLevelString = NutriByte.view.physicalActivityComboBox.getValue();
                    String gender = NutriByte.view.genderComboBox.getValue();
                    String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
                    
                    //set the default value
                    if(activityLevelString == null) activityLevelString = "Secondary";
                    
                    float age = 0;
                    float weight = 0;
                    float height=0;
                    TextField tf  = view.ageTextField;
                    
                    //set red font when negative age
                    try {
                        tf.setStyle("-fx-text-inner-color: black;");
                        age = Float.parseFloat(tf.getText().trim());
                        if(age < 0) throw new NumberFormatException();
                    }catch (NumberFormatException e) {
                        tf.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }
                    
                    //set red font when negative weight
                    try {
                        tf = view.weightTextField;
                        tf.setStyle("-fx-text-inner-color: black;");
                        weight = Float.parseFloat(view.weightTextField.getText().trim());
                        if(weight <0) throw new NumberFormatException();
                    } catch (NumberFormatException e1) {
                        
                        tf.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }
                    
                    //set red font when negative height
                    try {
                        tf = view.heightTextField;
                        tf.setStyle("-fx-text-inner-color: black;");
                        height = Float.parseFloat(view.heightTextField.getText().trim());
                        if(height<0) throw new NumberFormatException();
                    } catch (NumberFormatException e2) {
                        view.heightTextField.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }
                    
                    float activityLevel = 1.0f;
    //                for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
    //                    if (actEnum.getName().equals(activityLevelString))
    //                        activityLevel = actEnum.getPhysicalActivityLevel();
    //                }
                    
                    //judge the activityLevelString
                    if(activityLevelString.equals("Sedentary")) {
                        activityLevel = 1.0f;}
                    if(activityLevelString.equals("Low active")) {
                        activityLevel = 1.1f;}
                    if(activityLevelString.equals("Active")) {
                        activityLevel = 1.25f;}
                    if(activityLevelString.equals("Very active")) {
                        activityLevel = 1.48f;}
    
                    if (gender.toLowerCase().equals("male"))
                    {
                        return new Male(age, weight, height, activityLevel, ingredientsToWatch);
                    }
                    if (gender.toLowerCase().equals("female"))
                    {
                        return new Female(age, weight, height, activityLevel, ingredientsToWatch);
                    }
                }
                return null;
            }
        };
        
        //return nutrientName in this callback
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientNameCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                Nutrient nutrient = Model.nutrientsMap.get(arg0.getValue().getNutrientCode());
                return nutrient.nutrientNameProperty();
            }
        };
    
        //return NutrientQuantity in this callback
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientQuantityCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                for(RecommendedNutrient r: NutriByte.person.recommendedNutrientsList) {
                    if(r.getNutrientCode().equals(arg0.getValue().getNutrientCode())) {
                        float quantity = r.getNutrientQuantity();
                        String quantityString = String.format("%.2f", quantity);
                        return new SimpleStringProperty(quantityString);
                    }
                }
                return null;
            }
        };
        
        //return UOM in this callback
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientUomCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                Nutrient nutrient = Model.nutrientsMap.get(arg0.getValue().getNutrientCode());
                return nutrient.getNutrientUom();
            }
        };
        
        //return ProductNutrient's nutrient code in this callback
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientNameCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                return Model.nutrientsMap.get(arg1.getValue().getNutrientCode()).nutrientNameProperty();
            }
        };
        
        //return ProductNutrient's quantity in this callback
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientQuantityCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                return arg1.getValue().NutrientQuantityProperty().asString("%.2f");
            }
        };
        
        //return ProductNutrient's UOM in this callback
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientUomCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                return Model.nutrientsMap.get(arg1.getValue().getNutrientCode()).getNutrientUom();
            }
        };
    }
    View Code

    周日中午的controller

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.File;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.List;
    
    import hw3.Female;
    import hw3.Male;
    import hw3.NutriProfiler;
    import hw3.Model;
    import hw3.Product;
    import hw3.InvalidProfileException;
    import hw3.NutriByte;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    
    
    public class Controller {
    
        class RecommendNutrientsButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //judge genderComboBox at first 
                //            if (NutriByte.view.genderComboBox.getValue() == null) {
                //                new InvalidProfileException("Missing gender information");
                //            }
                if(NutriByte.view.genderComboBox.getSelectionModel().getSelectedIndex()<0){
                    new InvalidProfileException("Missing Gender Information");
                }
    
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    float age = 0, weight = 0, height = 0;
                    String gender = NutriByte.view.genderComboBox.getValue();
                    String ageString = NutriByte.view.ageTextField.getText().trim();
    
                    //改了下表达,没了
                    if (ageString == null || ageString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
    
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } 
                        catch (InvalidProfileException e) {
                            return;
                        }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
                    // weight empty exception
                    if (weightString == null || weightString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
    
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString == null || heightString.trim().length() == 0)
                        //原来是if (heightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
    
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
                    String activityLevelString = NutriByte.view.physicalActivityComboBox.getValue();
                    // activity exception
                    if (activityLevelString == null || activityLevelString.trim().length() == 0)
                        //if (activityLevelString == null)
                        activityLevelString = "Sedentary";
                    //activityLevelString = NutriProfiler.PhysicalActivityEnum.SEDENTARY.getName();
                    String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
                    //只改了这个:逐个判断
                    float physicalActivityLevel = 1.0f;
                    //                                for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
                    //                                    if (actEnum.getName().equals(activityLevelString))
                    //                                        physicalActivityLevel = actEnum.getPhysicalActivityLevel();
                    //                                }
                    //if the input is not empty, get the string from the ComboBox and change to according physicalActivityLevel
                    if(activityLevelString.equals("Sedentary")) {
                        physicalActivityLevel = 1.0f;}
                    if(activityLevelString.equals("Low active")) {
                        physicalActivityLevel = 1.1f;   
                    }
                    if(activityLevelString.equals("Active")) {
                        physicalActivityLevel = 1.25f;   
                    }
                    if(activityLevelString.equals("Very active")) {
                        physicalActivityLevel = 1.48f;   
                    }
    
                    //没怎么改
                    if (gender.toLowerCase().equals("male"))
                        NutriByte.person = new Male(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    if (gender.toLowerCase().equals("female"))
                        NutriByte.person = new Female(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                }
            }
        }
    
        class OpenMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                FileChooser fc = new FileChooser();
                fc.setTitle("Select file");
                //            fc.getExtensionFilters().addAll(new ExtensionFilter("Excel", "*.csv"),
                //                    new ExtensionFilter("XML", "*.xml"));
                fc.setInitialDirectory(new File("profiles/"));
                //改了一点
                fc.getExtensionFilters().addAll(
                        new ExtensionFilter("CSV Files", "*.csv"),
                        new ExtensionFilter("XML Files", "*.xml"),
                        new ExtensionFilter("All Files", "*.*"));
                File file = fc.showOpenDialog(new Stage());
                //System.out.print("path1 = " + file.getPath());
                //
                boolean canOpen = false;
    
                if (file == null) {
                    return;
                }else if (file != null){
                    //set up the fields
                    //String path = null;
                    //String path = file.getPath();
                    NutriByte.view.dietProductsTableView.getItems().clear();
                    NutriByte.view.nutriChart.clearChart();
                    NutriByte.view.genderComboBox.setPromptText("");
    
                    NutriByte.view.ageTextField.clear();
                    NutriByte.view.weightTextField.clear();
                    NutriByte.view.heightTextField.clear();
    
                    NutriByte.view.genderComboBox.getSelectionModel().clearSelection();
                    NutriByte.view.physicalActivityComboBox.getSelectionModel().clearSelection();
                    canOpen = NutriByte.model.readProfiles(file.getPath());
                    //System.out.print("
    path2 = " + file.getPath());
    
                    //双重弹窗这里, 一大堆就只改了顺序,感觉很危险
                    if (!canOpen) {
                        try {
                            throw (new InvalidProfileException("Could not read profile data"));
                        } catch (InvalidProfileException e) {
                            NutriByte.view.newNutriProfileMenuItem.fire();
                            NutriByte.view.productsComboBox.getItems().clear();
                            NutriByte.view.nutriChart.clearChart();
                            NutriByte.person = null;
                        }
                    }
                }
    
                if (NutriByte.person != null) {
                    NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
                    //                String formatedAge = String.format("%.2f", NutriByte.person.age);
                    //                NutriByte.view.ageTextField.setText(formatedAge);
                    //                String formatedWeight = String.format("%.2f", NutriByte.person.weight);
                    //                NutriByte.view.ageTextField.setText(formatedWeight);
                    //                String formatedHeight = String.format("%.2f", NutriByte.person.height);
                    //                NutriByte.view.ageTextField.setText(formatedHeight);
                    DecimalFormat decimalFormat = new DecimalFormat("0.00");
                    NutriByte.view.ageTextField.setText(decimalFormat.format(NutriByte.person.age));
                    NutriByte.view.weightTextField.setText(decimalFormat.format(NutriByte.person.weight) + "");
                    NutriByte.view.heightTextField.setText(decimalFormat.format(NutriByte.person.height) + "");
                    String activityLevelString = null;
                    //只改了physicalActivityLevel的逐个判断
                    //                for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
                    //                    if (actEnum.getPhysicalActivityLevel() == NutriByte.person.physicalActivityLevel)
                    //                        activityLevelString = actEnum.getName();
                    //                }
                    if(NutriByte.person.physicalActivityLevel == 1.0f) {
                        activityLevelString = "Sedentary";}
    
                    if(NutriByte.person.physicalActivityLevel == 1.1f) {
                        activityLevelString = "Low active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.25f) {
                        activityLevelString = "Active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.48f) {
                        activityLevelString = "Very active";   
                    }
    
                    NutriByte.view.physicalActivityComboBox.getSelectionModel().select(activityLevelString);
                    NutriByte.view.ingredientsToWatchTextArea.setText(NutriByte.person.ingredientsToWatch);
                    if (NutriByte.person instanceof Male)
                        NutriByte.view.genderComboBox.setValue("Male");
                    //NutriByte.view.genderComboBox.getSelectionModel().selectLast();
                    if (NutriByte.person instanceof Female)
                        NutriByte.view.genderComboBox.setValue("Female");
                    //NutriByte.view.genderComboBox.getSelectionModel().selectFirst();
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    // populate dietproducttable
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    // populate Tableview
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                    //循环改了下,其实没怎么改
                    // setup productCombobox
                    ObservableList<Product> temp = FXCollections.observableArrayList();
                    for (int i = 0; i < NutriByte.person.dietProductsList.size(); i++) {
                        Product product = NutriByte.person.dietProductsList.get(i);
                        String ndbNumber = product.getNdbNumber();
                        temp.add(Model.productsMap.get(ndbNumber));
                    }
                    //                for(Product product:NutriByte.person.dietProductsList)
                    //                {
                    //                    combo.add(Model.productsMap.get(product.getNdbNumber()));
                    //                }
                    NutriByte.view.productsComboBox.setItems(temp);
                    NutriByte.view.productsComboBox.getSelectionModel().selectFirst();
                    NutriByte.view.searchResultSizeLabel.setText(NutriByte.person.dietProductsList.size() + " products found");
                    // setup diet data
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.nutriChart.updateChart();
                }
            }
        }
        //这个一行也改不了?
        class NewMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
                NutriByte.view.initializePrompts();
                NutriByte.view.productsComboBox.getItems().clear();
                NutriByte.view.nutriChart.clearChart();
                NutriByte.view.recommendedNutrientsTableView.getItems().clear();
                NutriByte.view.productNutrientsTableView.getItems().clear();
                NutriByte.view.dietProductsTableView.getItems().clear();
                NutriByte.view.productIngredientsTextArea.clear();
                DecimalFormat decimalFormat = new DecimalFormat("0.00");
                NutriByte.view.servingSizeLabel.setText(decimalFormat.format(0));
                //NutriByte.view.servingSizeLabel.setText("0.00");
                //NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText(decimalFormat.format(0));
                if (NutriByte.person != null)
                    if (!NutriByte.person.recommendedNutrientsList.isEmpty()) {
                        NutriByte.person.recommendedNutrientsList.clear();
                        NutriByte.person.dietProductsList.clear();
                        NutriByte.view.genderComboBox.setPromptText("");
                        NutriByte.view.physicalActivityComboBox.setPromptText("");
                        NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                        NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                        NutriByte.view.productNutrientsTableView.getItems().clear();
                    }
            }
        }
    
        class AboutMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                Alert alert = new Alert(AlertType.INFORMATION);
                alert.setTitle("About");
                alert.setHeaderText("NutriByte");
                alert.setContentText(
                        "Version 3.0 
    Release 1.0
    Copyleft Java Nerds
    This software is designed purely for educational purposes.
    No commercial use intended");
                Image image = new Image(getClass().getClassLoader().getResource(NutriByte.NUTRIBYTE_IMAGE_FILE).toString());
                ImageView imageView = new ImageView();
                imageView.setImage(image);
                imageView.setFitWidth(300);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                alert.setGraphic(imageView);
                alert.showAndWait();
            }
        }
        //判断是否包含改成boolean了,思路没改
        class SearchButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                NutriByte.model.searchResultsList.clear();
                String productToSearch = NutriByte.view.productSearchTextField.getText().toLowerCase();
                String nutrientToSearch = NutriByte.view.nutrientSearchTextField.getText().toLowerCase();
                String ingredientToSearch = NutriByte.view.ingredientSearchTextField.getText().toLowerCase();
                boolean productToSearchIsEmpty = (productToSearch.isEmpty());
                boolean nutrientToSearchIsEmpty = (nutrientToSearch.isEmpty());
                boolean ingredientToSearchIsEmpty = (ingredientToSearch.isEmpty());
                String nutrientCode = null;
                List<String> productList = new ArrayList<>();
                List<String> nutrientList = new ArrayList<>();
                List<String> ingredientList = new ArrayList<>();
    
    
                //            for (Nutrient nutrient : Model.nutrientsMap.values()) {
                //                if (nutrient.getNutrientName().toLowerCase().contains(nutrientSearch))
                //                    nutrientCode = nutrient.getNutrientCode();
                //            }
    
                for (String key : Model.nutrientsMap.keySet()) {
                    Nutrient nutrient =  Model.nutrientsMap.get(key);
                    if (nutrient.getNutrientName().toLowerCase().contains(nutrientToSearch))
                        nutrientCode = nutrient.getNutrientCode();
                }
    
                if (productToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        productList.add(ndbnumber);
                } 
                if (!productToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductName().toLowerCase().contains(productToSearch))
                            productList.add(product.getNdbNumber());
                    } // fill in productList, which consists of nbdnumbers of products that contain
                }
    
    
                //keyword in name
                if (nutrientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        nutrientList.add(ndbnumber);
                } 
                if (!nutrientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductNutrients().containsKey(nutrientCode))
                            nutrientList.add(product.getNdbNumber());
                    } // fill in nutrientList, which consists of nbdnumbers of products that contain
                }
    
                // certain nutrientCode in productNutrients
                if (ingredientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        ingredientList.add(ndbnumber);
                } 
                if (!ingredientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getIngredients().toLowerCase().contains(ingredientToSearch))
                            ingredientList.add(product.getNdbNumber());
                    } // fill in ingredientList, which consists of nbdnumbers of products that contain
                }
    
                // certain ingredient in ingredient
                /* find common elements in these 3 lists */
                //循环改啰嗦了一点
                List<String> ndbToAdd = new ArrayList<>();
                boolean containsInNutrientList = false;
                boolean containsInIngredientList = false;
                for (int i = 0; i < productList.size(); i++) {
                    String ndb = productList.get(i);
                    if (nutrientList.contains(ndb)) containsInNutrientList = true;
                    if (ingredientList.contains(ndb)) containsInIngredientList = true;
                    if (containsInNutrientList && containsInIngredientList)
                        ndbToAdd.add(ndb);
                    containsInNutrientList = false;
                    containsInIngredientList = false;
                }
    
                //            for (String str : productList) {
                //                if (nutrientList.contains(str) && ingredientList.contains(str))
                //                    ndbToAdd.add(str);
                //            }
                if (!ndbToAdd.isEmpty())
                    //                for (String ndbNumber : ndbToAdd) {
                    //                    NutriByte.model.searchResultsList.add(Model.productsMap.get(ndbNumber));
                    //                }
                    for (int i = 0; i < ndbToAdd.size(); i++) {
                        String ndbNumber = ndbToAdd.get(i);
                        Product product = Model.productsMap.get(ndbNumber);
                        NutriByte.model.searchResultsList.add(product);
                    }
                // populate searchresultlist
                /* show products in combobox */
                NutriByte.view.productsComboBox.setItems(NutriByte.model.searchResultsList);
                //NutriByte.view.productsComboBox.getSelectionModel().select(0);
                NutriByte.view.productsComboBox.getSelectionModel().selectFirst();
                NutriByte.view.searchResultSizeLabel.setText(NutriByte.model.searchResultsList.size() + " products found");
            }
        }
        //这里也是一行改不了
        class ClearButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //SearchTextField
                NutriByte.view.productSearchTextField.clear();
                NutriByte.view.ingredientSearchTextField.clear();
                NutriByte.view.nutrientSearchTextField.clear();
                //products all info
                NutriByte.view.productsComboBox.getSelectionModel().clearSelection();
                NutriByte.view.productNutrientsTableView.setItems(null);
                NutriByte.model.searchResultsList.clear();
                NutriByte.view.productIngredientsTextArea.clear();
                //two sizes, uom
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.householdServingUom.setText("");
                NutriByte.view.servingUom.setText("");
                NutriByte.view.dietServingUomLabel.setText("");
                NutriByte.view.dietHouseholdUomLabel.setText("");
                NutriByte.view.searchResultSizeLabel.setText("");
            }
        }
    
        //没改但是这个好像不用改
        class ProductsComboBoxListener implements ChangeListener<Product> {
            @Override
            public void changed(ObservableValue<? extends Product> observable, Product oldValue, Product newValue) {
                {
                    if (NutriByte.view.productsComboBox.getSelectionModel().getSelectedIndex() >= 0) {
                        ObservableList<Product.ProductNutrient> resultList = FXCollections.observableArrayList();
                        Product selectedProduct = NutriByte.view.productsComboBox.getValue();
                        for (Product.ProductNutrient nutrient : selectedProduct.getProductNutrients().values()) {
                            resultList.add(nutrient);
                        }
                        NutriByte.view.productNutrientsTableView.setItems(resultList);
                        NutriByte.view.productIngredientsTextArea
                        .setText("Product ingredients: " + selectedProduct.getIngredients());
                        NutriByte.view.servingSizeLabel.setText(String.format("%.2f", selectedProduct.getServingSize()) + " "
                                + selectedProduct.getServingUom());
                        NutriByte.view.householdSizeLabel.setText(String.format("%.2f", selectedProduct.getHouseholdSize())
                                + " " + selectedProduct.getHouseholdUom());
                        NutriByte.view.householdServingUom.setText(selectedProduct.getServingUom());
                        NutriByte.view.servingUom.setText(selectedProduct.getServingUom());
                        NutriByte.view.dietServingUomLabel.setText(selectedProduct.getServingUom());
                        NutriByte.view.dietHouseholdUomLabel.setText(selectedProduct.getHouseholdUom());
                    }
                } // TODO Auto-generated method stub
            }
        }
        
        //合并了两种情况,思路没改
        class AddDietButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                // TODO Auto-generated method stub
                Product selectedProduct = NutriByte.view.productsComboBox.getValue();
                String inputServingSizeString = NutriByte.view.dietServingSizeTextField.getText().trim();
                String inputHouseholdSizeString = NutriByte.view.dietHouseholdSizeTextField.getText().trim();
                Product outputProduct = new Product(selectedProduct.getNdbNumber(), selectedProduct.getProductName(),
                        selectedProduct.getManufacturer(), selectedProduct.getIngredients());
                float outputServingSize = 0;
                //            if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                //            else outputServingSize = selectedProduct.getServingSize();
    
                float outputHouseholdSize = 0;
                //            if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                //            else outputHouseholdSize = selectedProduct.getHouseholdSize();
                boolean inputServingSizeStringIsNull = (inputServingSizeString.equals(""));
                boolean inputHouseholdSizeStringIsNull = (inputHouseholdSizeString.equals(""));
                //System.out.println("inputServingSizeStringIsNull = "+inputServingSizeStringIsNull);
                //System.out.println("inputHouseholdSizeStringIsNull = " +inputHouseholdSizeStringIsNull);
    
                // scenario 1: nothing input
                if (inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) {
                    outputServingSize = selectedProduct.getServingSize();
                    outputHouseholdSize = selectedProduct.getHouseholdSize();
                    if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                    if (selectedProduct.getServingSize().equals("none")) outputHouseholdSize = selectedProduct.getServingSize();
                }
    
                // scenario 2: only householdsize
                if (inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull) {
                    try {
                        outputHouseholdSize = Float.parseFloat(inputHouseholdSizeString);
                        outputServingSize = outputHouseholdSize / selectedProduct.getHouseholdSize()
                                * selectedProduct.getServingSize();
                        //只改了这一种情况,别的也要改
                        if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                        if (selectedProduct.getServingSize().equals("none")) outputHouseholdSize = selectedProduct.getServingSize();
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietHouseholdSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
                // scenario 3: only servingsize, scenario 4: two inputs
                if ((!inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) || 
                        (!inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull)) {
                    try {
                        outputServingSize = Float.parseFloat(inputServingSizeString);
                        outputHouseholdSize = outputServingSize / selectedProduct.getServingSize()
                                * selectedProduct.getHouseholdSize();
                        if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                        if (selectedProduct.getServingSize().equals("none")) outputHouseholdSize = selectedProduct.getServingSize();
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
    
                // scenario 4: two inputs
                //            if (!inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull) {
                //                try {
                //                    outputServingSize = Float.parseFloat(inputServingSizeString);
                //                    outputHouseholdSize = outputServingSize / selectedProduct.getServingSize()
                //                            * selectedProduct.getHouseholdSize();
                //                    if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                //                    if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                //                } catch (NumberFormatException e) {
                //                    NutriByte.view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                //                }
                //            }
                /* add new product into list */
    
                outputProduct.setHouseholdSize(outputHouseholdSize);
                //System.out.println("outputHouseholdSize = " +outputHouseholdSize);
                outputProduct.setServingSize(outputServingSize);
                outputProduct.setHouseholdUom(selectedProduct.getHouseholdUom());
                outputProduct.setServingUom(selectedProduct.getServingUom());
                //lambda改了
                //            selectedProduct.getProductNutrients().forEach((k, v) -> {
                //                outputProduct.setProductNutrients(v);
                //            });
                for(Product.ProductNutrient pn : selectedProduct.getProductNutrients().values()) {
                    outputProduct.setProductNutrients(pn);
                }
    
                if(NutriByte.person == null) {            
                    NutriByte.view.dietProductsTableView.getItems().add(outputProduct);
                    //                    System.out.println("person null");
                    return;
                }else {
                    //NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.person.dietProductsList.add(outputProduct);
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    NutriByte.view.nutriChart.updateChart();
                }
            }
        }
        //稍微改了一点
        class RemoveDietButtonHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                int index = NutriByte.view.dietProductsTableView.getSelectionModel().getSelectedIndex(); // 得到了dietProduct里面的第几个
    
                if (NutriByte.person == null) {
                    NutriByte.view.dietProductsTableView.getItems().remove(index);
    
                } else {
                    NutriByte.person.dietProductsList.remove(index);
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    NutriByte.view.nutriChart.updateChart();
    
                    if (NutriByte.person.dietProductsList.size() == 0) {
                        NutriByte.view.nutriChart.clearChart();
                    }
    
                }
            }
    
        }
    
        //    class RemoveDietButtonHandler implements EventHandler<ActionEvent> {
        //        @Override
        //        public void handle(ActionEvent event) {
        //            // TODO Auto-generated method stub
        //            NutriByte.person.dietProductsList
        //            .remove(NutriByte.view.dietProductsTableView.getSelectionModel().getSelectedIndex());
        //            NutriByte.person.dietNutrientsMap.clear();
        //            NutriByte.person.populateDietNutrientsMap();
        //            NutriByte.view.nutriChart.clearChart();
        //            NutriByte.view.nutriChart.updateChart();
        //        }
        //    }
    
        //没怎么改
        class SaveButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                // TODO Auto-generated method stub
                if (NutriByte.view.genderComboBox.getValue() == null) {
                    new InvalidProfileException("Missing gender information");
                }
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    float age = 0, weight = 0, height = 0;
                    //                String gender = NutriByte.view.genderComboBox.getValue();
                    String ageString = NutriByte.view.ageTextField.getText().trim();
                    // age empty exception
                    if (ageString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
                    // weight empty exception
                    if (weightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
    
                    FileChooser fc = new FileChooser();
                    fc.setTitle("Save file");
                    //fc.getExtensionFilters().addAll(new ExtensionFilter("Excel", "*.csv"));
                    fc.setInitialDirectory(new File("profiles/"));
                    //就改了这一点
                    fc.getExtensionFilters().addAll(
                            new ExtensionFilter("CSV Files", "*.csv"),
                            new ExtensionFilter("XML Files", "*.xml"),
                            new ExtensionFilter("All Files", "*.*"));
    
                    File file = fc.showSaveDialog(new Stage());
                    if (file != null)
                        try {
                            String path = file.getPath();
                            NutriByte.model.writeProfile(path);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                }
            }
        }
        //没改不过好像不用改
        class CloseMenuButtonHandler implements EventHandler<ActionEvent>{
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                NutriByte.view.root.setCenter(NutriByte.view.setupWelcomeScene());// TODO Auto-generated method stub
    
            }
        }
    }
    View Code

    周六十点半 抄的csvfiler

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.List;
    
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    
    public class CSVFiler extends DataFiler{
        @Override
        public boolean readFile(String filename) {
    
            CSVFormat csvFormat = CSVFormat.DEFAULT;
            try {
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat);
                List<CSVRecord> list = csvParser.getRecords();            
                StringBuilder sb = new StringBuilder();
                for(CSVRecord records:list)
                {
                    for(String columnContent:records)
                    {
                        sb.append(columnContent+",");
                    }
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                    sb.append("
    ");
                }//populate stringbuilder with each row
                /*load person data*/
                String[] rows = sb.toString().split("
    ");
                Person person = validatePersonData(rows[0]);
                NutriByte.person = person;
                /*load diet data*/
                for(int i=1;i<rows.length;i++)
                {
                    try{
                        Product dietProduct = validateProductData(rows[i]);
                        NutriByte.person.dietProductsList.add(dietProduct);
                    }catch (InvalidProfileException e1) {
                        continue;
                    }
                    
                }
                /*HW2 part*/
    //            for (int i = 5; i < list.get(0).size(); i++) {
    //                sb.append(list.get(0).get(i) + ",");
    //            }
    //            if (sb.length() > 0)
    //                sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
    //            String ingredientsToWatch = sb.toString();//get ingredients to watch
    //            if (gender.equals("Male")) {
    //                NutriByte.person = new Male(age, weight, height, activity, ingredientsToWatch);
    //                return true;
    //            }
    //            if (gender.equals("Female")) {
    //                NutriByte.person = new Female(age, weight, height, activity, ingredientsToWatch);
    //                return true;
    //            }//instantiate person
    
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
                return false;
            } catch (IOException e1) {
                e1.printStackTrace();
                return false;
            } catch(InvalidProfileException e1)
            {
                return false;
            }
            if(NutriByte.person!=null) return true;
            return false;
            
        }
        @Override
        public void writeFile(String filename) {
            // TODO Auto-generated method stub
            String gender = NutriByte.view.genderComboBox.getValue();
            if(gender==null) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw(new InvalidProfileException("Missing gender information"));            
            }
            String age = NutriByte.view.ageTextField.getText();
            String weight = NutriByte.view.weightTextField.getText();
            String height = NutriByte.view.heightTextField.getText();
            String activity = NutriByte.view.physicalActivityComboBox.getValue();
            float actiLevel=0;
            for(NutriProfiler.PhysicalActivityEnum physic: NutriProfiler.PhysicalActivityEnum.values())
            {
                if(physic.getName() == activity)
                {
                    actiLevel = physic.getPhysicalActivityLevel();
                }
            }
            String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
            StringBuilder sb = new StringBuilder();
            sb.append(gender+","+age+","+weight+","+height+","+String.format("%.2f", actiLevel)+","+ingredientsToWatch+"
    ");
    //        validatePersonData(sb.toString());
            for(Product product:NutriByte.view.dietProductsTableView.getItems())
            {
                sb.append(product.getNdbNumber()+","+product.getServingSize()+","+product.getHouseholdSize()+"
    ");
            }
            String[] records = sb.toString().split("
    ");
            
            try(BufferedWriter bw = new BufferedWriter(new FileWriter(filename));)
            {
                for(int i=0;i<records.length;i++)
                {
                    bw.write(records[i]+"
    ");
                }
            }catch (IOException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        
        Person validatePersonData(String data)
        {
            String[]column = data.split(",");
            if(!column[0].trim().equals("Male")&&!column[0].trim().equals("Female")) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw (new InvalidProfileException("The profile must have gender: Female or male as first word"));
            }
            try{
                String age = column[1].trim();
                 Float.parseFloat(age);
            }catch(NumberFormatException e1) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw (new InvalidProfileException("Invalid data for age: "+column[1]+"
    Age must be a number"));
            }
            try{
                 Float.parseFloat(column[2].trim());
            }catch(NumberFormatException e1) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw (new InvalidProfileException("Invalid data for weight: "+column[2]+"
    Weight must be a number"));
            }
            try{
                 Float.parseFloat(column[3].trim());
            }catch(NumberFormatException e1) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw (new InvalidProfileException("Invalid data for height: "+column[3]+"
    Height must be a number"));
            }
            boolean act = false;
            for(NutriProfiler.PhysicalActivityEnum physicEnum:NutriProfiler.PhysicalActivityEnum.values())
            {
                if(Float.parseFloat(column[4].trim())==physicEnum.getPhysicalActivityLevel()) act=true;
            }
            if(act==false)
                {
                NutriByte.view.newNutriProfileMenuItem.fire();
                throw (new InvalidProfileException("Invalid physical activity level: "+column[4]+"
    Must be 1.0,1.1,1.25 or 1.48"));
                }
            StringBuilder sb = new StringBuilder();
            for(int i=5;i<column.length;i++)
            {
                sb.append(column[i]+",");
            }
            if(sb.length()>0)
            sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
            String ingredients = sb.toString();
            if(column[0].equals("Male"))
            {
                
                return (new Male(Float.parseFloat(column[1].trim()),Float.parseFloat(column[2].trim()),
                        Float.parseFloat(column[3].trim()),Float.parseFloat(column[4].trim()),ingredients));
            }
            else
                {
                return (new Female(Float.parseFloat(column[1].trim()),Float.parseFloat(column[2].trim()),Float.parseFloat(column[3].trim()),Float.parseFloat(column[4].trim()),ingredients));
                }
                        
        }//to be coded
        
        Product validateProductData(String data) {
            String[] columnData = data.split(",");
            // ensure ndbnumber is valid
            if (!Model.productsMap.containsKey(columnData[0]))
                throw (new InvalidProfileException("No product found with this code: "+columnData[0]));
            //find if servingsize is number
            try {
                Float.parseFloat(columnData[1]);
            //find if missing quantity
            
                Product originProduct = Model.productsMap.get(columnData[0]);
                Product newProduct = new Product(originProduct.getNdbNumber(),originProduct.getProductName(),
                        originProduct.getManufacturer(),originProduct.getIngredients());
                newProduct.setServingSize(Float.parseFloat(columnData[1]));
                newProduct.setServingUom(originProduct.getServingUom());
                newProduct.setHouseholdSize(Float.parseFloat(columnData[2]));
                newProduct.setHouseholdUom(originProduct.getHouseholdUom());
                originProduct.getProductNutrients().forEach((k,v)->{
                    newProduct.setProductNutrients(v);
                });//1. get corresponding product from productMap
                   //2. create a same new product having same map of productNutrients, except servingsize and householdsize
                return newProduct;
            }catch (NumberFormatException e1) {
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.searchResultSizeLabel.setText("");
                NutriByte.view.productNutrientsTableView.itemsProperty().setValue(null);
                NutriByte.view.productIngredientsTextArea.clear();
                NutriByte.view.productsComboBox.getItems().clear();
                throw (new InvalidProfileException("Cannot read: "+data+"
    The data must be - String, number, number - for ndb number,
    "+"serving size, household size"));
            }catch (ArrayIndexOutOfBoundsException e1) {
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.searchResultSizeLabel.setText("");
                NutriByte.view.productIngredientsTextArea.clear();
                NutriByte.view.productNutrientsTableView.itemsProperty().setValue(null);
                NutriByte.view.productsComboBox.getItems().clear();
                throw (new InvalidProfileException("Cannot read: "+data+"
    The data must be - String, number, number - for ndb number,
    "+"serving size, household size"));
            }
        }
    }
    View Code

    周六八点半 有错的controller:

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.File;
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.List;
    
    import hw3.Female;
    import hw3.Male;
    import hw3.NutriProfiler;
    import hw3.Model;
    import hw3.Product;
    import hw3.InvalidProfileException;
    import hw3.NutriByte;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.stage.FileChooser;
    import javafx.stage.FileChooser.ExtensionFilter;
    import javafx.stage.Stage;
    
    
    public class Controller {
    
        class RecommendNutrientsButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //judge genderComboBox at first 
                //            if (NutriByte.view.genderComboBox.getValue() == null) {
                //                new InvalidProfileException("Missing gender information");
                //            }
                if(NutriByte.view.genderComboBox.getSelectionModel().getSelectedIndex()<0){
                    new InvalidProfileException("Missing Gender Information");
                }
    
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    float age = 0, weight = 0, height = 0;
                    String gender = NutriByte.view.genderComboBox.getValue();
                    String ageString = NutriByte.view.ageTextField.getText().trim();
    
                    // age empty exception必须有catch,不然console飘红
                    if (ageString == null || ageString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    //exception最好别改,console很危险
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } 
                        catch (InvalidProfileException e) {
                            return;
                        }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
                    // weight empty exception
                    if (weightString == null || weightString.trim().length() == 0)
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    //weight is not number or is empty
                    //                if (weightString.indexOf(".") == -1) {
                    //                    new InvalidProfileException("Incorrect weight input. Must be a number");
                    //                }else {
                    //                    weight = Float.parseFloat(weightString);
                    //                    if (weight < 0)
                    //                        try {
                    //                            throw (new InvalidProfileException("Weight must be a positive number"));
                    //                        } catch (InvalidProfileException e) {
                    //                            return;
                    //                        }
                    //                }
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString == null || heightString.trim().length() == 0)
                        //if (heightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
    
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
                    String activityLevelString = NutriByte.view.physicalActivityComboBox.getValue();
                    // activity exception
                    if (activityLevelString == null || activityLevelString.trim().length() == 0)
                        //if (activityLevelString == null)
                        activityLevelString = "Sedentary";
                    //activityLevelString = NutriProfiler.PhysicalActivityEnum.SEDENTARY.getName();
                    String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
                    //看看原来的吧,逐个判断?可以的。但是也就只改了这里啊我去。
                    float physicalActivityLevel = 1.0f;
                    //                                for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
                    //                                    if (actEnum.getName().equals(activityLevelString))
                    //                                        physicalActivityLevel = actEnum.getPhysicalActivityLevel();
                    //                                }
                    //if the input is not empty, get the string from the ComboBox and change to according physicalActivityLevel
                    if(activityLevelString.equals("Sedentary")) {
                        physicalActivityLevel = 1.0f;}
                    if(activityLevelString.equals("Low active")) {
                        physicalActivityLevel = 1.1f;   
                    }
                    if(activityLevelString.equals("Active")) {
                        physicalActivityLevel = 1.25f;   
                    }
                    if(activityLevelString.equals("Very active")) {
                        physicalActivityLevel = 1.48f;   
                    }
    
                    //                switch(gender) {
                    //                case "Male":
                    //                    NutriByte.person = new Male(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    //                case "Female":
                    //                    NutriByte.person = new Female(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    //                }
                    if (gender.toLowerCase().equals("male"))
                        NutriByte.person = new Male(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    if (gender.toLowerCase().equals("female"))
                        NutriByte.person = new Female(age, weight, height, physicalActivityLevel, ingredientsToWatch);
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                }
            }
        }
    
        class OpenMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                FileChooser fc = new FileChooser();
                fc.setTitle("Select file");
                //            fc.getExtensionFilters().addAll(new ExtensionFilter("Excel", "*.csv"),
                //                    new ExtensionFilter("XML", "*.xml"));
                fc.setInitialDirectory(new File("profiles/"));
                fc.getExtensionFilters().addAll(
                        new ExtensionFilter("CSV Files", "*.csv"),
                        new ExtensionFilter("XML Files", "*.xml"),
                        new ExtensionFilter("All Files", "*.*"));
                File file = fc.showOpenDialog(new Stage());
                System.out.print("path1 = " + file.getPath());
                //
                boolean canOpen = false;
    
    //            if (file == null) {
    //                return;
    //            }
    //            if (file != null){
    //                //set up the fields
    //                //String path = null;
    //                //String path = file.getPath();
    //
    //
    //                NutriByte.view.dietProductsTableView.getItems().clear();
    //                NutriByte.view.nutriChart.clearChart();
    //                NutriByte.view.genderComboBox.setPromptText("");
    //
    //                NutriByte.view.ageTextField.clear();
    //                NutriByte.view.weightTextField.clear();
    //                NutriByte.view.heightTextField.clear();
    //
    //                NutriByte.view.genderComboBox.getSelectionModel().clearSelection();
    //                NutriByte.view.physicalActivityComboBox.getSelectionModel().clearSelection();
    //                canOpen = NutriByte.model.readProfiles(file.getPath());
    //                System.out.print("path2 = " + file.getPath());
                if (file != null) {
    //                NutriByte.view.newNutriProfileMenuItem.fire();
    //                NutriByte.person.dietProductsList.clear();
    //                NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.genderComboBox.getSelectionModel().clearSelection();
                    NutriByte.view.physicalActivityComboBox.getSelectionModel().clearSelection();
                    NutriByte.view.ageTextField.clear();
                    NutriByte.view.weightTextField.clear();
                    NutriByte.view.heightTextField.clear();
                    NutriByte.view.dietProductsTableView.getItems().clear();
                    NutriByte.view.nutriChart.clearChart();
                    NutriByte.view.genderComboBox.setPromptText("");
                    canOpen = NutriByte.model.readProfiles(file.getPath());
                    if (canOpen == false) {
                        try {
                            
                            throw (new InvalidProfileException("Could not read profile data"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
    //                        NutriByte.view.initializePrompts();
    //                        NutriByte.person.recommendedNutrientsList.clear();
                            NutriByte.view.nutriChart.clearChart();
                            NutriByte.view.productsComboBox.getItems().clear();
    //                        NutriByte.view.productNutrientsTableView.getItems().clear();                        
    //                        NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
    //                        NutriByte.person.dietProductsList.clear();
    //                        NutriByte.view.genderComboBox.setPromptText("");
    //                        NutriByte.view.physicalActivityComboBox.setPromptText("");
    //                        NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                            NutriByte.view.newNutriProfileMenuItem.fire();
                            NutriByte.person = null;
    //                        NutriByte.person = null;
                        }
                    }
                }
                else {
                    return;
                }
                    //双重弹窗, 一大堆就只改了顺序,感觉很危险
                    if (!canOpen) {
                        try {
                            throw (new InvalidProfileException("Could not read profile data"));
                        } catch (InvalidProfileException e) {
                            NutriByte.view.newNutriProfileMenuItem.fire();
                            NutriByte.view.productsComboBox.getItems().clear();
                            NutriByte.view.nutriChart.clearChart();
                            NutriByte.person = null;
                        }
                    }
                
    
                if (NutriByte.person != null) {
                    NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
    //                String formatedAge = String.format("%.2f", NutriByte.person.age);
    //                NutriByte.view.ageTextField.setText(formatedAge);
    //                String formatedWeight = String.format("%.2f", NutriByte.person.weight);
    //                NutriByte.view.ageTextField.setText(formatedWeight);
    //                String formatedHeight = String.format("%.2f", NutriByte.person.height);
    //                NutriByte.view.ageTextField.setText(formatedHeight);
                    DecimalFormat decimalFormat = new DecimalFormat("0.00");
                    NutriByte.view.ageTextField.setText(decimalFormat.format(NutriByte.person.age));
                    NutriByte.view.weightTextField.setText(decimalFormat.format(NutriByte.person.weight) + "");
                    NutriByte.view.heightTextField.setText(decimalFormat.format(NutriByte.person.height) + "");
                    String activityLevelString = null;
                    //又是只有这里吗
                    //                for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
                    //                    if (actEnum.getPhysicalActivityLevel() == NutriByte.person.physicalActivityLevel)
                    //                        activityLevelString = actEnum.getName();
                    //                }
                    if(NutriByte.person.physicalActivityLevel == 1.0f) {
                        activityLevelString = "Sedentary";}
    
                    if(NutriByte.person.physicalActivityLevel == 1.1f) {
                        activityLevelString = "Low active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.25f) {
                        activityLevelString = "Active";   
                    }
                    if(NutriByte.person.physicalActivityLevel == 1.48f) {
                        activityLevelString = "Very active";   
                    }
    
                    NutriByte.view.physicalActivityComboBox.getSelectionModel().select(activityLevelString);
                    NutriByte.view.ingredientsToWatchTextArea.setText(NutriByte.person.ingredientsToWatch);
                    if (NutriByte.person instanceof Male)
                        NutriByte.view.genderComboBox.setValue("Male");
                    //NutriByte.view.genderComboBox.getSelectionModel().selectLast();
                    if (NutriByte.person instanceof Female)
                        NutriByte.view.genderComboBox.setValue("Female");
                    //NutriByte.view.genderComboBox.getSelectionModel().selectFirst();
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    // populate dietproducttable
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    // populate Tableview
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
    
                    // setup productCombobox
                    ObservableList<Product> temp = FXCollections.observableArrayList();
                    for (int i = 0; i < NutriByte.person.dietProductsList.size(); i++) {
                        Product product = NutriByte.person.dietProductsList.get(i);
                        String ndbNumber = product.getNdbNumber();
                        temp.add(Model.productsMap.get(ndbNumber));
                    }
                    //                for(Product product:NutriByte.person.dietProductsList)
                    //                {
                    //                    combo.add(Model.productsMap.get(product.getNdbNumber()));
                    //                }
                    NutriByte.view.productsComboBox.setItems(temp);
                    NutriByte.view.productsComboBox.getSelectionModel().selectFirst();
                    NutriByte.view.searchResultSizeLabel.setText(NutriByte.person.dietProductsList.size() + " products found");
                    // setup diet data
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.nutriChart.updateChart();
                }
            }
        }
    
        class NewMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
                NutriByte.view.initializePrompts();
                NutriByte.view.productsComboBox.getItems().clear();
                NutriByte.view.nutriChart.clearChart();
                NutriByte.view.recommendedNutrientsTableView.getItems().clear();
                NutriByte.view.productNutrientsTableView.getItems().clear();
                NutriByte.view.dietProductsTableView.getItems().clear();
                NutriByte.view.productIngredientsTextArea.clear();
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                if (NutriByte.person != null)
                    if (!NutriByte.person.recommendedNutrientsList.isEmpty()) {
                        NutriByte.person.recommendedNutrientsList.clear();
                        NutriByte.person.dietProductsList.clear();
                        NutriByte.view.genderComboBox.setPromptText("");
                        NutriByte.view.physicalActivityComboBox.setPromptText("");
                        NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                        NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                        NutriByte.view.productNutrientsTableView.getItems().clear();
                    }
            }
        }
    
        class AboutMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                Alert alert = new Alert(AlertType.INFORMATION);
                alert.setTitle("About");
                alert.setHeaderText("NutriByte");
                alert.setContentText(
                        "Version 3.0 
    Release 1.0
    Copyleft Java Nerds
    This software is designed purely for educational purposes.
    No commercial use intended");
                Image image = new Image(getClass().getClassLoader().getResource(NutriByte.NUTRIBYTE_IMAGE_FILE).toString());
                ImageView imageView = new ImageView();
                imageView.setImage(image);
                imageView.setFitWidth(300);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                alert.setGraphic(imageView);
                alert.showAndWait();
            }
        }
    
        class SearchButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                NutriByte.model.searchResultsList.clear();
                String productToSearch = NutriByte.view.productSearchTextField.getText().toLowerCase();
                String nutrientToSearch = NutriByte.view.nutrientSearchTextField.getText().toLowerCase();
                String ingredientToSearch = NutriByte.view.ingredientSearchTextField.getText().toLowerCase();
                boolean productToSearchIsEmpty = (productToSearch.isEmpty());
                boolean nutrientToSearchIsEmpty = (nutrientToSearch.isEmpty());
                boolean ingredientToSearchIsEmpty = (ingredientToSearch.isEmpty());
                String nutrientCode = null;
                List<String> productList = new ArrayList<>();
                List<String> nutrientList = new ArrayList<>();
                List<String> ingredientList = new ArrayList<>();
    
                //有循环的地方好像可以改, 存的是nutrients 可以用for吗
                //先用key,再用value
                //            for (Nutrient nutrient : Model.nutrientsMap.values()) {
                //                if (nutrient.getNutrientName().toLowerCase().contains(nutrientSearch))
                //                    nutrientCode = nutrient.getNutrientCode();
                //            }
    
                for (String key : Model.nutrientsMap.keySet()) {
                    Nutrient nutrient =  Model.nutrientsMap.get(key);
                    if (nutrient.getNutrientName().toLowerCase().contains(nutrientToSearch))
                        nutrientCode = nutrient.getNutrientCode();
                }
                //如果没有产品名,就添加全部产品。三项中有一项存在就添加
                if (productToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        productList.add(ndbnumber);
                } 
                if (!productToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductName().toLowerCase().contains(productToSearch))
                            productList.add(product.getNdbNumber());
                    } // fill in productList, which consists of nbdnumbers of products that contain
                }
    
    
                //keyword in name
                if (nutrientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        nutrientList.add(ndbnumber);
                } 
                if (!nutrientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getProductNutrients().containsKey(nutrientCode))
                            nutrientList.add(product.getNdbNumber());
                    } // fill in nutrientList, which consists of nbdnumbers of products that contain
                }
    
                // certain nutrientCode in productNutrients
                if (ingredientToSearchIsEmpty) {
                    for (String ndbnumber : Model.productsMap.keySet())
                        ingredientList.add(ndbnumber);
                } 
                if (!ingredientToSearchIsEmpty) {
                    for (Product product : Model.productsMap.values()) {
                        if (product.getIngredients().toLowerCase().contains(ingredientToSearch))
                            ingredientList.add(product.getNdbNumber());
                    } // fill in ingredientList, which consists of nbdnumbers of products that contain
                }
    
                // certain ingredient in ingredient
                /* find common elements in these 3 lists */
                //同时满足三个搜索条件采访到result中 没错,因为不搜就是全部
                //所以怎么改啊
                List<String> ndbToAdd = new ArrayList<>();
                //改成TTF的形式 LOL
                boolean containsInNutrientList = false;
                boolean containsInIngredientList = false;
                for (int i = 0; i < productList.size(); i++) {
                    String ndb = productList.get(i);
                    if (nutrientList.contains(ndb)) containsInNutrientList = true;
                    if (ingredientList.contains(ndb)) containsInIngredientList = true;
                    if (containsInNutrientList && containsInIngredientList)
                        ndbToAdd.add(ndb);
                    containsInNutrientList = false;
                    containsInIngredientList = false;
                }
    
                //            for (String str : productList) {
                //                if (nutrientList.contains(str) && ingredientList.contains(str))
                //                    ndbToAdd.add(str);
                //            }
                if (!ndbToAdd.isEmpty())
                    //                for (String ndbNumber : ndbToAdd) {
                    //                    NutriByte.model.searchResultsList.add(Model.productsMap.get(ndbNumber));
                    //                }
                    for (int i = 0; i < ndbToAdd.size(); i++) {
                        String ndbNumber = ndbToAdd.get(i);
                        Product product = Model.productsMap.get(ndbNumber);
                        NutriByte.model.searchResultsList.add(product);
                    }
                // populate searchresultlist
                /* show products in combobox */
                NutriByte.view.productsComboBox.setItems(NutriByte.model.searchResultsList);
                //NutriByte.view.productsComboBox.getSelectionModel().select(0);
                NutriByte.view.productsComboBox.getSelectionModel().selectFirst();
                NutriByte.view.searchResultSizeLabel.setText(NutriByte.model.searchResultsList.size() + " products found");
            }
        }
    
        class ClearButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.productSearchTextField.clear();
                NutriByte.view.ingredientSearchTextField.clear();
                NutriByte.view.nutrientSearchTextField.clear();
                NutriByte.view.productsComboBox.getSelectionModel().clearSelection();
                NutriByte.view.productNutrientsTableView.setItems(null);
                NutriByte.model.searchResultsList.clear();
                NutriByte.view.productIngredientsTextArea.clear();
                NutriByte.view.servingSizeLabel.setText("0.00");
                NutriByte.view.householdSizeLabel.setText("0.00");
                NutriByte.view.householdServingUom.setText("");
                NutriByte.view.servingUom.setText("");
                NutriByte.view.dietServingUomLabel.setText("");
                NutriByte.view.dietHouseholdUomLabel.setText("");
                NutriByte.view.searchResultSizeLabel.setText("");
            }
        }
    
        class ProductsComboBoxListener implements ChangeListener<Product> {
            @Override
            public void changed(ObservableValue<? extends Product> observable, Product oldValue, Product newValue) {
                {
                    if (NutriByte.view.productsComboBox.getSelectionModel().getSelectedIndex() >= 0) {
                        ObservableList<Product.ProductNutrient> resultList = FXCollections.observableArrayList();
                        Product selectedProduct = NutriByte.view.productsComboBox.getValue();
                        //改lambda?
                        for (Product.ProductNutrient nutrient : selectedProduct.getProductNutrients().values()) {
                            resultList.add(nutrient);
                        }
                        NutriByte.view.productNutrientsTableView.setItems(resultList);
                        NutriByte.view.productIngredientsTextArea
                        .setText("Product ingredients: " + selectedProduct.getIngredients());
                        NutriByte.view.servingSizeLabel.setText(String.format("%.2f", selectedProduct.getServingSize()) + " "
                                + selectedProduct.getServingUom());
                        NutriByte.view.householdSizeLabel.setText(String.format("%.2f", selectedProduct.getHouseholdSize())
                                + " " + selectedProduct.getHouseholdUom());
                        NutriByte.view.householdServingUom.setText(selectedProduct.getServingUom());
                        NutriByte.view.servingUom.setText(selectedProduct.getServingUom());
                        NutriByte.view.dietServingUomLabel.setText(selectedProduct.getServingUom());
                        NutriByte.view.dietHouseholdUomLabel.setText(selectedProduct.getHouseholdUom());
                    }
                } // TODO Auto-generated method stub
            }
        }
        //就用这个,但是可以合并两种情况
        class AddDietButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                // TODO Auto-generated method stub
                Product selectedProduct = NutriByte.view.productsComboBox.getValue();
                String inputServingSizeString = NutriByte.view.dietServingSizeTextField.getText().trim();
                String inputHouseholdSizeString = NutriByte.view.dietHouseholdSizeTextField.getText().trim();
                Product outputProduct = new Product(selectedProduct.getNdbNumber(), selectedProduct.getProductName(),
                        selectedProduct.getManufacturer(), selectedProduct.getIngredients());
                float outputServingSize = 0;
                //            if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                //            else outputServingSize = selectedProduct.getServingSize();
    
                float outputHouseholdSize = 0;
                //            if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                //            else outputHouseholdSize = selectedProduct.getHouseholdSize();
                boolean inputServingSizeStringIsNull = (inputServingSizeString.equals(""));
                boolean inputHouseholdSizeStringIsNull = (inputHouseholdSizeString.equals(""));
                //System.out.println("inputServingSizeStringIsNull = "+inputServingSizeStringIsNull);
                //System.out.println("inputHouseholdSizeStringIsNull = " +inputHouseholdSizeStringIsNull);
    
                // scenario 1: nothing input
                if (inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) {
                    outputServingSize = selectedProduct.getServingSize();
                    outputHouseholdSize = selectedProduct.getHouseholdSize();
                    if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                    if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                }
                // scenario 2: only servingsize
                if (!inputServingSizeStringIsNull && inputHouseholdSizeStringIsNull) {
                    try {
                        outputServingSize = Float.parseFloat(inputServingSizeString);
                        outputHouseholdSize = outputServingSize / selectedProduct.getServingSize()
                                * selectedProduct.getHouseholdSize();
                        if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                        if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
                // scenario 3: only householdsize
                if (inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull) {
                    try {
                        outputHouseholdSize = Float.parseFloat(inputHouseholdSizeString);
                        outputServingSize = outputHouseholdSize / selectedProduct.getHouseholdSize()
                                * selectedProduct.getServingSize();
                        //只改了这一种情况,别的也要改
                        if (selectedProduct.getHouseholdUom().equals("none")) outputServingSize = selectedProduct.getServingSize();
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietHouseholdSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
                // scenario 4: two inputs
                if (!inputServingSizeStringIsNull && !inputHouseholdSizeStringIsNull) {
                    try {
                        outputServingSize = Float.parseFloat(inputServingSizeString);
                        outputHouseholdSize = outputServingSize / selectedProduct.getServingSize()
                                * selectedProduct.getHouseholdSize();
                        if (selectedProduct.getServingSize() == null) outputServingSize = 0;
                        if (selectedProduct.getHouseholdSize() == null) outputHouseholdSize = 0;
                    } catch (NumberFormatException e) {
                        NutriByte.view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
                /* add new product into list */
    
                outputProduct.setHouseholdSize(outputHouseholdSize);
                //System.out.println("outputHouseholdSize = " +outputHouseholdSize);
                outputProduct.setServingSize(outputServingSize);
                outputProduct.setHouseholdUom(selectedProduct.getHouseholdUom());
                outputProduct.setServingUom(selectedProduct.getServingUom());
                //怎么简化lambda, 看来改错了。没错啊?再试试
                //            selectedProduct.getProductNutrients().forEach((k, v) -> {
                //                outputProduct.setProductNutrients(v);
                //            });
                for(Product.ProductNutrient pn : selectedProduct.getProductNutrients().values()) {
                    outputProduct.setProductNutrients(pn);
                }
    
                if(NutriByte.person == null) {            
                    NutriByte.view.dietProductsTableView.getItems().add(outputProduct);
                    //                    System.out.println("person null");
                    return;
                }else {
                    //NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.person.dietProductsList.add(outputProduct);
                    NutriByte.person.populateDietNutrientsMap();
                    NutriByte.view.dietProductsTableView.setItems(NutriByte.person.dietProductsList);
                    NutriByte.view.nutriChart.updateChart();
                }
            }
        }
    
        class RemoveDietButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                // TODO Auto-generated method stub
                //最多改改顺序?看看再说吧
                NutriByte.person.dietProductsList
                .remove(NutriByte.view.dietProductsTableView.getSelectionModel().getSelectedIndex());
                NutriByte.person.dietNutrientsMap.clear();
                NutriByte.person.populateDietNutrientsMap();
                NutriByte.view.nutriChart.clearChart();
                NutriByte.view.nutriChart.updateChart();
            }
        }
    
        class SaveButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                // TODO Auto-generated method stub
                if (NutriByte.view.genderComboBox.getValue() == null) {
                    new InvalidProfileException("Missing gender information");
                }
                if (NutriByte.view.genderComboBox.getValue() != null) {
                    float age = 0, weight = 0, height = 0;
                    //                String gender = NutriByte.view.genderComboBox.getValue();
                    String ageString = NutriByte.view.ageTextField.getText().trim();
                    // age empty exception
                    if (ageString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing age information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        age = Float.parseFloat(ageString);
                        if (age < 0)
                            try {
                                throw (new InvalidProfileException("Age must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect age input. Must be a number");
                        return;
                    }
    
                    String weightString = NutriByte.view.weightTextField.getText().trim();
                    // weight empty exception
                    if (weightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing weight information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        weight = Float.parseFloat(weightString);
                        if (weight < 0)
                            try {
                                throw (new InvalidProfileException("Weight must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect weight input. Must be a number");
                        return;
                    }
    
                    String heightString = NutriByte.view.heightTextField.getText().trim();
                    // height empty exception
                    if (heightString.isEmpty())
                        try {
                            throw (new InvalidProfileException("Missing height information"));
                        } catch (InvalidProfileException e) {
                            // TODO: handle exception
                            return;
                        }
                    try {
                        height = Float.parseFloat(heightString);
                        if (height < 0)
                            try {
                                throw (new InvalidProfileException("Height must be a positive number"));
                            } catch (InvalidProfileException e) {
                                return;
                            }
                    } catch (NumberFormatException e) {
                        new InvalidProfileException("Incorrect height input. Must be a number");
                        return;
                    }
    
                    FileChooser fc = new FileChooser();
                    fc.getExtensionFilters().addAll(new ExtensionFilter("Excel", "*.csv"));
                    fc.setInitialDirectory(new File("profiles/"));
                    File file = null;
                    file = fc.showSaveDialog(new Stage());
                    if (file != null)
                        try {
                            NutriByte.model.writeProfile(file.getPath());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                }
            }
        }
        class CloseMenuButtonHandler implements EventHandler<ActionEvent>{
            @Override
            public void handle(ActionEvent event) {
                NutriByte.view.newNutriProfileMenuItem.fire();
                NutriByte.view.root.setCenter(NutriByte.view.setupWelcomeScene());// TODO Auto-generated method stub
    
            }
        }
    }
    View Code

    自己改错的nutribyte:

    //yuec2 Yue Cheng
    package hw3;
    
    import hw3.NutriProfiler;
    import hw3.RecommendedNutrient;
    import hw3.Product.ProductNutrient;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.beans.binding.ObjectBinding;
    import javafx.beans.binding.StringBinding;
    import javafx.beans.value.ObservableValue;
    
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.TableColumn.CellDataFeatures;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.Background;
    import javafx.scene.layout.BackgroundFill;
    import javafx.scene.layout.CornerRadii;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class NutriByte extends Application{
        static Model model = new Model();      //made static to make accessible in the controller
        static View view = new View();        //made static to make accessible in the controller
        static Person person;                //made static to make accessible in the controller
    
    
        Controller controller = new Controller();    //all event handlers 
    
        /**Uncomment the following three lines if you want to try out the full-size data files */
    //        static final String PRODUCT_FILE = "data/Products.csv";
    //        static final String NUTRIENT_FILE = "data/Nutrients.csv";
    //        static final String SERVING_SIZE_FILE = "data/ServingSize.csv";
    
        /**The following constants refer to the data files to be used for this application */
    
        static final String PRODUCT_FILE = "data/Nutri2Products.csv";
        static final String NUTRIENT_FILE = "data/Nutri2Nutrients.csv";
        static final String SERVING_SIZE_FILE = "data/Nutri2ServingSize.csv";
    
        static final String NUTRIBYTE_IMAGE_FILE = "NutriByteLogo.png"; //Refers to the file holding NutriByte logo image 
        static final String NUTRIBYTE_PROFILE_PATH = "profiles";  //folder that has profile data files
    
        static final int NUTRIBYTE_SCREEN_WIDTH = 1015;
        static final int NUTRIBYTE_SCREEN_HEIGHT = 675;
    
        @Override
        public void start(Stage stage) throws Exception {
            model.readProducts(PRODUCT_FILE);
            model.readNutrients(NUTRIENT_FILE);
            model.readServingSizes(SERVING_SIZE_FILE );
            view.setupMenus();
            view.setupNutriTrackerGrid();
            view.root.setCenter(view.setupWelcomeScene());
            Background b = new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY));
            view.root.setBackground(b);
            Scene scene = new Scene (view.root, NUTRIBYTE_SCREEN_WIDTH, NUTRIBYTE_SCREEN_HEIGHT);
            view.root.requestFocus();  //this keeps focus on entire window and allows the textfield-prompt to be visible
            setupBindings();
            stage.setTitle("NutriByte 3.0");
            stage.setScene(scene);
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        void setupBindings() {
            //add handler on the MenuItems
            view.newNutriProfileMenuItem.setOnAction(controller.new NewMenuItemHandler());
            view.openNutriProfileMenuItem.setOnAction(controller.new OpenMenuItemHandler());
            view.exitNutriProfileMenuItem.setOnAction(event -> Platform.exit());
            view.aboutMenuItem.setOnAction(controller.new AboutMenuItemHandler());
    
            //add Callback values to the columns 
            view.recommendedNutrientNameColumn.setCellValueFactory(recommendedNutrientNameCallback);
            view.recommendedNutrientQuantityColumn.setCellValueFactory(recommendedNutrientQuantityCallback);
            view.recommendedNutrientUomColumn.setCellValueFactory(recommendedNutrientUomCallback);
            view.productNutrientNameColumn.setCellValueFactory(productNutrientNameCallback);
            view.productNutrientQuantityColumn.setCellValueFactory(productNutrientQuantityCallback);
            view.productNutrientUomColumn.setCellValueFactory(productNutrientUomCallback);
    
            //enable the Buttons
            view.createProfileButton.setOnAction(controller.new RecommendNutrientsButtonHandler());
            view.searchButton.setOnAction(controller.new SearchButtonHandler());
            view.productsComboBox.valueProperty().addListener(controller.new ProductsComboBoxListener());
            view.addDietButton.setOnAction(controller.new AddDietButtonHandler());
            view.removeDietButton.setOnAction(controller.new RemoveDietButtonHandler());
            view.clearButton.setOnAction(controller.new ClearButtonHandler());
            view.saveNutriProfileMenuItem.setOnAction(controller.new SaveButtonHandler());
            view.closeNutriProfileMenuItem.setOnAction(controller.new CloseMenuButtonHandler());
    
            //setup automatic recommendedNutrient
            //这里可以不用lambda吗
            recommendedNutrientBinding.addListener((observable,oldPerson,newPerson)->{
            view.productIngredientsTextArea.clear();
            view.productNutrientsTableView.getItems().clear();
                //if the newPerson is not null, give the newPerson's value to person
    //            if(newPerson != null)
    //            {
    //                if(person == null)  person = newPerson;
    //                else{
    //                    //pass the data to the newPerson
    //                    newPerson.dietNutrientsMap = person.dietNutrientsMap;
    //                    newPerson.dietProductsList = person.dietProductsList;
    //                    //clear the former expression
    //                    view.dietProductsTableView.getItems().clear();
    //                    view.nutriChart.clearChart();
    //                    //create new profile
    //                    NutriProfiler.createNutriProfile(newPerson);                    
    //                }
    //                //TableView.setItems
    //                person = newPerson;
    //                view.recommendedNutrientsTableView.setItems(person.recommendedNutrientsList);
    //            }
    //            else {
    //                person = null;
    //                view.recommendedNutrientsTableView.getItems().clear();
    //            }
                if(newPerson == null) {
                    person = null;
                    view.recommendedNutrientsTableView.getItems().clear();
                }else {
                    if(person == null)  person = newPerson;
                    else{
                        //pass the data to the newPerson
                        newPerson.dietNutrientsMap = person.dietNutrientsMap;
                        newPerson.dietProductsList = person.dietProductsList;
                        //clear the former expression
                        view.dietProductsTableView.getItems().clear();
                        view.nutriChart.clearChart();
                        //create new profile
                        NutriProfiler.createNutriProfile(newPerson);                    
                    }
                    //TableView.setItems
                    person = newPerson;
                    view.recommendedNutrientsTableView.setItems(person.recommendedNutrientsList);
                }
            }
            );
            view.dietServingSizeTextField.textProperty().addListener((observable,oldPerson,newPerson)->{
                if(newPerson!=null)
                {
                    view.ageTextField.setStyle("-fx-text-inner-color: black;");
                    try {
                        Float.parseFloat(newPerson);
                    }catch (NumberFormatException e) {
                        // TODO: handle exception
                        view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
            });
            view.dietHouseholdSizeTextField.textProperty().addListener((observable,oldPerson,newPerson)->{
                if(newPerson!=null)
                {
                    view.ageTextField.setStyle("-fx-text-inner-color: black;");
                    try {
                        Float.parseFloat(newPerson);
                    }catch (NumberFormatException e) {
                        // TODO: handle exception
                        view.dietServingSizeTextField.setStyle("-fx-text-inner-color: red;");
                    }
                }
            });
            dietServingBinding.addListener((observable,oldPerson,newPerson)->{
    
            });
            dietHouseholdBinding.addListener((observable,oldPerson,newPerson)->{
    
            });
        }
    
        StringBinding dietServingBinding = new StringBinding() {
            {
                super.bind(view.dietServingSizeTextField.textProperty());
            }
            @Override
            protected String computeValue() {
                // TODO Auto-generated method stub
                TextField textField = view.dietServingSizeTextField;
                float servingSize = 0;
                try {
                    textField.setStyle("-fx-text-inner-color: black;");
                    servingSize = Float.parseFloat(textField.getText().trim());
                    if(servingSize < 0) throw new NumberFormatException();
                }catch (NumberFormatException e) {
                    // TODO: handle exception
                    textField.setStyle("-fx-text-inner-color: red;");
                }
                return String.format("%.2f", servingSize);
            }
        };
    
        StringBinding dietHouseholdBinding = new StringBinding() {
            {
                super.bind(view.dietHouseholdSizeTextField.textProperty());
            }
            protected String computeValue() 
            {
                TextField textField = view.dietHouseholdSizeTextField;
                float servingSize = 0;
                try {
                    textField.setStyle("-fx-text-inner-color: black;");
                    servingSize = Float.parseFloat(textField.getText().trim());
                    if(servingSize<0) throw new NumberFormatException();
                }catch (NumberFormatException e) {
                    // TODO: handle exception
                    textField.setStyle("-fx-text-inner-color: red;");
                }
                return String.format("%.2f", servingSize);
            }
        };
    
    
        ObjectBinding<Person> recommendedNutrientBinding = new ObjectBinding<Person>() {
            {
                super.bind(view.genderComboBox.valueProperty(),view.ageTextField.textProperty(),
                        view.weightTextField.textProperty(),view.heightTextField.textProperty(),view.physicalActivityComboBox.valueProperty());
            }
            @Override
            protected Person computeValue() {
                // TODO Auto-generated method stub
                if (NutriByte.view.genderComboBox.getValue()!=null) {
                    String gender = NutriByte.view.genderComboBox.getValue();
                    String activityLevelstr = NutriByte.view.physicalActivityComboBox.getValue();
                    //activity exception
                    if(activityLevelstr==null) activityLevelstr=NutriProfiler.PhysicalActivityEnum.SEDENTARY.getName();
                    String ingredientsToWatch = NutriByte.view.ingredientsToWatchTextArea.getText();
                    float age,weight,height=0;
                    TextField textfield  = view.ageTextField;
    
                    try {
                        textfield.setStyle("-fx-text-inner-color: black;");
                        age = Float.parseFloat(textfield.getText().trim());
                        if(age<0) throw new NumberFormatException();
                    }catch (NumberFormatException e) {
                        // TODO: handle exception
                        textfield.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }    
                    try {
                        textfield = view.weightTextField;
                        textfield.setStyle("-fx-text-inner-color: black;");
                        weight = Float.parseFloat(view.weightTextField.getText().trim());
                        if(weight <0) throw new NumberFormatException();
                    } catch (NumberFormatException e1) {
                        // TODO: handle exception
                        textfield.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }
                    try {
                        textfield=view.heightTextField;
                        textfield.setStyle("-fx-text-inner-color: black;");
                        height = Float.parseFloat(view.heightTextField.getText().trim());
                        if(height<0) throw new NumberFormatException();
                    } catch (NumberFormatException e2) {
                        // TODO: handle exception
                        view.heightTextField.setStyle("-fx-text-inner-color: red;");
                        return null;
                    }
                    float activityLevel = 0.0f;
                    for (NutriProfiler.PhysicalActivityEnum actEnum : NutriProfiler.PhysicalActivityEnum.values()) {
                        if (actEnum.getName().equals(activityLevelstr))
                            activityLevel = actEnum.getPhysicalActivityLevel();
                    }
    
    
                    if (gender.equals("Male"))
                    {
                        //Person person = new Male(age, weight, height, activityLevel, ingredientsToWatch);
                        //return person;
                        return new Male(age, weight, height, activityLevel, ingredientsToWatch);
                    }
                    if (gender.equals("Female"))
                    {
                        //Person person = new Female(age, weight, height, activityLevel, ingredientsToWatch);
                        //return person;
                        return new Female(age, weight, height, activityLevel, ingredientsToWatch);
                    }
    
                }
    
                return null;
            }
        };
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientNameCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                Nutrient nutrient = Model.nutrientsMap.get(arg0.getValue().getNutrientCode());
                return nutrient.nutrientNameProperty();
            }
        };
    
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientQuantityCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                return arg0.getValue().NutrientQuantityProperty().asString("%.2f");    //set NutrientQuantity to according column    
            }
        };
    
    
        Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>> recommendedNutrientUomCallback = new Callback<CellDataFeatures<RecommendedNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<RecommendedNutrient, String> arg0) {
                Nutrient nutrient = Model.nutrientsMap.get(arg0.getValue().getNutrientCode());
                return nutrient.getNutrientUom();//set nutrientUom to according column
            }
        };
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientNameCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                // TODO Auto-generated method stub
                return Model.nutrientsMap.get(arg1.getValue().getNutrientCode()).nutrientNameProperty();
            }
        };
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientQuantityCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                // TODO Auto-generated method stub
                return arg1.getValue().NutrientQuantityProperty().asString("%.2f");
            }
        };
        Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>> productNutrientUomCallback = new Callback<CellDataFeatures<Product.ProductNutrient, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ProductNutrient, String> arg1) {
                // TODO Auto-generated method stub
                return Model.nutrientsMap.get(arg1.getValue().getNutrientCode()).getNutrientUom();
            }
        };
    
    }
    View Code

    完整有效的profile数据: 可是为啥点rec就变数了?

    蛋白棒:柱形图的比例不对,表格里两个size也不对

    年龄-20存档的时候要保持红色,

    valid文件打开后没有3 products found, 怎么打开啊?search的时候是239089条记录

    我自己写的感觉比较原生态,完全没有exception。加exception感觉会加的差不多。能改变思路么?空-有效性,好像不能改啊。变量的顺序甚至都不好改……。判断是不是数字的办法只有把它转为float的时候失败才算吗?不是吧

    我自己原来的controller

    //yuec2 Yue Cheng
    package hw3;
    
    import java.io.File;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.event.ActionEvent;
    import javafx.stage.FileChooser;
    import javafx.event.EventHandler;
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    
    public class Controller {
        //use the RecommendNutrientsButtonHandler to load the nutrients information 
        class RecommendNutrientsButtonHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //initialize the age to 0 in case of empty input
                float age = 0;
                //if the input is not empty, get the age from the TextField
                if (!NutriByte.view.ageTextField.getText().equals(""))
                    age = Float.parseFloat(NutriByte.view.ageTextField.getText());
                //initialize the weight to 0 in case of empty input
                float weight = 0;
                //if the input is not empty, get the weight from the TextField
                if (!NutriByte.view.weightTextField.getText().equals(""))
                    weight = Float.parseFloat(NutriByte.view.weightTextField.getText());
                //initialize the height to 0 in case of empty input
                float height = 0;
                //if the input is not empty, get the height from the TextField
                if (!NutriByte.view.heightTextField.getText().equals(""))
                    height=Float.parseFloat(NutriByte.view.heightTextField.getText());
                //initialize the gender to "" in case of empty input
                String gender = "";
                //if the input is not empty, get the gender from the ComboBox
                if (NutriByte.view.genderComboBox.getValue() != null)
                    gender = NutriByte.view.genderComboBox.getValue();
                //initialize the physicalActivityLevel to 0f in case of empty input
                float physicalActivityLevel=0f;
                //if the input is not empty, get the string from the ComboBox and change to according physicalActivityLevel
                if(NutriByte.view.physicalActivityComboBox.getValue() == null)
                    physicalActivityLevel= 1.0f;
                if(NutriByte.view.physicalActivityComboBox.getValue() != null && NutriByte.view.physicalActivityComboBox.getValue().equals("Sedentary")) {
                    physicalActivityLevel = 1.0f;}
                if(NutriByte.view.physicalActivityComboBox.getValue() != null && NutriByte.view.physicalActivityComboBox.getValue().equals("Low active")) {
                    physicalActivityLevel = 1.1f;   
                }
                if(NutriByte.view.physicalActivityComboBox.getValue() != null && NutriByte.view.physicalActivityComboBox.getValue().equals("Active")) {
                    physicalActivityLevel = 1.25f;   
                }
                if(NutriByte.view.physicalActivityComboBox.getValue() != null && NutriByte.view.physicalActivityComboBox.getValue().equals("Very active")) {
                    physicalActivityLevel = 1.48f;   
                }
                //get the string from ingredientsToWatchTextArea and serve as ingredientsToWatch
                String ingredientsToWatch=NutriByte.view.ingredientsToWatchTextArea.getText();
                //create profile according to different gender for a person
                if(gender.equals("Male")) {
                    //new a person as a male
                    //Person person=new Male(age, weight, height, physicalActivityLevel,ingredientsToWatch);
                    //calculate the information 
                    NutriByte.person.calculateEnergyRequirement();
                    NutriByte.person.calculateNutriRequirement();
                    //create the person's profile
                    NutriProfiler.createNutriProfile(NutriByte.person);
                    NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                }
                if(gender.equals("Female")) {
                    //new a person as a female
                    Person person=new Female(age, weight, height, physicalActivityLevel,ingredientsToWatch);
                    //calculate the information
                    person.calculateEnergyRequirement();
                    person.calculateNutriRequirement();
                    //create the person's profile
                    NutriProfiler.createNutriProfile(person);
                    NutriByte.view.recommendedNutrientsTableView.setItems(person.recommendedNutrientsList);
                }
                //load the recommendedNutrientsList's information onto the recommendedNutrientsTableView in order to show
                NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
            }
        }
        //use the OpenMenuItemHandler to open file and show the information 
        class OpenMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) { 
                //define a new FileChooser and name it to open file
                FileChooser chooser = new FileChooser();
                chooser.setTitle("Open File");
                //open a file using the filechooser
                File file = chooser.showOpenDialog(null);
    //            String filename = file.getName();        
    //            try{
    //                if (file == null) throw new InvalidProfileException(filename); 
    //            }catch(InvalidProfileException e) {
    //                System.out.println("wrong");
    //            }
                if (file != null) {
                    //read from the absolute path
                    if(NutriByte.model.readProfiles(file.getAbsolutePath())) {
                        //calculate the information
                        if (NutriByte.person != null) {
                        NutriByte.person.calculateEnergyRequirement();
                        NutriByte.person.calculateNutriRequirement();
                        //create the person's profile
                        NutriProfiler.createNutriProfile(NutriByte.person);
                        //load the recommendedNutrientsList's information onto the recommendedNutrientsTableView in order to show
                        NutriByte.view.recommendedNutrientsTableView.setItems(NutriByte.person.recommendedNutrientsList);
                        }
                        }
                }
                //put the nutriTrackerPane on to the center
                NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
            }
        }
        //use the NewMenuItemHandler to clear the old information and open up another pane 
        class NewMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                //clear all the items on the recommendedNutrientsTableView
                NutriByte.view.recommendedNutrientsTableView.getItems().removeAll();
                //clear the former recommendedNutrientsList's information
                //should be new object's list
                //if(NutriByte.person != null)
                //NutriByte.person.recommendedNutrientsList.clear();
    
                //clear the NutriChart
                NutriByte.view.nutriChart.clearChart();
                //clear the former NutriChart's list
                //should be new object's list
                NutriByte.view.nutriChart.actualDataList.clear();
                NutriByte.view.nutriChart.recommendedDataList.clear();
                NutriByte.view.nutriChart.actualDataList.clear();
    
                //put the nutriTrackerPane on to the center
                NutriByte.view.root.setCenter(NutriByte.view.nutriTrackerPane);
                //initialize a new menu
                NutriByte.view.initializePrompts();
            }
        }
        //use the AboutMenuItemHandler to open file and show the information 
        //the professor wrote this already
        class AboutMenuItemHandler implements EventHandler<ActionEvent> {
            @Override
            public void handle(ActionEvent event) {
                Alert alert = new Alert(AlertType.INFORMATION);
                alert.setTitle("About");
                alert.setHeaderText("NutriByte");
                alert.setContentText("Version 2.0 
    Release 1.0
    Copyleft Java Nerds
    This software is designed purely for educational purposes.
    No commercial use intended");
                Image image = new Image(getClass().getClassLoader().getResource(NutriByte.NUTRIBYTE_IMAGE_FILE).toString());
                ImageView imageView = new ImageView();
                imageView.setImage(image);
                imageView.setFitWidth(300);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                alert.setGraphic(imageView);
                alert.showAndWait();
            }
    
            class CloseMenuItemHandler implements EventHandler<ActionEvent> {
    
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
                    
                }
    
            }
    
            class SaveMenuItemHandler implements EventHandler<ActionEvent> {
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
                    //FileChooser fc = new FileChooser();
                    
                }
    
            }
    
            class SearchButtonHandler implements EventHandler<ActionEvent> {
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
                    
                }
            }
            //Clears product,nutrient,and ingredient search boxes and all products from the productsComboBox
            class ClearButtonHandler implements EventHandler<ActionEvent> {
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
                    //.productNutrients.clear();
                    View view = new View();
                    view.ageTextField.clear();
                    view.weightTextField.clear();
                    view.heightTextField.clear();
                    view.ingredientsToWatchTextArea.clear();
                    //how to clear this? view.genderComboBox
                    
                }
            }
    
            class AddDietButtonHandler implements EventHandler<ActionEvent> {
    
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
    
                }
    
            }
    
            class ProductComboBoxListener implements ChangeListener<String> {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                    // TODO Auto-generated method stub
    
                }
    
            }
    
            class RemoveDietButtonHandler implements EventHandler<ActionEvent> {
                @Override
                public void handle(ActionEvent event) {
                    // TODO Auto-generated method stub
                    
                }
    
            }
    
        }
    
    }
    View Code

    为啥profile营养数量有错检测不出来啊?!

    case

    console不能报错

    • new profile 

    输入三个变量以后aclevel自动变成secondary,自动生成推荐营养。后面的改动也会导致自动变化。

    • search

    输入一个product,搜出结果来。指定有protein的:结果更少。指定有ingredient的:结果更少。clear之后左下全部清零。

    全为0时点search,出现43个产品。vitamin a + salt = 12 + olive oil = 1

    • add

    protein bar - 2 - add - 出结果, 百分比 = actual / recm * 100%,输入size后,hoseholdsize 随即变化

    remove product from diet 柱子随即减少,左边的推荐营养不减少

    • save

    加两个产品,然后save,存一个新的CSV文件名 APP内部点close,内部open存了的那个文件,恢复原来的数据

    •  Exception handling in profile user input 

    age twenty红字,退格后回到黑字,三个变量都要

    • rec exception

    输入不对的时候,红框指出第一个发生的错误。注意下:没有事missing,格式不对是incorrect。-30:must be a positive number。

    三个变量都对之后,立马动态产生推荐营养。

    • profile exception

    打开那个valid的文件:注意下,4个大框全都有数。

    missing gender - 红框(记得改一下提示语句) - 注意下,然后还有一个红框!(此时后面的背景都是空的)

    only person:第一个大框里有数。close以后回到盘子界面。

    • product exception

    无效product number - 红框(记得改一下提示语句)- 四个框全有数 - 

    无效quantity - 只有第一个大框里有数 - OK以后4个大框里全有数,回到原来值  - close后回到盘子界面

    •  save exception

    不给gender就save 出红框。missing 三个变量也出红框。注意下,变量输入错误还是红字。负数还是红框提示positive。

    • 大文件exception

    打开validate全能文件 - remove所有product -  柱形图消失  -

    clear search - 区域2消失 - 点击search - 等一阵 - 出现239089个product - 

    搜索bread protein chocolate,出现85个产品,添加一个大老鹰面包

    clear

    搜索名为NATURE的产品,因为serving size是0所以柱形图不动,

    搜索TRADITIONAL GREEK YOUGURT,因为househoudesize = 0,serving size不等于,所以柱形图会动

     

     

     

    list.get(0) = CSVRecord [comment=null, mapping=null, recordNumber=1, values=[Female,  25,  55,  160,  1.48,  chocolate,  peanut]]怎么用这个来新建person啊

     

    -------总之就是controller有问题

    【问题1:new以后有问题,不知道怎么处理】

    检查一下空文件的效果: 【问题2:不对,应该出两个框,这里只出了一个】

    【问题3:test case飘红,看得我急死了】

    【问题1】

    populateDietNutrientMap里的RecommendedNutrient是从哪里取出来的啊?AddDietButtonHandler的也要存吗?

    先从pn里面拿code和名字,再存一遍

    说是对的,没有清单吗不过? 

    唉不想写了,自己写什么都不会,没人讨论,完全是在虚度。算了,先写数据库吧hhh。

    自己写的错误百出的cvsfiler

     

    //yuec2 Yue Cheng
    package hw3;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Scanner;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableMap;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.control.Alert;
    
    public class CSVFiler extends DataFiler implements EventHandler<ActionEvent>{
        static ObservableMap<String, Product> productsMap = FXCollections.observableHashMap();
    
        @Override
        public void writeFile(String filename) {
            // TODO Auto-generated method stub
            //write your code here
            Scanner input = new Scanner(System.in);
            String[] next = null;
            try (
                    BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
                    ){
                do {
                    next = input.nextLine().split("\s+");
                    //
                    bw.write(String.format("%s,%f,%f,%f,%f", next[0], next[1], next[2], next[3], next[4]));
                } while (!next[next.length-1].equals("*"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            //close here is a best practice
            finally {
                input.close();
            }
        }
    
        Person validatePersonData(String data) {
            try {
                String gender;
                float age, weight, height, pa = 0;
                //check if data is null
                if (data == null || data.isEmpty()) throw new InvalidProfileException("Input is Empty");
                String[] personInfo = data.split(",");
    
                //check gender information
                if (personInfo[0].trim().toLowerCase().equals("female")) {
                    gender = "Female";
                }else if (personInfo[0].trim().toLowerCase().equals("male")) {
                    gender = "Male";
                }else {
                    throw new InvalidProfileException("The profile must have gender: Female or Male as first word");
                }
    
                //right or not?
                //age
                try {
                    age = Float.parseFloat(personInfo[1]);
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Age:" + personInfo[1] + "
    Age must be a number");
                }
    
                //weight
                try {
                    weight = Float.parseFloat(personInfo[2]);
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Weight:" + personInfo[2] + "
    Weight must be a number");
                }
    
                //height
                try {
                    height = Float.parseFloat(personInfo[3]);
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Height:" + personInfo[3] + "
    Height must be a number");
                }
    
                //physical activitylevel
                //check gender information
                System.out.println("pa = " + pa);
                if (personInfo[4].trim().equals("1.0")) {
                    pa = (float) 1.0;
                }else if (personInfo[4].trim().equals("1.1")) {
                    pa = (float) 1.1;
                }else if (personInfo[4].trim().equals("1.25")) {
                    pa = (float) 1.25;
                }else if (personInfo[4].trim().equals("1.48")) {
                    pa = (float) 1.48;
                }
                else {
                    throw new InvalidProfileException("Invalid data for PhysicalActivityLevel:" + personInfo[4] + "Must be : 1.0, 1.1, 1.25 or 1.48");
                }
    
                //create people
                if (gender.equalsIgnoreCase("female")) {
                    return new Female(age, weight, height, pa, personInfo[5]);
                }
                if (gender.equalsIgnoreCase("male")) {
                    return new Male(age, weight, height, pa, personInfo[5]);
                }
                return null;
            } catch(InvalidProfileException e) {
                //
                return null;
            }
        }
    
        Product validateProductData(String data) {
            //why can't print
            System.out.print("data = " + data);
            String[] productLine = data.split("
    ");
            //add each line to the list
            List<String> list = new ArrayList<>();
            for (int i = 0; i < productLine.length; i++) {
                list.add(productLine[i]);
            }
            //use iter to handle exception
            Iterator<String> iter = list.iterator();
            //if iter is null, display the first people
            while (iter.hasNext()) {
                String eachProductLine = iter.next();
                String[] productData = eachProductLine.split("	");
                try {
                    //ProductNumber
                    if (productData[0] == null || (!productsMap.containsKey(Integer.parseInt(productData[0])))) throw new InvalidProfileException("No product found with this code: " + productData[0]);
                    //ProductQuantity
                } catch (InvalidProfileException | NullPointerException e) {
                    iter.next();
                }
    
            }
            return null;
        }
    
        @SuppressWarnings("unused")
        @Override
        public
        boolean readFile(String filename) {
            //define the csvFormat to the default value
            CSVFormat csvFormat = CSVFormat.DEFAULT; 
            try {
                //define a csvParser to read the cvs file
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat); 
                //load the results into the CSVRecord list
                List<CSVRecord> list = csvParser.getRecords();
                //load the variable's value from the CSVRecord list
                //check gender information
                if (list.get(0).get(0).trim().toLowerCase().equals("female")) {
                    String gender = "Female";
                }else if (list.get(0).get(0).trim().toLowerCase().equals("male")) {
                    String gender = "Male";
                }else {
                    throw new InvalidProfileException("The profile must have gender: Female or Male as first word");
                }
                String gender = list.get(0).get(0).trim();
                
                //age
                try {
                    float age = Float.parseFloat(list.get(0).get(1));
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Age:" + list.get(0).get(1) + "
    Age must be a number");
                }
                float age = Float.parseFloat(list.get(0).get(1).trim());
                
                //weight
                try {
                    float weight = Float.parseFloat(list.get(0).get(2));
                    //throw new InvalidProfileException("Invalid data for Weight:" + list.get(0).get(2) + "
    Weight must be a number");
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Weight:" + list.get(0).get(2) + "
    Weight must be a number");
                }
                float weight = Float.parseFloat(list.get(0).get(2).trim());
                
                //height
                try {
                    float height = Float.parseFloat(list.get(0).get(3));
                }catch(NumberFormatException e) {
                    throw new InvalidProfileException("Invalid data for Height:" + list.get(0).get(3) + "
    Height must be a number");
    }
                float height = Float.parseFloat(list.get(0).get(3).trim());
                
                if (list.get(0).get(4).trim().equals("1.0")) {
                    float activity = (float) 1.0;
                }else if (list.get(0).get(4).trim().equals("1.1")) {
                    float activity = (float) 1.1;
                }else if (list.get(0).get(4).trim().equals("1.25")) {
                    float activity = (float) 1.25;
                }else if (list.get(0).get(4).trim().equals("1.48")) {
                    float activity = (float) 1.48;
                }
                else {
                    throw new InvalidProfileException("Invalid data for PhysicalActivityLevel:" + list.get(0).get(4) + "
    Must be : 1.0, 1.1, 1.25 or 1.48");
                }
                float activity = Float.parseFloat(list.get(0).get(4).trim());
                //initialize a stringbuilder to append the information
                StringBuilder sb = new StringBuilder();
                //append each individual person's information to one stringbuilder
                list.get(0).size();
                for (int i = 5; i < list.get(0).size(); i++) {
                    sb.append(list.get(0).get(i) + ",");
                }
                //append empty string to the end 
                if (sb.length() > 0) 
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                //get the ingredientsToWatch from the sb
                String ingredientsToWatch = sb.toString();
                //create new person object according to their gender
                //return true if created 
                if (gender.equals("Female")) {
                    NutriByte.person = new Female(age, weight, height, activity, ingredientsToWatch);
                    return true;
                }
                if (gender.equals("Male")) {
                    NutriByte.person = new Male(age, weight, height, activity, ingredientsToWatch);
                    return true;
                }
            } 
            catch (InvalidProfileException e1) {e1.printStackTrace();return false;}
            catch(NumberFormatException e1) {throw new InvalidProfileException("");}
            catch (FileNotFoundException e1) { e1.printStackTrace();return false;}
            catch (IOException e1) { e1.printStackTrace();} return false;}
    
        @Override
        public void handle(ActionEvent event) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

    自己昨晚改了好多的csvfiler

    //yuec2 Yue Cheng
    package hw3;
    
    
    import java.util.List;
    import java.util.Scanner;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableMap;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    
    public class CSVFiler extends DataFiler implements EventHandler<ActionEvent>{
        static ObservableMap<String, Product> productsMap = FXCollections.observableHashMap();
    
        public boolean readFile(String filename) {
    
            CSVFormat csvFormat = CSVFormat.DEFAULT;
            try {
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat);
                List<CSVRecord> list = csvParser.getRecords();
                StringBuilder sb = new StringBuilder();
    
                for(int i = 0; i < list.size(); i++)
                {
                    for (int j = 0; j < list.get(i).size(); j++) {
                        sb.append(list.get(i).get(j));
                        sb.append(",");
                    }
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                    sb.append("
    ");
                }
                //populate stringbuilder with each row
                /*load person data*/
                String[] csvInfo = sb.toString().split("
    ");
                System.out.println("csvInfo[0] = " + csvInfo[0]);
    
                NutriByte.person = validatePersonData(csvInfo[0]);
    
                System.out.println("NutriByte.person.age = "+NutriByte.person.age);
                /*load diet data*/
                for (int i = 1; i < csvInfo.length; i++)
                {
                    Product csvProduct = validateProductData(csvInfo[i]);
                    NutriByte.person.dietProductsList.add(csvProduct);
                }
                System.out.println("person.age = " + NutriByte.person.age);
            }catch(InvalidProfileException e1)
            {
                //System.out.println("Error");
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
                return false;
            } catch (IOException e1) {
                e1.printStackTrace();
                return false;
            } 
            return false;
        }
    
        @Override
        public void writeFile(String filename) {
            // TODO Auto-generated method stub
            //write your code here
            Scanner input = new Scanner(System.in);
            String[] next = null;
            try (
                    BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
                    ){
                do {
                    next = input.nextLine().split("\s+");
                    //
                    bw.write(String.format("%s,%f,%f,%f,%f", next[0], next[1], next[2], next[3], next[4]));
                } while (!next[next.length-1].equals("*"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            //close here is a best practice
            finally {
                input.close();
            }
        }
    
        Person validatePersonData(String data)
        {
            String[]wordsInData = data.split(",");
            try {
                if(!wordsInData[0].trim().equals("Male") && !wordsInData[0].trim().equals("Female")) 
                    throw (new InvalidProfileException("The profile must have gender: Female or Male as first word"));
    
                try{
                    Float.valueOf(wordsInData[1].trim());
                }catch(NumberFormatException e1) {
                    throw (new InvalidProfileException("Invalid data for Age:" + wordsInData[1] + "
    Age must be a number"));
                }
    
                try{
                    Float.valueOf(wordsInData[2].trim());
                }catch(NumberFormatException e1) {
                    throw (new InvalidProfileException("Invalid data for Weight:" + wordsInData[2] + "
    Weight must be a number"));
                }
    
                try{
                    Float.valueOf(wordsInData[3].trim());
                }catch(NumberFormatException e1) {
                    throw (new InvalidProfileException("Invalid data for Height:" + wordsInData[3] + "
    Height must be a number"));
                }
                System.out.println("Float.parseFloat(wordsInData[4].trim()) = " + Float.parseFloat(wordsInData[4].trim()));
                boolean flag = (Float.parseFloat(wordsInData[4].trim()) == 1.48);
                System.out.println(flag);
                //why?
                if(Float.parseFloat(wordsInData[4].trim()) != 1.0 && 
                   Float.parseFloat(wordsInData[4].trim()) != 1.1 &&
                   Float.parseFloat(wordsInData[4].trim()) != 1.25 &&
                   Float.parseFloat(wordsInData[4].trim()) != 1.48)
                    throw (new InvalidProfileException("Invalid data for PhysicalActivityLevel:" + wordsInData[4] + "
    Must be : 1.0, 1.1, 1.25 or 1.48"));
    
                StringBuilder sb = new StringBuilder();
                for (int i= 5;i < wordsInData.length; i++){
                    sb.append(wordsInData[i]);
                    sb.append(",");
                }
                sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                String ingredientsToWatch = sb.toString();
    
                switch(wordsInData[0]) {
                case "Male":
                    return new Male(Float.valueOf(wordsInData[1].trim()),Float.valueOf(wordsInData[2].trim()),
                            Float.valueOf(wordsInData[3].trim()),Float.valueOf(wordsInData[4].trim()),ingredientsToWatch);
                case "Female":
                    return new Female(Float.valueOf(wordsInData[1].trim()),Float.valueOf(wordsInData[2].trim()),
                            Float.valueOf(wordsInData[3].trim()),Float.valueOf(wordsInData[4].trim()),ingredientsToWatch);
                }            
            }catch(InvalidProfileException e1) {
                throw (new InvalidProfileException("Could not read profile data."));}
            return null;
        }
    
        Product validateProductData(String data) {
            String[] wordsInData = data.split(",");
            // ensure ndbnumber is valid
            boolean notExist = true;
            for (String key : Model.productsMap.keySet()) {
                if (key.equals(wordsInData[0]))
                    notExist = false;
            }
            if (notExist)
                throw (new InvalidProfileException("No product found with this code: " + wordsInData[0]));
            
            // judge missing
            if (wordsInData.length == 3) {
                try {
                    //judge invalid 
                    Float.valueOf(wordsInData[1]);
                    //also necessary?
                    Float.valueOf(wordsInData[2]);
                } catch (NumberFormatException e1) {
                    throw (new InvalidProfileException("Cannot read: " + wordsInData[1] + 
                            "
    The data must be - String number, number - for ndb number, serving size, household size"));}
            }else {throw (new InvalidProfileException("Cannot read: " + wordsInData[0] + "," + wordsInData[1] + 
                    "
    The data must be - String number, number - for ndb number, serving size, household size"));}
    
            return null;
        }
    
        @Override
        public void handle(ActionEvent event) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

     

    LXJ CVSfiler

     

    //yuec2 Yue Cheng
    package hw3;
    
    
    import java.util.List;
    import java.util.Scanner;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableMap;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    
    public class CSVFiler extends DataFiler implements EventHandler<ActionEvent>{
        static ObservableMap<String, Product> productsMap = FXCollections.observableHashMap();
    
        public boolean readFile(String filename) {
    
            CSVFormat csvFormat = CSVFormat.DEFAULT;
            try {
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat);
                List<CSVRecord> list = csvParser.getRecords();
                StringBuilder sb = new StringBuilder();
                for(CSVRecord records:list)
                {
                    for(String columnContent:records)
                    {
                        sb.append(columnContent+",");
                    }
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                    sb.append("
    ");
                }//populate stringbuilder with each row
                /*load person data*/
                String[] rows = sb.toString().split("
    ");
                System.out.println("rows[0] = " + rows[0]);
                Person person = validatePersonData(rows[0]);
                NutriByte.person = person;
                System.out.println("called");
                //not called
                System.out.println("NutriByte.person.age = "+NutriByte.person.age);
                /*load diet data*/
                for(int i=1;i<rows.length;i++)
                {
                    Product dietProduct = validateProductData(rows[i]);
                    NutriByte.person.dietProductsList.add(dietProduct);
                }
                System.out.println("person.age = " +person.age);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
                return false;
            } catch (IOException e1) {
                e1.printStackTrace();
                return false;
            } catch(InvalidProfileException e1)
            {
                System.out.println("Error");
            }
            return false;
        }
    
        @Override
        public void writeFile(String filename) {
            // TODO Auto-generated method stub
            //write your code here
            Scanner input = new Scanner(System.in);
            String[] next = null;
            try (
                    BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
                    ){
                do {
                    next = input.nextLine().split("\s+");
                    //
                    bw.write(String.format("%s,%f,%f,%f,%f", next[0], next[1], next[2], next[3], next[4]));
                } while (!next[next.length-1].equals("*"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            //close here is a best practice
            finally {
                input.close();
            }
        }
    
        Person validatePersonData(String data)
        {
            String[]column = data.split(",");
    
            if(!column[0].trim().equals("Male")&&!column[0].trim().equals("Female")) throw (new InvalidProfileException("Gender error"));
            try{
                String age = column[1].trim();
                Float.parseFloat(age);
            }catch(RuntimeException e1) {
                throw (new InvalidProfileException("Age error: "+column[1]));
            }
            try{
                Float.parseFloat(column[2].trim());
            }catch(RuntimeException e1) {
                throw (new InvalidProfileException("Weight error: "+column[2]));
            }
            try{
                Float.parseFloat(column[3].trim());
            }catch(RuntimeException e1) {
                throw (new InvalidProfileException("Height error: "+column[3]));
            }
            if(Float.parseFloat(column[4].trim())!=1f&&Float.parseFloat(column[4].trim())!=1.1f&&
                    Float.parseFloat(column[4].trim())!=1.25f&&Float.parseFloat(column[4].trim())!=1.48f)
                throw (new InvalidProfileException("Activity error: "+Float.parseFloat(column[4])));
            StringBuilder sb = new StringBuilder();
            for(int i=5;i<column.length;i++)
            {
                sb.append(column[i]+",");
            }
            sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
            String ingredients = sb.toString();
            if(column[0].equals("Male"))
            {
                return (new Male(Float.parseFloat(column[1].trim()),Float.parseFloat(column[2].trim()),
                        Float.parseFloat(column[3].trim()),Float.parseFloat(column[4].trim()),ingredients));
            }
            else
                return (new Female(Float.parseFloat(column[1].trim()),Float.parseFloat(column[2].trim()),
                        Float.parseFloat(column[3].trim()),Float.parseFloat(column[4].trim()),ingredients));
        }
    
        Product validateProductData(String data) {
            String[] columnData = data.split(",");
            // ensure ndbnumber is valid
            if (!Model.productsMap.containsKey(columnData[0]))
                throw (new InvalidProfileException("ndbNumber invalid"));
    
            if (columnData.length == 3) {
                try {
                    Float.parseFloat(columnData[1]);
                } catch (RuntimeException e1) {
                    throw (new InvalidProfileException("quantity invalid"));}
            }else {throw (new InvalidProfileException("quantity invalid"));}
            
            return null;}
    
    
    
        @Override
        public void handle(ActionEvent event) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

     

     

     

     

     

    【search function】

    怎么写啊我去,先看视频吧还是。看懂了,for循环吗?之前有例子吗?没有诶,自己写两句吧。

    是从model里拿和放东西,好吧。可是输入的字符串是哪里来的啊?

    【save memu】

    看上去好复杂啊,完全不会啊,妈的。好想直接复制粘贴……真是太复杂了,自己瞎写肯定写不出来。先看看视频8。

    那就从FC先开始写好咯?person要处理exception 然后用CSV Write

    感觉写不出来完全就是在浪费时间,但是吧,不写几个字又不甘心。还是算了吧,自己瞎写不如抱大腿。

    【openmenu】

    好像挺麻烦的呢,唉。好像要打开、计算?啥意思啊,我去。 加exception?这里怎么加啊,之前的都写不对,唉,我去。该不该先把之前的搞对再说哦?

    后面的几个handler都和shit一样啊,妈的。

    再看看内俩案例吧。处理输入输出数字的exception和处理文件的,应该不一样8?真不一样,还是看看课件8

    课件里都是处理数字输入的exception啊,并不是读文件,但是都是把错误的语句放在try中

    所以应该是判断文件非空吧,我觉得。应该是的,不过不知道应该往哪里输出,要看看以前的menu往哪里输出吧,我觉得。就是推荐营养那里。所以在哪里打印异常呢?再看看视频。就是和CSVFILER一样,4个变量都要处理,输出到红框框里,不过我真没有找到红框框的view在哪里啊。而且不是说是判断文件的异常吗,怎么视频里就要判断输入输出的异常了呢?哦,这是【recommendednutrient】,一样的道理,那就先不写吧。


    【newmenu】

    怎么往newmenu里面加chart啊,我去,应该和list类似吧?实例给view了?我咋没看见呢。看见了。不过要clear哪些东西啊,还要添加配置么。 view好像都没变的,就不用再controller里面新建了吧。那new就先这样。

    清理chart好像直接用就行了8,不过我为了保险起见还是把它的几个list都清理掉了。

    【我在写exception】

    validate product这个,读到下一行,是什么鬼。怎么换行啊,用n吗。不论怎么分隔,好像和我之前的结果一样,是什么鬼。 那就随意咯?先用n来写好了。然后用iter? 不让我用是咋回事,傻逼吧。必须要list, 数组不行。那就先加到list里面咯?可以了哈哈哈。

    先不写,跑跑效果试一试。好吧,不写果然没有exception,天下没有免费的exception,好吧hhh. 

    validateProduct应该只要管product就好了吧

    如果全是空的,反而没有exception了,是这个意思吗?

    突然想试试case了,看是哪里不过……不能建立nurtibyte是什么鬼阿。先修修这类吧?好像是因为exception,那就写exception先咯。可是我exception写不对啊……先试试吧

    productNUMBER找不到是啥意思啊,去哪里找?好像是productMap

    写错了,没有catch到。。不会。。。5555

    感觉我这想法不是特别对,算了,明天问问助教

    下午写界面,然后看看

    【问题1】

    exception就是不知道怎么打印到小框框Field里,没找到.

    范围是什么啊?还是自己瞎编就行啊。发现missing gender也没写诶,性别是第0位吗 究竟还是身高?性别,好吧

    我需要看看视频中的正确提示语句再写. 怎么感觉视频里的界面更复杂?我去,再看看。发现下面一行字应该在exception括号里。

    那括号里为啥还要嵌入数据啊我去……用加号就行,好吧。

    原来only person而没有产品的时候不会throw exception,好吧。

    好,这个exception差不多就这样吧,看看界面怎么搞出来。就是上面4个变量都要判断,不对就显示红框框,和CSVFiler一样不会,不知道红框框在哪里啊

    自己写的错filer

    //yuec2 Yue Cheng
    package hw3;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Scanner;
    import java.io.BufferedWriter;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    
    
    import org.apache.commons.csv.CSVFormat;
    import org.apache.commons.csv.CSVParser;
    import org.apache.commons.csv.CSVRecord;
    
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableMap;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.control.Alert;
    
    public class CSVFiler extends DataFiler implements EventHandler<ActionEvent>{
        static ObservableMap<String, Product> productsMap = FXCollections.observableHashMap();
    
        @Override
        public void writeFile(String filename) {
            // TODO Auto-generated method stub
            //write your code here
            Scanner input = new Scanner(System.in);
            String[] next = null;
            try (
                    BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
                    ){
                do {
                    next = input.nextLine().split("\s+");
                    //
                    bw.write(String.format("%s,%f,%f,%f,%f", next[0], next[1], next[2], next[3], next[4]));
                } while (!next[next.length-1].equals("*"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            //close here is a best practice
            finally {
                input.close();
            }
        }
    
        Person validatePersonData(String data) {
            //why can't print
            System.out.print("data = " + data);
            String[] personInfo = data.split("	");
    
            try {
                //gender
                if (personInfo[0] == null || ((!personInfo[0].equals("Male")) && (!personInfo[0].equals("Female")))) throw new InvalidProfileException("The profile must have gender Female or Male as first word");
                //age
                if (personInfo[1] == null || Integer.parseInt(personInfo[1]) > 200 || Integer.parseInt(personInfo[0]) < 0) throw new InvalidProfileException("Invalid data for Age:" + personInfo[1] + " Age must be a number");
                //weight
                if (personInfo[2] == null || Integer.parseInt(personInfo[2]) > 500 || Integer.parseInt(personInfo[0]) < 0) throw new InvalidProfileException("Invalid data for Weight:" + personInfo[2] + " Weight must be a number");
                //height
                if (personInfo[3] == null || Integer.parseInt(personInfo[3]) > 200 || Integer.parseInt(personInfo[3]) < 0) throw new InvalidProfileException("Invalid data for Height:" + personInfo[3] + " Height must be a number");
                //activity level
                if (personInfo[4] == null || ((Float.valueOf(personInfo[4]) != 1.0) && (Float.valueOf(personInfo[4]) != 1.1) && (Float.valueOf(personInfo[4]) != 1.25) && (Float.valueOf(personInfo[4]) != 1.48))) throw new InvalidProfileException("Invalid physical activity level:" + personInfo[4] + "
     Must be 1.0 1.1 1.23 or 1.48");
            } catch (InvalidProfileException | NullPointerException e) {
    //            Alert alert = new Alert(Alert.AlertType.ERROR);
    //            alert.setTitle("Could not read profile data");
                //mortgageValue.setText("Could not read profile data");
                System.out.println("Could not read profile data");
            }
            return null;
        }
    
        Product validateProductData(String data) {
            //why can't print
            System.out.print("data = " + data);
            String[] productLine = data.split("
    ");
            //add each line to the list
            List<String> list = new ArrayList<>();
            for (int i = 0; i < productLine.length; i++) {
                list.add(productLine[i]);
            }
            //use iter to handle exception
            Iterator<String> iter = list.iterator();
            //if iter is null, display the first people
            while (iter.hasNext()) {
                String eachProductLine = iter.next();
                String[] productData = eachProductLine.split("	");
                try {
                    //ProductNumber
                    if (productData[0] == null || (!productsMap.containsKey(Integer.parseInt(productData[0])))) throw new InvalidProfileException("No product found with this code: " + productData[0]);
                    //ProductQuantity
                } catch (InvalidProfileException | NullPointerException e) {
                    iter.next();
                }
                
            }
            return null;
        }
    
        @Override
        public
        boolean readFile(String filename) {
            //define the csvFormat to the default value
            CSVFormat csvFormat = CSVFormat.DEFAULT; 
            try {
                //define a csvParser to read the cvs file
                CSVParser csvParser = CSVParser.parse(new FileReader(filename), csvFormat); 
                //load the results into the CSVRecord list
                List<CSVRecord> list = csvParser.getRecords();
                //load the variable's value from the CSVRecord list
                String gender = list.get(0).get(0).trim();
                float age = Float.parseFloat(list.get(0).get(1).trim());
                float weight = Float.parseFloat(list.get(0).get(2).trim());
                float height = Float.parseFloat(list.get(0).get(3).trim());
                float activity = Float.parseFloat(list.get(0).get(4).trim());
                //initialize a stringbuilder to append the information
                StringBuilder sb = new StringBuilder();
                //append each individual person's information to one stringbuilder
                list.get(0).size();
                for (int i = 5; i < list.get(0).size(); i++) {
                    sb.append(list.get(0).get(i) + ",");
                }
                //append empty string to the end 
                if (sb.length() > 0) 
                    sb.replace(sb.toString().length() - 1, sb.toString().length(), "");
                //get the ingredientsToWatch from the sb
                String ingredientsToWatch = sb.toString();
                //create new person object according to their gender
                //return true if created 
                if (gender.equals("Female")) {
                    NutriByte.person = new Female(age, weight, height, activity, ingredientsToWatch);
                    return true;
                }
                if (gender.equals("Male")) {
                    NutriByte.person = new Male(age, weight, height, activity, ingredientsToWatch);
                    return true;
                }
            } 
            catch (FileNotFoundException e1) { e1.printStackTrace();return false;}
            catch (IOException e1) { e1.printStackTrace();} return false;}
    
        @Override
        public void handle(ActionEvent event) {
            // TODO Auto-generated method stub
    
        }
    }
    View Code

    为啥有红字:没catch,让我去model里面catch,也不对吧?而且完全没思路,一点也不会啊

    【问题2】

    product exception我的思路是不是有问题啊,怎么识别不出来

    然后product全都没有的话就展示第一个人,是神马意思

    【save menu完全不会阿】要根据前面的来写

    【问题3】

    ProductComboBoxListener怎么写啊,什么意思都不懂,所以model就不会

    提示了一个新的handler 还没写

     

    【model里的filewrite怎么写啊,所以CSV里的write也不会】

    model的wrtite怎么写啊?是不是要看XML 不是,是一个统一的。要用到哪个知识啊?pdf或者别的文件里有吗

    有的,用buffer

    发现write profile 和write file是分开的, 先写CSVFILER里面的吧,更具体。filename是括号里的东西。

    具体存了多少数啊??profile and diet products data是一些啥?应该是profile和diet products分开吧,所以要写两次

    用S分割是代表一行数据吧, 存profile,那就是5个咯

    仔细看图,发现model用了Data filer,那就看看filer咯。原来是实现接口,好吧。所以照抄,一样的。为啥Case过不了啊,奇怪。哦,写没法测试,那就再说吧。

    exception好像能写8 看老师给的

    不知道读的表格在哪里啊,先看看Exception怎么写再说8

    怎么有的是内部类,有的是boolean啊什么鬼,到底信谁。应该是类里面写方法。没有那个方法啊可是,看来不对。

    直接try catch试试?

    是验证string啊,但是打印不出来,那就先随便写吧。也不知道应该用什么分隔符,写的s+不知道对不对

    数据范围也忘了,还得回去看HW2,我日

    不知道exception要打印在哪啊,先试试console上好了, 猪啊,怎么还是case过不去啊我日

    哦,应该打开,可是打不开,我日,修好了

    format exception?看来果然读错了 。哈哈哈哈哈,没读错,就是不知道怎么打印到小框框Field里,没找到。哈哈哈哈哈哈哈哈。所以继续写完。

    好难受啊,编不下去了,听歌试试?好像还蛮舒服的诶

    还有几个变量的exception没写完,

    【主要是前面指定有错,newmenuhamdler里怎么清理chart啊】

     【savemenu怎么写啊 搜一下吧先】

    【searchbotton怎么写啊 搜一下吧先】

    【clearhbotton怎么写啊 搜一下吧先】

    。。。

     两个写好像还不一样啊??一人一个

    发现很多handler没写,难受

    不知道怎么改person,看看图吧

    于是开始写controller了,主要部分

    可是还是从头往后写吧,不会的先空着

     static是类的,non-static是一个实例化变量的,这基本概念了吧,赶紧复习。

    我想要populate一个map,它却有两个输入是咋回事,我去。看了一下计算,能给我气吐血。我的耐心已经耗尽……于此。妈蛋,map里存的是什么啊。好像存的是两个servingsize的比例? 还是product, nutrient?怎么把产品的营养取出来啊,存在哪里了啊?我觉得是在productnutrient里, 我看看。product类里面的nutrient?有啥联系么。突然发现是Recommendednutrient,唉算了。先从product里拿出来,再存到person里面去吧?我怎么从里面拿啊?必须是recommanded nutrients,否则不行能存新的map。好像是吧RecommendedNutrient移到person里面了已经。可我初始化男女的时候没移啊怎么办啊。怎么理解use的关系。

    发现没看图,返回去把图看懂了

    好像明白map里存什么了,能写了不? 不知道两个输入是啥意思。都是产生product。那就可以写了。

    发现少写了个box,妈的。是不是要新写啊?

    person算是基本完事了吧,不会,呵呵呵呵呵。看看计算。男女应该不用改吧。NP RN也不用改。最下边一行看完了。exception 然后handler。

    NB改了参数,还要再改是什么意思啊,难道还不够么。 

     

     

     

  • 相关阅读:
    C++——多态性
    C++——继承与派生
    C++——字符串处理
    C++——深拷贝
    C++——浅拷贝
    C++——动态内存分配3
    C++——动态内存分配2-创建对象数组
    C++——动态内存分配1
    C++——指针5
    C++——指针4
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9972876.html
Copyright © 2011-2022 走看看