Просмотр исходного кода

Merge branch 'feat/view/fillFromModel'

* feat/view/fillFromModel:
  Add summary of Product ingredients, fix display by removing preferredSize settings.
  Fix amount parsing for COUNT.
  Properly visualize rests.
  Don't track coverage for lombok generated methods.
  Add preparation and instructions into the view.
  Update Jackson to the latest stable version.
  Fix NPE in amount unit switch.
  Add ingredient data into the IngredientPanel.
Sam Jaffe 5 лет назад
Родитель
Сommit
d32cc4e2eb

+ 1 - 0
lombok.config

@@ -0,0 +1 @@
+lombok.addLombokGeneratedAnnotation = true

+ 2 - 2
pom.xml

@@ -68,13 +68,13 @@
     <dependency>
     <dependency>
       <groupId>org.projectlombok</groupId>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <artifactId>lombok</artifactId>
-      <version>1.16.8</version>
+      <version>1.18.16</version>
       <scope>provided</scope>
       <scope>provided</scope>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
       <artifactId>jackson-databind</artifactId>
-      <version>2.7.3</version>
+      <version>2.12.0</version>
     </dependency>
     </dependency>
     <dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.datatype</groupId>
       <groupId>com.fasterxml.jackson.datatype</groupId>

+ 8 - 2
src/main/lombok/org/leumasjaffe/recipe/model/Amount.java

