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