HW3 纠结的心得

时间:2023-03-09 02:36:01
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 \nRelease 1.0\nCopyleft Java Nerds\nThis software is designed purely for educational purposes.\nNo 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());
}
}
}
}
}

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("\n");
} //store the stringbuilder's content into the string array
String[] csvInfo = sb.toString().split("\n"); //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] + "\nAge must be a number"));
} //validate weight
try{
Float.valueOf(wordsInData[2].trim());
}catch(NumberFormatException e1) {
throw (new InvalidProfileException("Invalid data for Weight:" + wordsInData[2] + "\nWeight must be a number"));
} //validate height
try{
Float.valueOf(wordsInData[3].trim());
}catch(NumberFormatException e1) {
throw (new InvalidProfileException("Invalid data for Height:" + wordsInData[3] + "\nHeight 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] + "\nMust 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 + "\nThe data must be - String, number, number - for ndb number,\n"+"serving size, household size"));
}catch (NumberFormatException e1) {
throw (new InvalidProfileException("Cannot read: " + data+ "\nThe data must be - String, number, number - for ndb number,\n"+"serving size, household size"));
}
}
}

自己改错顺序的红色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();
}
};
}

周日中午的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("\npath2 = " + 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 \nRelease 1.0\nCopyleft Java Nerds\nThis software is designed purely for educational purposes.\nNo 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 }
}
}

周六十点半 抄的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("\n");
}//populate stringbuilder with each row
/*load person data*/
String[] rows = sb.toString().split("\n");
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+"\n");
// validatePersonData(sb.toString());
for(Product product:NutriByte.view.dietProductsTableView.getItems())
{
sb.append(product.getNdbNumber()+","+product.getServingSize()+","+product.getHouseholdSize()+"\n");
}
String[] records = sb.toString().split("\n"); try(BufferedWriter bw = new BufferedWriter(new FileWriter(filename));)
{
for(int i=0;i<records.length;i++)
{
bw.write(records[i]+"\n");
}
}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]+"\nAge 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]+"\nWeight 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]+"\nHeight 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]+"\nMust 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+"\nThe data must be - String, number, number - for ndb number,\n"+"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+"\nThe data must be - String, number, number - for ndb number,\n"+"serving size, household size"));
}
}
}

周六八点半 有错的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 \nRelease 1.0\nCopyleft Java Nerds\nThis software is designed purely for educational purposes.\nNo 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 }
}
}

自己改错的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();
}
}; }

完整有效的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 \nRelease 1.0\nCopyleft Java Nerds\nThis software is designed purely for educational purposes.\nNo 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 } } } }

为啥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] + "\nAge must be a number");
} //weight
try {
weight = Float.parseFloat(personInfo[2]);
}catch(NumberFormatException e) {
throw new InvalidProfileException("Invalid data for Weight:" + personInfo[2] + "\nWeight must be a number");
} //height
try {
height = Float.parseFloat(personInfo[3]);
}catch(NumberFormatException e) {
throw new InvalidProfileException("Invalid data for Height:" + personInfo[3] + "\nHeight 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("\n");
//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("\t");
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) + "\nAge 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) + "\nWeight must be a number");
}catch(NumberFormatException e) {
throw new InvalidProfileException("Invalid data for Weight:" + list.get(0).get(2) + "\nWeight 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) + "\nHeight 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) + "\nMust 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 }
}

自己昨晚改了好多的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("\n");
}
//populate stringbuilder with each row
/*load person data*/
String[] csvInfo = sb.toString().split("\n");
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] + "\nAge must be a number"));
} try{
Float.valueOf(wordsInData[2].trim());
}catch(NumberFormatException e1) {
throw (new InvalidProfileException("Invalid data for Weight:" + wordsInData[2] + "\nWeight must be a number"));
} try{
Float.valueOf(wordsInData[3].trim());
}catch(NumberFormatException e1) {
throw (new InvalidProfileException("Invalid data for Height:" + wordsInData[3] + "\nHeight 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] + "\nMust 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] +
"\nThe data must be - String number, number - for ndb number, serving size, household size"));}
}else {throw (new InvalidProfileException("Cannot read: " + wordsInData[0] + "," + wordsInData[1] +
"\nThe 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 }
}

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("\n");
}//populate stringbuilder with each row
/*load person data*/
String[] rows = sb.toString().split("\n");
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 }
}

【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("\t"); 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] + "\n 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("\n");
//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("\t");
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 }
}

为啥有红字:没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改了参数,还要再改是什么意思啊,难道还不够么。