Sfoglia il codice sorgente

Merge branch 'feat/linkview'

* feat/linkview:
  Change instructions to use a binding.
  Use a ReplaceChildrenController for summary.ElementPanel
  Add servings to SummaryPanel, use a binding mechanism that doesn't trigger ObserverDispatch unnecessarily.
Sam Jaffe 5 anni fa
parent
commit
9d3779b180

+ 39 - 0
src/main/lombok/org/leumasjaffe/recipe/controller/SpinnerBinding.java

@@ -0,0 +1,39 @@
+package org.leumasjaffe.recipe.controller;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.swing.JSpinner;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
+
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class SpinnerBinding<T, O> implements ChangeListener {
+	JSpinner component;
+	Function<T, O> get;
+	BiConsumer<T, O> set;
+	@NonFinal T model;
+	
+	public SpinnerBinding(JSpinner component, Function<T, O> get, BiConsumer<T, O> set) {
+		this.component = component;
+		this.get = get;
+		this.set = set;
+		component.addChangeListener(this);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public void stateChanged(ChangeEvent e) {
+		set.accept(this.model, (O) component.getValue());
+	}
+	
+	public void setModel(T model) {
+		this.model = model;
+		component.setValue(get.apply(model));
+	}
+
+}

+ 39 - 0
src/main/lombok/org/leumasjaffe/recipe/controller/TextBinding.java

@@ -0,0 +1,39 @@
+package org.leumasjaffe.recipe.controller;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.JTextComponent;
+
+import org.leumasjaffe.event.AnyActionDocumentListener;
+
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
+
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class TextBinding<T> implements AnyActionDocumentListener {
+	JTextComponent component;
+	Function<T, String> get;
+	BiConsumer<T, String> set;
+	@NonFinal T model;
+	
+	public TextBinding(JTextComponent component, Function<T, String> get, BiConsumer<T, String> set) {
+		this.component = component;
+		this.get = get;
+		this.set = set;
+		component.getDocument().addDocumentListener(this);
+	}
+	
+	@Override
+	public void update(DocumentEvent e) {
+		set.accept(this.model, component.getText());
+	}
+	
+	public void setModel(T model) {
+		this.model = model;
+		component.setText(get.apply(model));
+	}
+
+}

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

@@ -7,6 +7,7 @@ import org.leumasjaffe.observer.ForwardingObservableListener;
 import org.leumasjaffe.observer.ObservableController;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
+import org.leumasjaffe.recipe.controller.TextBinding;
 import org.leumasjaffe.recipe.model.Ingredient;
 import org.leumasjaffe.recipe.model.Step;
 
@@ -31,7 +32,7 @@ import java.awt.Dimension;
 @FieldDefaults(level=AccessLevel.PRIVATE)
 public class StepPanel extends JPanel implements AutoGrowPanel.ChildComponent {
 	ForwardingObservableListener<Step> listener = new ForwardingObservableListener<>();
-	ObservableListener<JTextPane, Step> instructionListener;
+	TextBinding<Step> instructionBinding;
 	ObservableListener<JFormattedTextField, Step> durationController;
 
 	JLabel lblIndex;
@@ -98,7 +99,7 @@ public class StepPanel extends JPanel implements AutoGrowPanel.ChildComponent {
 		gbc_txtpnInstructions.gridy = 0;
 		add(txtpnInstructions, gbc_txtpnInstructions);
 		
-		instructionListener = ObservableController.from(txtpnInstructions,
+		instructionBinding = new TextBinding<>(txtpnInstructions,
 				Step::getInstruction, Step::setInstruction);
 		durationController = ObservableController.from(panelDuration.txtTime,
 				Step::getDuration, Step::setDuration);
@@ -119,7 +120,7 @@ public class StepPanel extends JPanel implements AutoGrowPanel.ChildComponent {
 			}
 		});
 		listener.setObserved(step, step.getIngredients());
-		instructionListener.setObserved(step);
+		instructionBinding.setModel(step);
 		durationController.setObserved(step);
 	}
 	
@@ -127,7 +128,7 @@ public class StepPanel extends JPanel implements AutoGrowPanel.ChildComponent {
 	public void removeNotify() {
 		super.removeNotify();
 		ObserverDispatch.unsubscribeAll(listener);
-		ObserverDispatch.unsubscribeAll(instructionListener);
+		ObserverDispatch.unsubscribeAll(instructionBinding);
 		ObserverDispatch.unsubscribeAll(durationController);
 	}
 

+ 7 - 4
src/main/lombok/org/leumasjaffe/recipe/view/summary/ElementPanel.java

@@ -5,7 +5,9 @@ import javax.swing.JPanel;
 import org.jdesktop.swingx.VerticalLayout;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
+import org.leumasjaffe.recipe.controller.ReplaceChildrenController;
 import org.leumasjaffe.recipe.model.Element;
+import org.leumasjaffe.recipe.model.Ingredient;
 
 import lombok.AccessLevel;
 import lombok.Getter;
@@ -20,6 +22,7 @@ import java.awt.GridBagConstraints;
 @SuppressWarnings("serial")
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class ElementPanel extends JPanel {
+	ReplaceChildrenController<Element, Ingredient> controller;
 	ObservableListener<JLabel, Element> nameListener;
 	ObservableListener<JPanel, Element> childListener;
 	
@@ -27,6 +30,8 @@ public class ElementPanel extends JPanel {
 	@Getter(AccessLevel.PACKAGE) JPanel panelIngredients;
 	
 	public ElementPanel(final Element element) {
+		controller = new ReplaceChildrenController<>(
+				Element::getIngredients, IngredientPanel::new);
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0, 0};
 		gridBagLayout.rowHeights = new int[]{0, 0, 0};
@@ -52,10 +57,8 @@ public class ElementPanel extends JPanel {
 		add(panelIngredients, gbc_panel);
 		
 		nameListener = new ObservableListener<>(lblProductName, (c, t) -> c.setText(t.getName()));
-		childListener = new ObservableListener<>(panelIngredients, (c, t) -> {
-			c.removeAll();
-			element.getIngredients().stream().map(IngredientPanel::new).forEach(c::add);
-		});
+		childListener = new ObservableListener<>(panelIngredients, (c, t) -> 
+			controller.accept(c, t));
 		
 		nameListener.setObserved(element);
 		childListener.setObserved(element);

+ 49 - 10
src/main/lombok/org/leumasjaffe/recipe/view/summary/SummaryPanel.java

@@ -8,12 +8,14 @@ import javax.swing.JPanel;
 import javax.swing.JSeparator;
 import javax.swing.JTextArea;
 import javax.swing.JTextField;
+import javax.swing.SpinnerNumberModel;
 
 import org.jdesktop.swingx.VerticalLayout;
-import org.leumasjaffe.observer.ObservableController;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
 import org.leumasjaffe.recipe.controller.ReplaceChildrenController;
+import org.leumasjaffe.recipe.controller.SpinnerBinding;
+import org.leumasjaffe.recipe.controller.TextBinding;
 import org.leumasjaffe.recipe.model.Element;
 import org.leumasjaffe.recipe.model.RecipeCard;
 import org.leumasjaffe.recipe.view.CollatedDurationPanel;
@@ -21,13 +23,16 @@ import org.leumasjaffe.recipe.view.ImagePanel;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
+import javax.swing.JLabel;
+import javax.swing.JSpinner;
 
 @SuppressWarnings("serial")
 @FieldDefaults(level=AccessLevel.PRIVATE)
 public class SummaryPanel extends JPanel {
 	ReplaceChildrenController<RecipeCard, Element> controller;
-	ObservableListener<JTextField, RecipeCard> titleListener;
-	ObservableListener<JTextArea, RecipeCard> descriptionListener;
+	TextBinding<RecipeCard> titleBinding;
+	SpinnerBinding<RecipeCard, Integer> servingsBinding;
+	TextBinding<RecipeCard> descriptionBinding;
 	ObservableListener<CollatedDurationPanel, RecipeCard> durationListener;
 	ObservableListener<JPanel, RecipeCard> childListener;
 	
@@ -44,9 +49,9 @@ public class SummaryPanel extends JPanel {
 		
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0, 0};
-		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0};
+		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0};
 		gridBagLayout.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
-		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 1.0, Double.MIN_VALUE};
+		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		
 		JPanel panelHeader = new JPanel();
@@ -79,17 +84,47 @@ public class SummaryPanel extends JPanel {
 		gbc_panelDuration.gridy = 1;
 		
 		panelHeader.add(panelDuration, gbc_panelDuration);
+		
+		JPanel panelServings = new JPanel();
+		GridBagConstraints gbc_panelServings = new GridBagConstraints();
+		gbc_panelServings.insets = new Insets(0, 0, 5, 5);
+		gbc_panelServings.fill = GridBagConstraints.BOTH;
+		gbc_panelServings.gridx = 0;
+		gbc_panelServings.gridy = 1;
+		add(panelServings, gbc_panelServings);
+		GridBagLayout gbl_panelServings = new GridBagLayout();
+		gbl_panelServings.columnWidths = new int[]{0, 0, 0};
+		gbl_panelServings.rowHeights = new int[]{0, 0};
+		gbl_panelServings.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
+		gbl_panelServings.rowWeights = new double[]{0.0, Double.MIN_VALUE};
+		panelServings.setLayout(gbl_panelServings);
+		
+		JLabel lblServes = new JLabel("Serves");
+		GridBagConstraints gbc_lblServes = new GridBagConstraints();
+		gbc_lblServes.insets = new Insets(0, 0, 5, 0);
+		gbc_lblServes.gridx = 0;
+		gbc_lblServes.gridy = 0;
+		panelServings.add(lblServes, gbc_lblServes);
+		
+		JSpinner spnServings = new JSpinner(new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1));
+		GridBagConstraints gbc_spnServings = new GridBagConstraints();
+		gbc_spnServings.fill = GridBagConstraints.HORIZONTAL;
+		gbc_spnServings.gridx = 1;
+		gbc_spnServings.gridy = 0;
+		panelServings.add(spnServings, gbc_spnServings);
+		
 		JPanel panelIngredients = new JPanel();
 		GridBagConstraints gbc_panelIngredients = new GridBagConstraints();
 		gbc_panelIngredients.insets = new Insets(0, 0, 5, 5);
 		gbc_panelIngredients.fill = GridBagConstraints.BOTH;
 		gbc_panelIngredients.gridx = 0;
-		gbc_panelIngredients.gridy = 1;
+		gbc_panelIngredients.gridy = 2;
 		add(panelIngredients, gbc_panelIngredients);
 		panelIngredients.setLayout(new VerticalLayout());
 		
 		JPanel panel = new JPanel();
 		GridBagConstraints gbc_panel = new GridBagConstraints();
+		gbc_panel.gridheight = 2;
 		gbc_panel.insets = new Insets(0, 0, 5, 0);
 		gbc_panel.fill = GridBagConstraints.BOTH;
 		gbc_panel.gridx = 1;
@@ -120,10 +155,13 @@ public class SummaryPanel extends JPanel {
 		gbc_txaDescription.gridy = 1;
 		panel.add(txaDescription, gbc_txaDescription);
 		
-		titleListener = ObservableController.from(txtTitle,
+		titleBinding = new TextBinding<>(txtTitle,
 				RecipeCard::getTitle, RecipeCard::setTitle);
+		
+		servingsBinding = new SpinnerBinding<>(spnServings, 
+				RecipeCard::getServings, RecipeCard::setServings);
 
-		descriptionListener = ObservableController.from(txaDescription,
+		descriptionBinding = new TextBinding<>(txaDescription,
 				RecipeCard::getDescription, RecipeCard::setDescription);
 
 		durationListener = new ObservableListener<>(panelDuration,
@@ -140,8 +178,9 @@ public class SummaryPanel extends JPanel {
 	}
 	
 	public void setModel(final RecipeCard card) {
-		titleListener.setObserved(card);
-		descriptionListener.setObserved(card);
+		titleBinding.setModel(card);
+		servingsBinding.setModel(card);
+		descriptionBinding.setModel(card);
 		durationListener.setObserved(card);
 		childListener.setObserved(card);
 	}