package org.multibit.hd.ui.views.components; import com.google.common.base.Optional; import org.multibit.hd.ui.models.Model; import org.multibit.hd.ui.views.View; import javax.swing.*; import java.awt.event.KeyEvent; /** * <p>Abstract base class to provide the following to components:</p> * <ul> * <li>Standard implementations of lifecycle methods between a component view and its model</li> * </ul> * * @since 0.0.1 * */ public abstract class AbstractComponentView<M extends Model> implements View<M> { private Optional<M> model = Optional.absent(); protected JPanel panel; /** * @param model The model backing this view */ public AbstractComponentView(M model) { this.model = Optional.fromNullable(model); // Views are automatically registered for UI events through ModelAndView } @Override public Optional<M> getModel() { return model; } @Override public void setModel(M model) { this.model = Optional.fromNullable(model); } /** * <p>Called when the view components have changed and need to update the model</p> * * <p>Implementers must update the model (if present) with the contents of the view components</p> */ @Override public abstract void updateModelFromView(); /** * <p>Called when the model has changed and the view components need to update</p> * <p>Default implementation is to do nothing since most components are pulling data</p> */ @Override public void updateViewFromModel() { // Do nothing } /** * <p>Called when a new instance of the component is required</p> * * <p>Implementers must create a new panel taking the current locale into account</p> * * @return A new panel enclosing this component */ @Override public abstract JPanel newComponentPanel(); /** * @return The current panel enclosing this component */ @Override public JPanel currentComponentPanel() { return panel; } /** * <p>Called in the Swing event thread when this component is first shown</p> * * <p>Implementers should select a primary component to <code>requestFocusInWindow()</code></p> */ public abstract void requestInitialFocus(); /** * Configure the panel to call an action when ESC is pressed and the panel has focus */ protected void useEscToClose(Action closeAction) { // Add support for using ESC to close the panel panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY"); panel.getActionMap().put("ESCAPE_KEY", closeAction); } }