Skip to content
Snippets Groups Projects
Commit 90911f75 authored by HSoreide's avatar HSoreide
Browse files

Improve UI based on customer feedback(21/4-23) and add help-button to the 'Add...

Improve UI based on customer feedback(21/4-23) and add help-button to the 'Add ingredients to Fridge' view
parent 6fa5ca8e
No related branches found
No related tags found
1 merge request!49Improve UI based on customer feedback(21/4-23) and add help-button to the 'Add...
......@@ -10,101 +10,34 @@ 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 ListView<String> allList;
private String selectedRecipeName;
/**
* 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 Button goBackBtn;
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 %%)", recipe.getName(), recipe.getMissingIngredients(), percent(recipe.getIngredientList().size() - recipe.getMissingIngredients(), recipe.getIngredientList().size()))).toList());
}
@FXML
private ListView<String> allList;
allList.setItems(recipes);
allList.setOnMouseClicked(new EventHandler<>() {
private ObservableList<String> recipes;
/**
* 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);
}
}
});
}
private String selectedRecipeName;
/**
* 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();
......@@ -117,12 +50,6 @@ 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"));
......@@ -130,33 +57,59 @@ public class AllRecipesController implements Initializable {
Recipe recipeOfInterest = recipeRegister.getRecipe(recipeName);
Parent root = loader.load();
RecipeController recipeController = loader.getController();
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.");
}
recipeController.setData(recipeOfInterest);
Stage stage = (Stage)allList.getParent().getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* 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);
private float percent(int a, int b) {
if(b != 0 && a != 0) {
return (float) a / 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);
}
}
});
}
}
......@@ -31,5 +31,6 @@ public class IngredientTileController {
.append(ingredient.getAmount()).append(" ")
.append(ingredient.getUnit().label);
text.setText(String.valueOf(sb));
text.setStyle("-fx-font-size: 18");
}
}
......@@ -27,7 +27,7 @@ import java.util.ResourceBundle;
public class RecipeTileController implements Initializable {
@FXML
private Button nameTag;
private Label nameTag;
@FXML
private Label missingTag;
......
CARROT
MILK
AVOCADO
CANNED_TOMATO
CELERY
BROTH
BAY_LEAF
DRY_OREGANO
WHITE_BEANS
DRY_THYME
FRESH_YEAST
GARLIC_CLOVE
RED_ONION
PIE_DOUGH
BROCCOLI
LAM
CHILLI_POWDER
SAUSAGE
YELLOW_CHEESE
MINCED_MEAT
ONION
HAM
WHEAT_FLOUR
ORANGE
OIL
POTATO
OLIVE_OIL
......@@ -10,15 +10,13 @@
}
.button-style {
//-fx-background-color: linear-gradient(#8ca45b, #1e5b5b);
-fx-background-color: white;
-fx-text-fill: black;
-fx-background-radius: 30;
-fx-background-insets: 0;
-fx-font-family: "JetBrains Mono";
-fx-font-size: 16;
//-fx-text-fill: white;
}
.welcome-button {
......@@ -36,7 +34,7 @@
}
#on-white {
-fx-background-color: #79b2b2;
-fx-background-color: #83b6b6;
-fx-text-fill: black;
}
......@@ -80,9 +78,10 @@
}
.list-cell{
-fx-font-size:18.0;
-fx-font-size:20.0;
}
.list-cell:even {
-fx-background-color: rgba(255, 255, 255, 0.7);
}
......@@ -101,12 +100,17 @@
-fx-alignment: center;
}
.ingredient:hover {
-fx-scale-x: 1.05;
-fx-scale-y: 1.05;
-fx-scale-z: 1.05;
/*#ingredient-label {
-fx-font-family: "JetBrains Mono Medium";
}
#ingredient:hover {
-fx-text-fill: red;
-fx-scale-x: 1.03;
-fx-scale-y: 1.03;
-fx-scale-z: 1.03;
}*/
.recipe-instructions {
-fx-font-size: 16;
-fx-font-style: italic;
......@@ -122,9 +126,19 @@
.scroll-pane > .viewport {
-fx-background-color: transparent;
}
.scroll-pane {
-fx-background-color: rgba(255, 255, 255, 0.5);
-fx-background-color: rgba(255, 255, 255, 0.35);
-fx-border-width: 5;
-fx-border-radius: 5;
-fx-border-color: rgba(255, 255, 255, 0.75);
}
#help {
-fx-font-size: 30;
-fx-font-weight: bold;
-fx-background-color: #e09188;
-fx-border-width: 5;
-fx-border-radius: 30;
-fx-border-color: white;
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<DialogPane id="dialog-pane" expanded="true" prefHeight="524.0" prefWidth="614.0" 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.AddIngredientController">
<DialogPane id="dialog-pane" expanded="true" prefHeight="555.0" prefWidth="614.0" 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.AddIngredientController">
<content>
<AnchorPane prefHeight="400.0" prefWidth="600.0">
<padding>
......@@ -56,9 +56,9 @@
</Pane>
<Pane prefHeight="100.0" prefWidth="614.0">
<children>
<Label fx:id="status" layoutX="28.0" layoutY="6.0" prefHeight="44.0" prefWidth="558.0" textAlignment="CENTER" wrapText="true">
<Label fx:id="status" layoutX="28.0" layoutY="-4.0" prefHeight="44.0" prefWidth="558.0" textAlignment="CENTER" wrapText="true">
<font>
<Font size="14.0" />
<Font size="20.0" />
</font></Label>
</children>
</Pane>
......@@ -66,17 +66,30 @@
</VBox>
</children></AnchorPane>
</content>
<header>
<Label fx:id="addIngredientPane" alignment="CENTER" contentDisplay="CENTER" styleClass="font" stylesheets="@../style.css" text="Add an ingredient to the fridge">
<font>
<Font size="24.0" />
</font>
<padding>
<Insets bottom="25.0" top="20.0" />
</padding>
</Label>
</header>
<buttonTypes>
<ButtonType fx:constant="CLOSE" />
</buttonTypes>
<header>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<Pane prefHeight="100.0" prefWidth="543.0">
<children>
<Label layoutX="19.0" layoutY="30.0" prefWidth="516.0" styleClass="head-line" stylesheets="@../style.css" text="Add ingredients to Fridge">
<font>
<Font size="30.0" />
</font>
</Label>
</children>
</Pane>
<Pane prefHeight="100.0" prefWidth="102.0">
<children>
<Button id="help" fx:id="helpBtn" layoutX="9.0" layoutY="14.0" mnemonicParsing="false" onAction="#help" styleClass="button-style" stylesheets="@../style.css" text="?">
<font>
<Font name="System Bold" size="36.0" />
</font></Button>
</children>
</Pane>
</children>
</HBox>
</header>
</DialogPane>
......@@ -5,11 +5,11 @@
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<Pane fx:id="ingredientPane" styleClass="ingredient" 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">
<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 fx:id="text" prefHeight="40.0" prefWidth="250.0" styleClass="font" stylesheets="@../style.css" text="Ingredient">
<Label id="ingredient-label" fx:id="text" prefHeight="40.0" prefWidth="250.0" styleClass="font" stylesheets="@../style.css" text="Ingredient">
<font>
<Font name="Ani" size="14.0" />
<Font name="Ani" size="18.0" />
</font>
<padding>
<Insets left="15.0" />
......
......@@ -7,34 +7,49 @@
<VBox fx:id="recipeTile" prefHeight="220.0" prefWidth="280.0" styleClass="recipe-tile" 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.RecipeTileController">
<children>
<Pane fx:id="namePane" prefHeight="178.0" prefWidth="268.0">
<Pane fx:id="namePane" prefHeight="218.0" prefWidth="268.0">
<children>
<Button fx:id="nameTag" mnemonicParsing="false" onAction="#tileClick" prefHeight="149.0" prefWidth="268.0" styleClass="tile-button" stylesheets="@../style.css" text="nameOfRecipe">
<Button fx:id="tileBtn" alignment="TOP_LEFT" layoutX="-6.0" mnemonicParsing="false" onAction="#tileClick" prefHeight="213.0" prefWidth="280.0" styleClass="tile-button" stylesheets="@../style.css" textAlignment="CENTER">
<font>
<Font size="24.0" />
<Font name="System Bold" size="24.0" />
</font>
<graphic>
<VBox prefHeight="199.0" prefWidth="95.0">
<children>
<Pane prefHeight="132.0" prefWidth="248.0" styleClass="font" stylesheets="@../style.css">
<children>
<Label fx:id="nameTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="135.0" prefWidth="250.0" text="nameOfRecipe" textAlignment="CENTER" wrapText="true">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
</children>
</Pane>
<HBox accessibleRole="BUTTON" prefHeight="66.0" prefWidth="268.0">
<children>
<Label alignment="CENTER" prefHeight="66.0" prefWidth="243.0" text="Missing ingredients:" textAlignment="CENTER" wrapText="true">
<font>
<Font size="24.0" />
</font>
<opaqueInsets>
<Insets left="20.0" right="20.0" />
</opaqueInsets>
</Label>
<Label id="noMissingIngredients" fx:id="missingTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="69.0" prefWidth="127.0" text="# missing">
<font>
<Font size="24.0" />
</font>
</Label>
</children>
<opaqueInsets>
<Insets left="20.0" right="20.0" />
</opaqueInsets>
</HBox>
</children>
</VBox>
</graphic>
</Button>
</children>
</Pane>
<HBox prefHeight="88.0" prefWidth="500.0">
<children>
<Label alignment="CENTER" prefHeight="63.0" prefWidth="292.0" text="Ingredients missing:">
<font>
<Font size="18.0" />
</font>
<opaqueInsets>
<Insets left="20.0" right="20.0" />
</opaqueInsets>
</Label>
<Label id="noMissingIngredients" fx:id="missingTag" alignment="CENTER" contentDisplay="CENTER" prefHeight="69.0" prefWidth="127.0" text="# missing">
<font>
<Font size="24.0" />
</font>
</Label>
</children>
<opaqueInsets>
<Insets left="20.0" right="20.0" />
</opaqueInsets>
</HBox>
</children>
</VBox>
......@@ -30,7 +30,7 @@
</Label>
</children>
</Pane>
<ListView id="list-cell" fx:id="fridgeList" prefHeight="470.0" prefWidth="378.0" stylesheets="@../style.css">
<ListView fx:id="fridgeList" prefHeight="470.0" prefWidth="378.0" styleClass="list-cell" stylesheets="@../style.css">
<VBox.margin>
<Insets right="20.0" />
</VBox.margin></ListView>
......@@ -60,7 +60,7 @@
<children>
<Label fx:id="missingList" stylesheets="@../style.css">
<font>
<Font name="System Bold" size="14.0" />
<Font name="System Bold" size="20.0" />
</font>
<padding>
<Insets left="20.0" right="20.0" />
......@@ -106,7 +106,7 @@
</BorderPane>
</top>
<center>
<GridPane fx:id="recipeGrid" hgap="20.0" prefWidth="603.0" vgap="20.0" BorderPane.alignment="CENTER">
<GridPane fx:id="recipeGrid" hgap="20.0" prefHeight="443.0" prefWidth="609.0" vgap="20.0" BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment