From 3694d00a72e76970dbabe0b7772c6ac8c3b8fffb Mon Sep 17 00:00:00 2001 From: HSoreide <sofie.scisly@gmail.com> Date: Sat, 22 Apr 2023 17:57:08 +0200 Subject: [PATCH] Fix background image not filling all views and make IngredientTile re-size with content --- .../controller/AddIngredientController.java | 14 -- .../demo/controller/AllRecipesController.java | 155 ++++++++++++------ src/main/resources/style.css | 1 + src/main/resources/view/AllRecipes.fxml | 2 +- src/main/resources/view/IngredientTile.fxml | 4 +- src/main/resources/view/Recipe.fxml | 4 +- 6 files changed, 107 insertions(+), 73 deletions(-) diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIngredientController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIngredientController.java index a5c67bb4..408a98ed 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AddIngredientController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AddIngredientController.java @@ -2,7 +2,6 @@ package no.ntnu.idatt1002.demo.controller; import javafx.application.Platform; import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; @@ -31,25 +30,12 @@ import no.ntnu.idatt1002.demo.data.recipes.IngredientsAtHand; */ public class AddIngredientController implements Initializable { - private ObservableList<String> ingredients; - private String[] ingredientsList; - - @FXML - private Button addBtn; - - @FXML - private Button helpBtn; - - @FXML private ListView<String> listView; @FXML private TextField searchBar; - @FXML - private Button searchBtn; - @FXML private Label status; diff --git a/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java b/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java index 30e59521..80de931b 100644 --- a/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java +++ b/src/main/java/no/ntnu/idatt1002/demo/controller/AllRecipesController.java @@ -10,34 +10,101 @@ import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; -import javafx.scene.control.Button; import javafx.scene.control.ListView; import javafx.scene.input.MouseEvent; import javafx.stage.Stage; import no.ntnu.idatt1002.demo.data.recipes.*; - import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.ResourceBundle; +/** + * The AllRecipesController manages the view named AllRecipes.fxml that displays a scrollable list of all the + * recipes that are stored in the recipe register at 'src/main/resources/recipes/Recipes.register'. The controller + * holds an instance of the IngredientsAtHand class and the RecipeRegister class and combines the two to + * fill the list with recipes sorted by the number of ingredients that are not currently in the 'fridge' of the + * user. Each recipe is also lister with a percentage value that shows how many percent of the recipe's + * ingredients are actually in the fridge. This information is included so that recipes with a lower number of + * ingredients are not given an unfair advantage over others where the user may have a significant number of + * the ingredients available. Each listed recipe may be clicked on by the user to open it in a new view in full + * detail. + * + * @author hannesofie + */ public class AllRecipesController implements Initializable { IngredientsAtHand ingredientsAtHand; RecipeRegister recipeRegister; - @FXML - private Button goBackBtn; - @FXML private ListView<String> allList; + private String selectedRecipeName; + - private ObservableList<String> recipes; + /** + * The initialize method of the controller takes in a URL (location) and ResourceBundle(resources) to + * initialize the controller once its root element has been processed. The method then reads and creates + * an object of the IngredientsAtHand class and one of the RecipesRegister class. + * If the recipe register exists, the list is filled with Strings for each recipe at the format: + * <Recipe name> - X missing ingredients (XX%) + * Finally, a MouseClick event and handler is attached to the list that gets the recipe name of the clicked + * list item and runs the method showRecipe() with that name as input to show the recipe in detail in the + * view Recipe.fxml. + * + * @param url The location to resolve the relative paths to the root object. + * @param resourceBundle Resources used to localize the root object. + */ + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { - private String selectedRecipeName; + ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); + recipeRegister = FileHandler.readRecipeRegister("Recipes"); + + ObservableList<String> recipes; + + if(recipeRegister == null) { + recipes = FXCollections.observableArrayList(new ArrayList<>()); + } else { + int numberOfRecipes = recipeRegister.getRecipes().size(); + + ArrayList<Recipe> sortedRecipes = recipeRegister.pickBestFits(numberOfRecipes, ingredientsAtHand); + + recipes = FXCollections.observableArrayList(sortedRecipes.stream().map(recipe -> String.format("# %s - %d missing ingredients (%2.0f %% covered)", recipe.getName(), recipe.getMissingIngredients(), percent(recipe.getIngredientList().size() - recipe.getMissingIngredients(), recipe.getIngredientList().size()))).toList()); + } + allList.setItems(recipes); + + allList.setOnMouseClicked(new EventHandler<>() { + + /** + * The handler method takes a MouseEvent(Mouse Click) and uses the list item that was subjected to the + * mouse click and extracts the recipe name. That name as a String is then passed to the method + * 'showRecipe' that loads the view Recipe.fxml to display this particular recipe in full detail. + * + * @param mouseEvent A mouse event, in this case a MouseClicked event. + */ + @Override + public void handle(MouseEvent mouseEvent) { + selectedRecipeName = allList.getSelectionModel() + .getSelectedItem().split("[-#]")[1].strip(); + try { + showRecipe(selectedRecipeName); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + + /** + * The goBack method is fired whenever the user presses the button 'Back To Suggestions'. It loads the location + * of the SuggestRecipes.fxml view and sets the new stage. + * @param event Action event that triggers this method, in this case a button click. + * @throws IOException If the method fails to load the location at the given file path. + */ @FXML private void goBack(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(); @@ -50,6 +117,12 @@ public class AllRecipesController implements Initializable { stage.show(); } + /** + * The showRecipe method takes in a recipe name as a String and navigates to the view Recipe.fxml after having + * the RecipeController set the data of the view according to this particular recipe. + * @param recipeName A case-sensitive string representation of the recipe to open in detail. + * @throws IOException If the method fails to load the location of the Recipe.fxml view. + */ private void showRecipe(String recipeName) throws IOException { FXMLLoader loader = new FXMLLoader(); loader.setLocation(getClass().getResource("/view/Recipe.fxml")); @@ -57,59 +130,33 @@ public class AllRecipesController implements Initializable { Recipe recipeOfInterest = recipeRegister.getRecipe(recipeName); Parent root = loader.load(); - RecipeController recipeController = loader.getController(); - recipeController.setData(recipeOfInterest); - - Stage stage = (Stage)allList.getParent().getScene().getWindow(); - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); + if(recipeOfInterest != null) { + recipeController.setData(recipeOfInterest); + Stage stage = (Stage)allList.getParent().getScene().getWindow(); + Scene scene = new Scene(root); + stage.setScene(scene); + stage.show(); + } else { + System.out.println("The selected recipe is null."); + } } -private float percent(int a, int b) { - if(b != 0 && a != 0) { - return (float) a / b; + /** + * The percent method takes in two integers(a, b) and performs float-division(a/b) on then and multiplies the + * answer by 100 to get the percentage 'a' makes of the total 'b'. If either 'a' or 'b' is zero, zero is returned. + * In the current context; 'a' is an int representing a number of ingredients at hand and part of a recipe and 'b' + * is an int representing the total number of ingredients in the same recipe. + * @param a An int to divide by b and multiply by 100. + * @param b An int by which to divide 'a'. + * @return A float value presenting the percentage value of 'a' out of 'b'. + */ + private float percent(int a, int b) { + if (b != 0 && a != 0) { + return (a * 100f / b); } else { return 0; } - - -} - - @Override - public void initialize(URL url, ResourceBundle resourceBundle) { - - ingredientsAtHand = FileHandler.readIngredientsAtHand("Fridge"); - recipeRegister = FileHandler.readRecipeRegister("Recipes"); - - int numberOfRecipes = recipeRegister.getRecipes().size(); - - ArrayList<Recipe> sortedRecipes = recipeRegister.pickBestFits(numberOfRecipes, ingredientsAtHand); - - recipes = FXCollections.observableArrayList(sortedRecipes.stream().map(recipe -> { - return String.format("# %s - %d missing ingredients (%.2f %% covered)", recipe.getName(), recipe.getMissingIngredients(), percent(recipe.getIngredientList().size() - recipe.getMissingIngredients(),recipe.getIngredientList().size())); - }).toList()); - - allList.setItems(recipes); - - allList.setOnMouseClicked(new EventHandler<MouseEvent>() { - - @Override - public void handle(MouseEvent mouseEvent) { - selectedRecipeName = allList.getSelectionModel() - .getSelectedItem().split("-|#")[1].strip(); - - try { - showRecipe(selectedRecipeName); - - } catch (IOException e) { - throw new RuntimeException(e); - } - - } - }); - } } diff --git a/src/main/resources/style.css b/src/main/resources/style.css index 0a8075b8..b763b869 100644 --- a/src/main/resources/style.css +++ b/src/main/resources/style.css @@ -141,4 +141,5 @@ -fx-border-width: 5; -fx-border-radius: 30; -fx-border-color: white; + -fx-text-fill: white; } \ No newline at end of file diff --git a/src/main/resources/view/AllRecipes.fxml b/src/main/resources/view/AllRecipes.fxml index c1ab05ae..ddb3a64f 100644 --- a/src/main/resources/view/AllRecipes.fxml +++ b/src/main/resources/view/AllRecipes.fxml @@ -7,7 +7,7 @@ <AnchorPane prefHeight="695.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.AllRecipesController"> <children> - <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true" preserveRatio="true"> + <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true"> <image> <Image url="@../Images/backgroundMini.jpg" /> </image> diff --git a/src/main/resources/view/IngredientTile.fxml b/src/main/resources/view/IngredientTile.fxml index bd749e3a..ebd54256 100644 --- a/src/main/resources/view/IngredientTile.fxml +++ b/src/main/resources/view/IngredientTile.fxml @@ -7,12 +7,12 @@ <Pane id="ingredient" fx:id="ingredientPane" mouseTransparent="true" stylesheets="@../style.css" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.IngredientTileController"> <children> - <Label id="ingredient-label" fx:id="text" prefHeight="40.0" prefWidth="250.0" styleClass="font" stylesheets="@../style.css" text="Ingredient"> + <Label id="ingredient-label" fx:id="text" styleClass="font" stylesheets="@../style.css" text="Ingredient"> <font> <Font name="Ani" size="18.0" /> </font> <padding> - <Insets left="15.0" /> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </padding> </Label> </children> diff --git a/src/main/resources/view/Recipe.fxml b/src/main/resources/view/Recipe.fxml index 5e71c20a..2ca258be 100644 --- a/src/main/resources/view/Recipe.fxml +++ b/src/main/resources/view/Recipe.fxml @@ -6,9 +6,9 @@ <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> -<AnchorPane prefHeight="695.0" prefWidth="1130.0" xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.RecipeController"> +<AnchorPane xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="no.ntnu.idatt1002.demo.controller.RecipeController"> <children> - <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true" preserveRatio="true"> + <ImageView fitHeight="695.0" fitWidth="1130.0" pickOnBounds="true"> <image> <Image url="@../Images/backgroundMini.jpg" /> </image> -- GitLab