package org.leumasjaffe.recipe.view; import javax.swing.JPanel; import java.awt.GridBagLayout; import javax.swing.JTextField; import java.awt.GridBagConstraints; import java.awt.Insets; import javax.swing.event.DocumentListener; import org.leumasjaffe.observer.ObservableController; import org.leumasjaffe.observer.ObservableListener; import org.leumasjaffe.observer.ObserverDispatch; import org.leumasjaffe.recipe.model.Ingredient; import org.leumasjaffe.recipe.view.formatter.AmountFormatter; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.FieldDefaults; import javax.swing.JFormattedTextField; import javax.swing.JLabel; @SuppressWarnings("serial") @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) public class IngredientPanel extends JPanel implements AutoGrowPanel.ChildComponent { ObservableListener nameController; ObservableListener amountController; ObservableListener preparationController; @Getter(AccessLevel.PACKAGE) JTextField txtName; @Getter(AccessLevel.PACKAGE) JFormattedTextField txtAmount; @Getter(AccessLevel.PACKAGE) JTextField txtPreparation; public IngredientPanel() { GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0}; gridBagLayout.rowHeights = new int[]{0, 0}; gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE}; setLayout(gridBagLayout); JLabel label = new JLabel("\u2022"); GridBagConstraints gbc_label = new GridBagConstraints(); gbc_label.insets = new Insets(0, 0, 0, 5); gbc_label.anchor = GridBagConstraints.EAST; gbc_label.gridx = 0; gbc_label.gridy = 0; add(label, gbc_label); txtName = new JTextField(); GridBagConstraints gbc_txtName = new GridBagConstraints(); gbc_txtName.fill = GridBagConstraints.HORIZONTAL; gbc_txtName.insets = new Insets(0, 0, 0, 5); gbc_txtName.gridx = 1; gbc_txtName.gridy = 0; add(txtName, gbc_txtName); txtName.setColumns(10); txtAmount = new JFormattedTextField(new AmountFormatter()); GridBagConstraints gbc_txtAmount = new GridBagConstraints(); gbc_txtAmount.fill = GridBagConstraints.HORIZONTAL; gbc_txtAmount.insets = new Insets(0, 0, 0, 5); gbc_txtAmount.gridx = 2; gbc_txtAmount.gridy = 0; add(txtAmount, gbc_txtAmount); txtAmount.setColumns(11); txtPreparation = new JTextField(); GridBagConstraints gbc_txtPreparation = new GridBagConstraints(); gbc_txtPreparation.anchor = GridBagConstraints.ABOVE_BASELINE; gbc_txtPreparation.fill = GridBagConstraints.HORIZONTAL; gbc_txtPreparation.gridx = 3; gbc_txtPreparation.gridy = 0; add(txtPreparation, gbc_txtPreparation); txtPreparation.setColumns(10); // I technically don't need to listen here as of this change, // but if I ever restore support for it, it will be convenient. nameController = ObservableController.from(txtName, Ingredient::getName, Ingredient::setName); amountController = ObservableController.from(txtAmount, Ingredient::getAmount, Ingredient::setAmount); preparationController = ObservableController.from(txtPreparation, Ingredient::getPreparation, Ingredient::setPreparation, ing -> { ing.setPreparation(""); ObserverDispatch.notifySubscribers(ing); }); } public IngredientPanel(final Ingredient ingredient) { this(); setModel(ingredient); } public void setModel(final Ingredient ingredient) { nameController.setObserved(ingredient); amountController.setObserved(ingredient); preparationController.setObserved(ingredient); } @Override public void removeNotify() { super.removeNotify(); ObserverDispatch.unsubscribeAll(nameController); ObserverDispatch.unsubscribeAll(amountController); ObserverDispatch.unsubscribeAll(preparationController); } @Override public void addGrowShrinkListener(DocumentListener dl) { this.txtName.getDocument().addDocumentListener(dl); } @Override public void removeGrowShrinkListener(DocumentListener dl) { this.txtName.getDocument().removeDocumentListener(dl); } }