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改了参数,还要再改是什么意思啊,难道还不够么。 

 

 

 

原文地址:https://www.cnblogs.com/immiao0319/p/9972876.html