package org.leumasjaffe.recipe.view; import javax.swing.JPanel; import org.jdesktop.swingx.VerticalLayout; import org.leumasjaffe.observer.IndirectObservableListener; import org.leumasjaffe.observer.ObservableController; import org.leumasjaffe.observer.ObservableListener; import org.leumasjaffe.observer.ObserverDispatch; import org.leumasjaffe.recipe.controller.ReplaceChildrenAction; import org.leumasjaffe.recipe.model.Duration; import org.leumasjaffe.recipe.model.Ingredient; import org.leumasjaffe.recipe.model.Phase; import org.leumasjaffe.recipe.model.Preparation; import org.leumasjaffe.recipe.viewmodel.ScaleFactor; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Insets; import javax.swing.JLabel; import java.awt.Component; import javax.swing.Box; import javax.swing.JFormattedTextField; @SuppressWarnings("serial") @FieldDefaults(level=AccessLevel.PRIVATE) public class PreparationPanel extends JPanel { ReplaceChildrenAction controller; IndirectObservableListener childListener; ObservableListener durationController; DurationPanel panelDuration; public PreparationPanel(final ScaleFactor scale) { controller = new ReplaceChildrenAction<>(Preparation::getIngredients, ing -> new IngredientPanel(ing, scale, false)); GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{0, 0, 0}; gridBagLayout.rowHeights = new int[]{0, 0}; gridBagLayout.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE}; setLayout(gridBagLayout); JPanel panelLeft = new JPanel(); GridBagConstraints gbc_panelLeft = new GridBagConstraints(); gbc_panelLeft.insets = new Insets(0, 0, 0, 5); gbc_panelLeft.fill = GridBagConstraints.BOTH; gbc_panelLeft.gridx = 0; gbc_panelLeft.gridy = 0; add(panelLeft, gbc_panelLeft); GridBagLayout gbl_panelLeft = new GridBagLayout(); gbl_panelLeft.columnWidths = new int[]{0, 0, 0, 0}; gbl_panelLeft.rowHeights = new int[]{0, 0, 0}; gbl_panelLeft.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE}; gbl_panelLeft.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE}; panelLeft.setLayout(gbl_panelLeft); JLabel lblIndex = new JLabel("Prep"); GridBagConstraints gbc_lblIndex = new GridBagConstraints(); gbc_lblIndex.fill = GridBagConstraints.HORIZONTAL; gbc_lblIndex.insets = new Insets(0, 0, 0, 5); gbc_lblIndex.gridx = 0; gbc_lblIndex.gridy = 0; panelLeft.add(lblIndex, gbc_lblIndex); Component horizontalGlue = Box.createHorizontalGlue(); GridBagConstraints gbc_horizontalGlue = new GridBagConstraints(); gbc_horizontalGlue.insets = new Insets(0, 0, 0, 5); gbc_horizontalGlue.gridx = 1; gbc_horizontalGlue.gridy = 0; panelLeft.add(horizontalGlue, gbc_horizontalGlue); panelDuration = new DurationPanel("Requires", Duration.ZERO); GridBagConstraints gbc_panelDuration = new GridBagConstraints(); gbc_panelDuration.gridx = 2; gbc_panelDuration.gridy = 0; panelLeft.add(panelDuration, gbc_panelDuration); JPanel panelIngredients = new JPanel(); panelIngredients.setLayout(new VerticalLayout()); GridBagConstraints gbc_panelIngredients = new GridBagConstraints(); gbc_panelIngredients.gridwidth = 3; gbc_panelIngredients.insets = new Insets(0, 0, 0, 5); gbc_panelIngredients.fill = GridBagConstraints.BOTH; gbc_panelIngredients.gridx = 0; gbc_panelIngredients.gridy = 1; panelLeft.add(panelIngredients, gbc_panelIngredients); // This indirection allows for testing of controller childListener = new IndirectObservableListener<>(panelIngredients, (c, v) -> controller.accept(c, v)); durationController = ObservableController.from(panelDuration.txtTime, Preparation::getDuration, Preparation::setDuration); } public PreparationPanel(final Phase phase, final ScaleFactor scale) { this(scale); setModel(phase); } public void setModel(final Phase phase) { final Preparation prep = phase.getPreparation(); childListener.setObserved(prep, phase); durationController.setObserved(prep); } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); panelDuration.txtTime.setEditable(enabled); } @Override public void removeNotify() { super.removeNotify(); ObserverDispatch.unsubscribeAll(childListener); ObserverDispatch.unsubscribeAll(durationController); } }