@@ -47,16 +47,22 @@ public class Amount {
 	@JsonCreator
 	@JsonCreator
 	public Amount(final String serial) {
 	public Amount(final String serial) {
 		final String[] tokens = serial.split(" ", 2);
 		final String[] tokens = serial.split(" ", 2);
+		unit = Unit.COUNT;
 		value = Double.parseDouble(tokens[0]);
 		value = Double.parseDouble(tokens[0]);
+		if (tokens.length == 1) {
+			return;
+		}
 		final Optional<Volume> rv = Stream.of(Volume.values())
 		final Optional<Volume> rv = Stream.of(Volume.values())
 				.filter(v -> v.displayName.equals(tokens[1])).findFirst();
 				.filter(v -> v.displayName.equals(tokens[1])).findFirst();
 		if (rv.isPresent()) {
 		if (rv.isPresent()) {
+			unit = Unit.VOLUME;
 			vol = rv.get();
 			vol = rv.get();
 			return;
 			return;
 		}
 		}
 		final Optional<Weight> rw = Stream.of(Weight.values())
 		final Optional<Weight> rw = Stream.of(Weight.values())
 				.filter(w -> w.displayName.equals(tokens[1])).findFirst();
 				.filter(w -> w.displayName.equals(tokens[1])).findFirst();
 		if (rw.isPresent()) {
 		if (rw.isPresent()) {
+			unit = Unit.WEIGHT;
 			wgt = rw.get();
 			wgt = rw.get();
 			return;
 			return;
 		}
 		}
@@ -73,14 +79,14 @@ public class Amount {
 		return build.toString();
 		return build.toString();
 	}
 	}
 	
 	
-	private String unitName() {
+	public String unitName() {
 		switch (unit) {
 		switch (unit) {
 		case WEIGHT:
 		case WEIGHT:
 			return wgt.displayName;
 			return wgt.displayName;
 		case VOLUME:
 		case VOLUME:
 			return vol.displayName;
 			return vol.displayName;
 		default:
 		default:
-			return "";
+			return "ct";
 		}
 		}
 	}
 	}
 
 

+ 3 - 2
src/main/lombok/org/leumasjaffe/recipe/model/Ingredient.java

@@ -2,11 +2,12 @@ package org.leumasjaffe.recipe.model;
 
 
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 
-@Data @AllArgsConstructor
+@Data @AllArgsConstructor @NoArgsConstructor
 public class Ingredient {
 public class Ingredient {
 	String name;
 	String name;
-	String preparation;
+	String preparation = "";
 	Amount amount;
 	Amount amount;
 	
 	
 	Ingredient plus(final Ingredient rhs) {
 	Ingredient plus(final Ingredient rhs) {

+ 3 - 3
src/main/lombok/org/leumasjaffe/recipe/model/Preparation.java

@@ -1,12 +1,12 @@
 package org.leumasjaffe.recipe.model;
 package org.leumasjaffe.recipe.model;
 
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
 
 
 import lombok.Data;
 import lombok.Data;
 
 
 @Data
 @Data
 public class Preparation implements RecipeComponent {
 public class Preparation implements RecipeComponent {
-	Set<Ingredient> ingredients = new HashSet<>();
+	List<Ingredient> ingredients = new ArrayList<>();
 	Duration duration;
 	Duration duration;
 }
 }

+ 9 - 1
src/main/lombok/org/leumasjaffe/recipe/model/Rest.java

@@ -1,11 +1,19 @@
 package org.leumasjaffe.recipe.model;
 package org.leumasjaffe.recipe.model;
 
 
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.Data;
+import lombok.Getter;
+import lombok.experimental.FieldDefaults;
 
 
 @Data
 @Data
 public class Rest {
 public class Rest {
+	@AllArgsConstructor @Getter @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 	public enum Where {
 	public enum Where {
-		FREEZER, REFRIGERATOR, ROOM_TEMPERATURE, WARM_PLACE
+		FREEZER("in the freezer"), REFRIGERATOR("in the refrigerator"),
+		ROOM_TEMPERATURE("at room temperature"), WARM_PLACE("in a warm place");
+		
+		String humanReadable;
 	}
 	}
 	
 	
 	Where where;
 	Where where;

+ 3 - 3
src/main/lombok/org/leumasjaffe/recipe/model/Step.java

@@ -1,13 +1,13 @@
 package org.leumasjaffe.recipe.model;
 package org.leumasjaffe.recipe.model;
 
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
 
 
 import lombok.Data;
 import lombok.Data;
 
 
 @Data
 @Data
 public class Step implements RecipeComponent {
 public class Step implements RecipeComponent {
-	Set<Ingredient> ingredients = new HashSet<>();
+	List<Ingredient> ingredients = new ArrayList<>();
 	Duration duration;
 	Duration duration;
 	String instruction;
 	String instruction;
 }
 }

+ 11 - 3
src/main/lombok/org/leumasjaffe/recipe/view/AutoGrowPanel.java

@@ -3,6 +3,7 @@ package org.leumasjaffe.recipe.view;
 import java.awt.Component;
 import java.awt.Component;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.function.IntFunction;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
 
 
@@ -48,10 +49,10 @@ public class AutoGrowPanel extends JPanel {
 	 * @wbp.parser.constructor
 	 * @wbp.parser.constructor
 	 */
 	 */
 	public AutoGrowPanel(Supplier<DocumentListenable> prod) {
 	public AutoGrowPanel(Supplier<DocumentListenable> prod) {
-		this(i -> prod.get());
+		this(i -> prod.get(), 1);
 	}
 	}
 	
 	
-	public AutoGrowPanel(IntFunction<DocumentListenable> prod) {
+	public AutoGrowPanel(IntFunction<DocumentListenable> prod, int create) {
 		this.prod = prod;
 		this.prod = prod;
 		
 		
 		this.grow = new AnyActionDocumentListener() {
 		this.grow = new AnyActionDocumentListener() {
@@ -64,7 +65,14 @@ public class AutoGrowPanel extends JPanel {
 		};
 		};
 
 
 		setLayout(new VerticalLayout(5));
 		setLayout(new VerticalLayout(5));
-		extend();
+		while (create-- > 0) {
+			extend();
+		}
+	}
+
+	public <T> AutoGrowPanel(Function<T, DocumentListenable> function, List<T> ingredients) {
+		this(i -> function.apply(ingredients.get(i)), ingredients.size());
+		
 	}
 	}
 
 
 	private void extend() {
 	private void extend() {

+ 21 - 6
src/main/lombok/org/leumasjaffe/recipe/view/IngredientPanel.java

@@ -11,6 +11,8 @@ import java.util.Locale;
 import javax.swing.event.DocumentListener;
 import javax.swing.event.DocumentListener;
 import javax.swing.text.NumberFormatter;
 import javax.swing.text.NumberFormatter;
 
 
+import org.leumasjaffe.recipe.model.Ingredient;
+
 import javax.swing.JFormattedTextField;
 import javax.swing.JFormattedTextField;
 import java.awt.Font;
 import java.awt.Font;
 import javax.swing.JLabel;
 import javax.swing.JLabel;
@@ -19,12 +21,13 @@ import javax.swing.JLabel;
 public class IngredientPanel extends JPanel implements AutoGrowPanel.DocumentListenable {
 public class IngredientPanel extends JPanel implements AutoGrowPanel.DocumentListenable {
 	private JTextField txtName;
 	private JTextField txtName;
 	private JTextField txtUnit;
 	private JTextField txtUnit;
+	private JTextField txtPreparation;
 	
 	
-	public IngredientPanel() {
+	public IngredientPanel(final Ingredient ingredient) {
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		GridBagLayout gridBagLayout = new GridBagLayout();
-		gridBagLayout.columnWidths = new int[]{0, 100, 40, 40, 0};
+		gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0};
 		gridBagLayout.rowHeights = new int[]{0, 0};
 		gridBagLayout.rowHeights = new int[]{0, 0};
-		gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE};
+		gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
 		gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		setLayout(gridBagLayout);
 		
 		
@@ -36,7 +39,7 @@ public class IngredientPanel extends JPanel implements AutoGrowPanel.DocumentLis
 		gbc_label.gridy = 0;
 		gbc_label.gridy = 0;
 		add(label, gbc_label);
 		add(label, gbc_label);
 		
 		
-		txtName = new JTextField();
+		txtName = new JTextField(ingredient.getName());
 		txtName.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		txtName.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		GridBagConstraints gbc_txtName = new GridBagConstraints();
 		GridBagConstraints gbc_txtName = new GridBagConstraints();
 		gbc_txtName.fill = GridBagConstraints.HORIZONTAL;
 		gbc_txtName.fill = GridBagConstraints.HORIZONTAL;
@@ -50,6 +53,7 @@ public class IngredientPanel extends JPanel implements AutoGrowPanel.DocumentLis
 		fmtDone.setMinimum(0.0);
 		fmtDone.setMinimum(0.0);
 		fmtDone.setCommitsOnValidEdit(true);
 		fmtDone.setCommitsOnValidEdit(true);
 		JFormattedTextField txtAmount = new JFormattedTextField(fmtDone);
 		JFormattedTextField txtAmount = new JFormattedTextField(fmtDone);
+		txtAmount.setValue(ingredient.getAmount().getValue());
 		txtAmount.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		txtAmount.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		GridBagConstraints gbc_txtAmount = new GridBagConstraints();
 		GridBagConstraints gbc_txtAmount = new GridBagConstraints();
 		gbc_txtAmount.fill = GridBagConstraints.HORIZONTAL;
 		gbc_txtAmount.fill = GridBagConstraints.HORIZONTAL;
@@ -59,15 +63,26 @@ public class IngredientPanel extends JPanel implements AutoGrowPanel.DocumentLis
 		add(txtAmount, gbc_txtAmount);
 		add(txtAmount, gbc_txtAmount);
 		txtAmount.setColumns(4);
 		txtAmount.setColumns(4);
 		
 		
-		txtUnit = new JTextField();
+		txtUnit = new JTextField(ingredient.getAmount().unitName());
 		txtUnit.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		txtUnit.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
 		GridBagConstraints gbc_txtUnit = new GridBagConstraints();
 		GridBagConstraints gbc_txtUnit = new GridBagConstraints();
+		gbc_txtUnit.insets = new Insets(0, 0, 0, 5);
 		gbc_txtUnit.anchor = GridBagConstraints.ABOVE_BASELINE;
 		gbc_txtUnit.anchor = GridBagConstraints.ABOVE_BASELINE;
 		gbc_txtUnit.fill = GridBagConstraints.HORIZONTAL;
 		gbc_txtUnit.fill = GridBagConstraints.HORIZONTAL;
 		gbc_txtUnit.gridx = 3;
 		gbc_txtUnit.gridx = 3;
 		gbc_txtUnit.gridy = 0;
 		gbc_txtUnit.gridy = 0;
 		add(txtUnit, gbc_txtUnit);
 		add(txtUnit, gbc_txtUnit);
-		txtUnit.setColumns(10);
+		txtUnit.setColumns(6);
+		
+		txtPreparation = new JTextField(ingredient.getPreparation());
+		txtPreparation.setFont(new Font("Source Code Pro", Font.PLAIN, 10));
+		GridBagConstraints gbc_txtPreparation = new GridBagConstraints();
+		gbc_txtPreparation.anchor = GridBagConstraints.ABOVE_BASELINE;
+		gbc_txtPreparation.fill = GridBagConstraints.HORIZONTAL;
+		gbc_txtPreparation.gridx = 4;
+		gbc_txtPreparation.gridy = 0;
+		add(txtPreparation, gbc_txtPreparation);
+		txtPreparation.setColumns(10);
 	}
 	}
 
 
 	@Override
 	@Override

+ 3 - 14
src/main/lombok/org/leumasjaffe/recipe/view/PreparationPanel.java

@@ -14,7 +14,6 @@ import javax.swing.JLabel;
 import javax.swing.JTextPane;
 import javax.swing.JTextPane;
 import java.awt.Component;
 import java.awt.Component;
 import javax.swing.Box;
 import javax.swing.Box;
-import java.awt.Dimension;
 
 
 @SuppressWarnings("serial")
 @SuppressWarnings("serial")
 public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentListenable {
 public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentListenable {
@@ -30,7 +29,6 @@ public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentLi
 		setLayout(gridBagLayout);
 		setLayout(gridBagLayout);
 		
 		
 		JPanel panelLeft = new JPanel();
 		JPanel panelLeft = new JPanel();
-		panelLeft.setPreferredSize(new Dimension(200, 50));
 		GridBagConstraints gbc_panelLeft = new GridBagConstraints();
 		GridBagConstraints gbc_panelLeft = new GridBagConstraints();
 		gbc_panelLeft.insets = new Insets(0, 0, 0, 5);
 		gbc_panelLeft.insets = new Insets(0, 0, 0, 5);
 		gbc_panelLeft.fill = GridBagConstraints.BOTH;
 		gbc_panelLeft.fill = GridBagConstraints.BOTH;
@@ -44,7 +42,7 @@ public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentLi
 		gbl_panelLeft.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
 		gbl_panelLeft.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
 		panelLeft.setLayout(gbl_panelLeft);
 		panelLeft.setLayout(gbl_panelLeft);
 		
 		
-		lblIndex = new JLabel("");
+		lblIndex = new JLabel("Prep");
 		GridBagConstraints gbc_lblIndex = new GridBagConstraints();
 		GridBagConstraints gbc_lblIndex = new GridBagConstraints();
 		gbc_lblIndex.fill = GridBagConstraints.HORIZONTAL;
 		gbc_lblIndex.fill = GridBagConstraints.HORIZONTAL;
 		gbc_lblIndex.insets = new Insets(0, 0, 5, 5);
 		gbc_lblIndex.insets = new Insets(0, 0, 5, 5);
@@ -59,14 +57,14 @@ public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentLi
 		gbc_horizontalGlue.gridy = 0;
 		gbc_horizontalGlue.gridy = 0;
 		panelLeft.add(horizontalGlue, gbc_horizontalGlue);
 		panelLeft.add(horizontalGlue, gbc_horizontalGlue);
 		
 		
-		JLabel lblDuration = new JLabel("Duration");
+		JLabel lblDuration = new JLabel("Requires: " + step.getDuration().toString());
 		GridBagConstraints gbc_lblDuration = new GridBagConstraints();
 		GridBagConstraints gbc_lblDuration = new GridBagConstraints();
 		gbc_lblDuration.insets = new Insets(0, 0, 5, 0);
 		gbc_lblDuration.insets = new Insets(0, 0, 5, 0);
 		gbc_lblDuration.gridx = 2;
 		gbc_lblDuration.gridx = 2;
 		gbc_lblDuration.gridy = 0;
 		gbc_lblDuration.gridy = 0;
 		panelLeft.add(lblDuration, gbc_lblDuration);
 		panelLeft.add(lblDuration, gbc_lblDuration);
 		
 		
-		AutoGrowPanel panelIngredients = new AutoGrowPanel(IngredientPanel::new);
+		AutoGrowPanel panelIngredients = new AutoGrowPanel(IngredientPanel::new, step.getIngredients());
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		gbc_panelIngredients.gridwidth = 3;
 		gbc_panelIngredients.gridwidth = 3;
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
@@ -74,15 +72,6 @@ public class PreparationPanel extends JPanel implements AutoGrowPanel.DocumentLi
 		gbc_panelIngredients.gridx = 0;
 		gbc_panelIngredients.gridx = 0;
 		gbc_panelIngredients.gridy = 1;
 		gbc_panelIngredients.gridy = 1;
 		panelLeft.add(panelIngredients, gbc_panelIngredients);
 		panelLeft.add(panelIngredients, gbc_panelIngredients);
-		
-		txtpnInstructions = new JTextPane();
-		txtpnInstructions.setPreferredSize(new Dimension(200, 30));
-		txtpnInstructions.setText("Instructions");
-		GridBagConstraints gbc_txtpnInstructions = new GridBagConstraints();
-		gbc_txtpnInstructions.fill = GridBagConstraints.BOTH;
-		gbc_txtpnInstructions.gridx = 1;
-		gbc_txtpnInstructions.gridy = 0;
-		add(txtpnInstructions, gbc_txtpnInstructions);
 	}
 	}
 
 
 	@Override
 	@Override

+ 39 - 0
src/main/lombok/org/leumasjaffe/recipe/view/ProductSummaryPanel.java

@@ -0,0 +1,39 @@
+package org.leumasjaffe.recipe.view;
+
+import javax.swing.JPanel;
+
+import org.leumasjaffe.recipe.model.Product;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.ArrayList;
+
+import javax.swing.JLabel;
+import java.awt.GridBagConstraints;
+
+@SuppressWarnings("serial")
+public class ProductSummaryPanel extends JPanel {
+	public ProductSummaryPanel(final Product product) {
+		GridBagLayout gridBagLayout = new GridBagLayout();
+		gridBagLayout.columnWidths = new int[]{0, 0, 0};
+		gridBagLayout.rowHeights = new int[]{0, 0};
+		gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
+		gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE};
+		setLayout(gridBagLayout);
+		
+		JLabel lblProductName = new JLabel(product.getName());
+		GridBagConstraints gbc_lblProductName = new GridBagConstraints();
+		gbc_lblProductName.gridx = 0;
+		gbc_lblProductName.gridy = 0;
+		add(lblProductName, gbc_lblProductName);
+		
+		AutoGrowPanel panelIngredients = new AutoGrowPanel(IngredientPanel::new,
+				new ArrayList<>(product.getIngredients()));
+		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
+		gbc_panelIngredients.gridwidth = 2;
+		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
+		gbc_panelIngredients.fill = GridBagConstraints.BOTH;
+		gbc_panelIngredients.gridx = 0;
+		gbc_panelIngredients.gridy = 1;
+		add(panelIngredients, gbc_panelIngredients);
+	}
+}

+ 1 - 0
src/main/lombok/org/leumasjaffe/recipe/view/RecipeFrame.java

@@ -28,6 +28,7 @@ public class RecipeFrame extends JFrame {
 		try {
 		try {
 			Recipe recipe = mapper.readValue(new File("src/test/resources/example.json"), Recipe.class);
 			Recipe recipe = mapper.readValue(new File("src/test/resources/example.json"), Recipe.class);
 			for (Product comp : recipe.getProducts()) {
 			for (Product comp : recipe.getProducts()) {
+				summaryPanel.addProduct(comp);
 				tabbedPane.addTab(comp.getName(), new ProductPanel(comp));
 				tabbedPane.addTab(comp.getName(), new ProductPanel(comp));
 			}
 			}
 		} catch (IOException e) {
 		} catch (IOException e) {

+ 1 - 1
src/main/lombok/org/leumasjaffe/recipe/view/RestPanel.java

@@ -26,7 +26,7 @@ public class RestPanel extends JPanel {
 		gbc_lblRest.gridy = 0;
 		gbc_lblRest.gridy = 0;
 		add(lblRest, gbc_lblRest);
 		add(lblRest, gbc_lblRest);
 		
 		
-		JLabel lblLocation = new JLabel(rest.getWhere().toString());
+		JLabel lblLocation = new JLabel(rest.getWhere().getHumanReadable());
 		GridBagConstraints gbc_lblLocation = new GridBagConstraints();
 		GridBagConstraints gbc_lblLocation = new GridBagConstraints();
 		gbc_lblLocation.insets = new Insets(0, 0, 0, 5);
 		gbc_lblLocation.insets = new Insets(0, 0, 0, 5);
 		gbc_lblLocation.gridx = 1;
 		gbc_lblLocation.gridx = 1;

+ 3 - 4
src/main/lombok/org/leumasjaffe/recipe/view/StepPanel.java

@@ -30,7 +30,6 @@ public class StepPanel extends JPanel implements AutoGrowPanel.DocumentListenabl
 		setLayout(gridBagLayout);
 		setLayout(gridBagLayout);
 		
 		
 		JPanel panelLeft = new JPanel();
 		JPanel panelLeft = new JPanel();
-		panelLeft.setPreferredSize(new Dimension(200, 50));
 		GridBagConstraints gbc_panelLeft = new GridBagConstraints();
 		GridBagConstraints gbc_panelLeft = new GridBagConstraints();
 		gbc_panelLeft.insets = new Insets(0, 0, 0, 5);
 		gbc_panelLeft.insets = new Insets(0, 0, 0, 5);
 		gbc_panelLeft.fill = GridBagConstraints.BOTH;
 		gbc_panelLeft.fill = GridBagConstraints.BOTH;
@@ -59,14 +58,14 @@ public class StepPanel extends JPanel implements AutoGrowPanel.DocumentListenabl
 		gbc_horizontalGlue.gridy = 0;
 		gbc_horizontalGlue.gridy = 0;
 		panelLeft.add(horizontalGlue, gbc_horizontalGlue);
 		panelLeft.add(horizontalGlue, gbc_horizontalGlue);
 		
 		
-		JLabel lblDuration = new JLabel("Duration");
+		JLabel lblDuration = new JLabel("Requires: " + step.getDuration().toString());
 		GridBagConstraints gbc_lblDuration = new GridBagConstraints();
 		GridBagConstraints gbc_lblDuration = new GridBagConstraints();
 		gbc_lblDuration.insets = new Insets(0, 0, 5, 0);
 		gbc_lblDuration.insets = new Insets(0, 0, 5, 0);
 		gbc_lblDuration.gridx = 2;
 		gbc_lblDuration.gridx = 2;
 		gbc_lblDuration.gridy = 0;
 		gbc_lblDuration.gridy = 0;
 		panelLeft.add(lblDuration, gbc_lblDuration);
 		panelLeft.add(lblDuration, gbc_lblDuration);
 		
 		
-		AutoGrowPanel panelIngredients = new AutoGrowPanel(IngredientPanel::new);
+		AutoGrowPanel panelIngredients = new AutoGrowPanel(IngredientPanel::new, step.getIngredients());
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		gbc_panelIngredients.gridwidth = 3;
 		gbc_panelIngredients.gridwidth = 3;
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
@@ -77,7 +76,7 @@ public class StepPanel extends JPanel implements AutoGrowPanel.DocumentListenabl
 		
 		
 		txtpnInstructions = new JTextPane();
 		txtpnInstructions = new JTextPane();
 		txtpnInstructions.setPreferredSize(new Dimension(200, 30));
 		txtpnInstructions.setPreferredSize(new Dimension(200, 30));
-		txtpnInstructions.setText("Instructions");
+		txtpnInstructions.setText(step.getInstruction());
 		GridBagConstraints gbc_txtpnInstructions = new GridBagConstraints();
 		GridBagConstraints gbc_txtpnInstructions = new GridBagConstraints();
 		gbc_txtpnInstructions.fill = GridBagConstraints.BOTH;
 		gbc_txtpnInstructions.fill = GridBagConstraints.BOTH;
 		gbc_txtpnInstructions.gridx = 1;
 		gbc_txtpnInstructions.gridx = 1;

+ 14 - 4
src/main/lombok/org/leumasjaffe/recipe/view/SummaryPanel.java

@@ -7,14 +7,20 @@ import java.awt.Insets;
 
 
 import javax.swing.JLabel;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JPanel;
+import javax.swing.JSeparator;
 import javax.swing.JTextField;
 import javax.swing.JTextField;
 import javax.swing.JTextPane;
 import javax.swing.JTextPane;
 
 
 import org.jdesktop.swingx.VerticalLayout;
 import org.jdesktop.swingx.VerticalLayout;
+import org.leumasjaffe.recipe.model.Product;
+
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
 
 
 @SuppressWarnings("serial")
 @SuppressWarnings("serial")
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class SummaryPanel extends JPanel {
 public class SummaryPanel extends JPanel {
-	JTextField txtTitle;
+	JPanel panelIngredients;
 	
 	
 	public SummaryPanel() {
 	public SummaryPanel() {
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		GridBagLayout gridBagLayout = new GridBagLayout();
@@ -39,7 +45,7 @@ public class SummaryPanel extends JPanel {
 		gbl_panelHeader.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		gbl_panelHeader.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		panelHeader.setLayout(gbl_panelHeader);
 		panelHeader.setLayout(gbl_panelHeader);
 		
 		
-		txtTitle = new JTextField();
+		JTextField txtTitle = new JTextField();
 		txtTitle.setText("Title");
 		txtTitle.setText("Title");
 		GridBagConstraints gbc_txtTitle = new GridBagConstraints();
 		GridBagConstraints gbc_txtTitle = new GridBagConstraints();
 		gbc_txtTitle.insets = new Insets(0, 0, 0, 5);
 		gbc_txtTitle.insets = new Insets(0, 0, 0, 5);
@@ -55,8 +61,7 @@ public class SummaryPanel extends JPanel {
 		gbc_lblDuration.gridy = 0;
 		gbc_lblDuration.gridy = 0;
 		panelHeader.add(lblDuration, gbc_lblDuration);
 		panelHeader.add(lblDuration, gbc_lblDuration);
 		
 		
-		JPanel panelIngredients = new JPanel();
-		panelIngredients.setPreferredSize(new Dimension(200, 100));
+		panelIngredients = new JPanel();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		gbc_panelIngredients.gridheight = 2;
 		gbc_panelIngredients.gridheight = 2;
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
 		gbc_panelIngredients.insets = new Insets(0, 0, 0, 5);
@@ -83,4 +88,9 @@ public class SummaryPanel extends JPanel {
 		gbc_txtpnDescription.gridy = 2;
 		gbc_txtpnDescription.gridy = 2;
 		add(txtpnDescription, gbc_txtpnDescription);
 		add(txtpnDescription, gbc_txtpnDescription);
 	}
 	}
+
+	void addProduct(final Product comp) {
+		panelIngredients.add(new ProductSummaryPanel(comp));
+		panelIngredients.add(new JSeparator());
+	}
 }
 }

+ 57 - 3
src/test/resources/example.json

@@ -13,16 +13,70 @@
             "ingredients": [
             "ingredients": [
               {
               {
                 "name": "onion",
                 "name": "onion",
-                "preparation": "",
+                "preparation": "chopped",
                 "amount": "100 g"
                 "amount": "100 g"
-              }
+              },
+              {
+                "name": "onion",
+                "amount": "1"
+              },
+              {
+              	"name": "oil",
+              	"amount": "1 Tbsp"
+            	},
+              {
+              	"name": "oil",
+              	"amount": "1 Tbsp"
+            	}
             ],
             ],
             "duration": {
             "duration": {
               "displayAs": "MINUTES",
               "displayAs": "MINUTES",
-              "isApproximate": true,
+              "approximate": true,
               "minSeconds": 300,
               "minSeconds": 300,
               "maxSeconds": 600
               "maxSeconds": 600
             }
             }
+          },
+          "cooking": [
+          	{
+          		"ingredients": [
+          			{
+          				"name": "oil",
+          				"amount": "1 Tbsp"
+          			}
+          		],
+	            "duration": {
+	              "displayAs": "SECONDS",
+	              "approximate": true,
+	              "minSeconds": 30,
+	              "maxSeconds": 60
+	            },
+          		"instruction": "Heat oil over high heat"
+          	},
+          	{
+          		"ingredients": [
+          			{
+          				"name": "onion",
+          				"preparation": "chopped",
+          				"amount": "100 g"
+          			}
+          		],
+	            "duration": {
+	              "displayAs": "MINUTES",
+	              "approximate": true,
+	              "minSeconds": 300,
+	              "maxSeconds": 900
+	            },
+          		"instruction": "Sauté the onions until soft and translucent, stirring to prevent burning"
+          	}
+          ],
+          "rest": {
+          	"where": "ROOM_TEMPERATURE",
+            "duration": {
+              "displayAs": "SECONDS",
+              "approximate": false,
+              "minSeconds": 30,
+              "maxSeconds": 30
+            }
           }
           }
         }
         }
       ]
       ]