package org.leumasjaffe.recipe.view; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.leumasjaffe.observer.ForwardingObservableListener; import org.leumasjaffe.observer.ObservableController; import org.leumasjaffe.observer.ObservableListener; import org.leumasjaffe.observer.ObserverDispatch; import org.leumasjaffe.recipe.model.Phase; import org.leumasjaffe.recipe.controller.AddPhaseAction; import org.leumasjaffe.recipe.model.Element; import lombok.AccessLevel; import lombok.Getter; import lombok.experimental.FieldDefaults; import org.jdesktop.swingx.VerticalLayout; import javax.swing.JSeparator; import javax.swing.JTextField; import javax.swing.ScrollPaneConstants; import javax.swing.event.DocumentListener; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.FocusListener; import java.awt.Component; import java.awt.Dimension; import javax.swing.Box; import javax.swing.JButton; @SuppressWarnings("serial") @FieldDefaults(level=AccessLevel.PRIVATE) public class ElementPanel extends JScrollPane implements AutoGrowPanel.ChildComponent { ForwardingObservableListener listener = new ForwardingObservableListener<>(); ObservableListener nameController; ObservableListener durationListener; @Getter(AccessLevel.PACKAGE) JTextField txtName; AddPhaseAction addPhase; JPanel panelViewPort; public ElementPanel() { setPreferredSize(new Dimension(600, 450)); setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); JPanel panelColumnHeader = new JPanel(); setColumnHeaderView(panelColumnHeader); GridBagLayout gbl_panelColumnHeader = new GridBagLayout(); gbl_panelColumnHeader.columnWidths = new int[]{0, 0, 0, 0, 0}; gbl_panelColumnHeader.rowHeights = new int[]{0, 0}; gbl_panelColumnHeader.columnWeights = new double[]{0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE}; gbl_panelColumnHeader.rowWeights = new double[]{0.0, Double.MIN_VALUE}; panelColumnHeader.setLayout(gbl_panelColumnHeader); txtName = new JTextField(); txtName.setColumns(10); GridBagConstraints gbc_txtName = new GridBagConstraints(); gbc_txtName.insets = new Insets(0, 0, 0, 5); gbc_txtName.gridx = 0; gbc_txtName.gridy = 0; panelColumnHeader.add(txtName, gbc_txtName); JButton btnAdd = new JButton("+"); btnAdd.setToolTipText("Add new phase"); btnAdd.setPreferredSize(new Dimension(17, 17)); btnAdd.setMargin(new Insets(0, 0, 0, 0)); GridBagConstraints gbc_btnAdd = new GridBagConstraints(); gbc_btnAdd.insets = new Insets(0, 0, 0, 5); gbc_btnAdd.gridx = 1; gbc_btnAdd.gridy = 0; panelColumnHeader.add(btnAdd, gbc_btnAdd); Component horizontalGlue = Box.createHorizontalGlue(); GridBagConstraints gbc_horizontalGlue = new GridBagConstraints(); gbc_horizontalGlue.insets = new Insets(0, 0, 0, 5); gbc_horizontalGlue.gridx = 2; gbc_horizontalGlue.gridy = 0; panelColumnHeader.add(horizontalGlue, gbc_horizontalGlue); CollatedDurationPanel panelDuration = new CollatedDurationPanel(); GridBagConstraints gbc_panelDuration = new GridBagConstraints(); gbc_panelDuration.gridx = 3; gbc_panelDuration.gridy = 0; panelColumnHeader.add(panelDuration, gbc_panelDuration); panelViewPort = new JPanel(); setViewportView(panelViewPort); panelViewPort.setLayout(new VerticalLayout(5)); addPhase = new AddPhaseAction(panelViewPort); btnAdd.addActionListener(addPhase); nameController = ObservableController.from(txtName, Element::getName, Element::setName); durationListener = new ObservableListener<>(panelDuration, (c, v) -> c.setModel(v.getCollatedDuration())); } public ElementPanel(final Element element) { this(); setModel(element); } public void setModel(final Element element) { addPhase.setModel(element); panelViewPort.removeAll(); for (final Phase phase : element.getPhases()) { panelViewPort.add(new PhasePanel(phase)); panelViewPort.add(new JSeparator()); } listener.setObserved(element, element.getPhases()); nameController.setObserved(element); durationListener.setObserved(element); } @Override public void removeNotify() { super.removeNotify(); ObserverDispatch.unsubscribeAll(listener); ObserverDispatch.unsubscribeAll(nameController); ObserverDispatch.unsubscribeAll(durationListener); } @Override public void addGrowListener(DocumentListener dl) { this.txtName.getDocument().addDocumentListener(dl); } @Override public void removeGrowListener(DocumentListener dl) { this.txtName.getDocument().removeDocumentListener(dl); } @Override public void addShrinkListener(FocusListener fl) { this.txtName.addFocusListener(fl); } @Override public void removeShrinkListener(FocusListener fl) { this.txtName.removeFocusListener(fl); } }