AbstractEditor.java :  » Music » jukes » com » melloware » jukes » gui » view » editor » Java Open Source

Java Open Source » Music » jukes 
jukes » com » melloware » jukes » gui » view » editor » AbstractEditor.java
package com.melloware.jukes.gui.view.editor;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.ProgressMonitor;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.text.JTextComponent;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.uif.action.ActionManager;
import com.jgoodies.uif.application.Application;
import com.jgoodies.uif.component.ToolBarButton;
import com.jgoodies.uifextras.util.UIFactory;
import com.jgoodies.validation.view.ValidationComponentUtils;
import com.jgoodies.validation.view.ValidationResultViewFactory;
import com.melloware.jukes.db.orm.AbstractJukesObject;
import com.melloware.jukes.gui.tool.Actions;
import com.melloware.jukes.gui.tool.MainModule;
import com.melloware.jukes.gui.tool.Resources;
import com.melloware.jukes.gui.tool.Settings;
import com.melloware.jukes.gui.view.MainFrame;
import com.melloware.jukes.gui.view.tasks.UpdateTagsTask;
import com.melloware.jukes.gui.view.validation.AbstractValidationModel;
import com.melloware.jukes.util.MessageUtil;

/**
 * The abstract superclass of all <code>Editor</code> implementations.
 * <p>
 * Copyright (c) 1999-2007 Melloware, Inc. <http://www.melloware.com>
 * @author Emil A. Lefkof III <info@melloware.com>
 * @version 4.0
 * 2010 AZ Development
 */
@SuppressWarnings("PMD")
abstract public class AbstractEditor
    extends JPanel
    implements Editor {

    protected static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd yyyy h:mm a", Locale.US);
    protected static final Font FONT_ENABLED = new JLabel().getFont();
    protected static final Font FONT_DISABLED = FONT_ENABLED.deriveFont(FONT_ENABLED.getStyle() ^ Font.BOLD);
    protected static final Border BORDER_ENABLED = new JTextField().getBorder();
    protected static final Border BORDER_DISABLED = BorderFactory.createEmptyBorder();
    protected static final String HINT = "HINT";
    protected AbstractValidationModel validationModel;
    protected final Icon icon;
    protected JComponent hintAreaPane;
    protected JLabel createdByLabel;
    protected JLabel createdDateLabel;
    protected JLabel hintLabel;
    protected JLabel modifiedByLabel;
    protected JLabel modifiedDateLabel;
    protected JTextArea hintArea;
    protected ProgressMonitor progressMonitor;
    protected final String titlePrefix;
    protected Timer timer;
    protected UpdateTagsTask task;
    private Object model;

    /**
     * Constructs an <code>AbstractEditor</code> with the specified icon.
     */
    public AbstractEditor(Icon icon) {
        this(icon, "");
    }

    /**
     * Constructs an <code>AbstractEditor</code> with the specified title
     * prefix.
     */
    public AbstractEditor(String titlePrefix) {
        this(null, titlePrefix);
    }

    /**
     * Constructs an <code>AbstractEditor</code> with the specified
     * <code>Icon</code> and title prefix.
     */
    public AbstractEditor(Icon icon, String titlePrefix) {
        this.icon = icon;
        this.titlePrefix = titlePrefix;
        build();
    }

    /**
     * Returns the class used to register this instance in the UpdateManager.
     */
    abstract public Class getDomainClass();

    /**
     * Answers this <code>Editor</code>'s <code>JToolBar</code>.
     * The default implementation specifies that no tool bar is used.
     */
    public JToolBar getHeaderToolBar() {
        return null;
    }

    /**
     * Answers this <code>Editor</code>'s <code>Icon</code>.
     */
    public Icon getIcon() {
        return icon;
    }

    /**
     * Returns this editor's underlying model.
     */
    public Object getModel() {
        return model;
    }

    /**
     * Returns this editor's underlying model as an AbstractJukesObject.
     */
    public AbstractJukesObject getOrmObject() {
        return (AbstractJukesObject)model;
    }

    /**
     * Answers this <code>Editor</code>'s title.
     */
    public String getTitle() {
        return titlePrefix + ' ' + getTitleSuffix();
    }

    /**
     * Answers this <code>Editor</code>'s <code>JToolBar</code>.
     * The default implementation specifies that no tool bar is used.
     */
    public JToolBar getToolBar() {
        return null;
    }

    /**
     * Sets a new model. Does nothing if the old and new model are the same.
     * If the model changes, invokes <code>#updateView</code>.
     * AZ 2010: compare object Id also.
     * @param newModel   the model to set
     */
    public void setModel(Object newModel) {
        Object oldModel = getModel();
        AbstractJukesObject newObject, oldObject;//AZ
      oldObject = (AbstractJukesObject) oldModel;
      newObject = (AbstractJukesObject) newModel;
      
      if ((oldModel != null) && (oldModel.equals(newModel)) && (oldObject.getId() == newObject.getId()) ) {
          this.lock();
            return;
        }
        model = newModel;
        updateView();
        this.lock();
    }

    /**
     * Activates this viewer.
     */
    public void activate() {
        // Do nothing by default; subclasses may override.
    }

    /**
     * Commits any changes made to this editor.
     */
    public void commit() {
      this.lock();
    }
    
    /**
     * Unlocks this viewer and updates all text fields and buttons.
     */
    public void unlock() {
      ActionManager.get(Actions.UNLOCK_ID).setEnabled(false);
      validationModel.updateButtonState(true);
        final Collection components = getAllComponents(this);
      
      for (Iterator iter = components.iterator(); iter.hasNext();) {
      final Component component = (Component) iter.next();
      if (component instanceof JTextComponent) {
        final JTextComponent field = (JTextComponent)component;
        //skip if this is the hint area
        if (field.getClientProperty(HINT) != null) {
          continue;
        }
        field.setEnabled(true);
        field.setBorder(BORDER_ENABLED);
        field.setOpaque(true);
        field.setFont(FONT_ENABLED);
      } else if (component instanceof JComboBox) {
        final JComboBox field = (JComboBox)component;
        field.setEnabled(true);
        field.setVisible(true);
      } else if (component instanceof JLabel) {
        final JLabel field = (JLabel)component;
        if ("GENRE".equalsIgnoreCase(field.getName())) {
          field.setVisible(false);
        }
      } else if (component instanceof ToolBarButton) {
        final ToolBarButton button = (ToolBarButton)component;
        button.setVisible(true);
      }
    }
      
      this.updateUI();
    }
    
    /**
     * Locks this viewer and updates all text fields and buttons.
     */
    public void lock() {
      ActionManager.get(Actions.UNLOCK_ID).setEnabled(true);
      validationModel.updateButtonState(false);
      final Collection components = getAllComponents(this);
      
      for (Iterator iter = components.iterator(); iter.hasNext();) {
      final Component component = (Component) iter.next();
      if (component instanceof JTextComponent) {
        final JTextComponent field = (JTextComponent)component;
        //skip if this is the hint area
        if (field.getClientProperty(HINT) != null) {
          continue;
        }
        
        field.setEnabled(false);
        field.setDisabledTextColor(Color.BLACK);
        field.setBorder(BORDER_DISABLED);
        field.setOpaque(false);
        field.setFont(FONT_DISABLED);
      }  else if (component instanceof JComboBox) {
        final JComboBox field = (JComboBox)component;
        field.setEnabled(false);
        field.setVisible(false);
      } else if (component instanceof JLabel) {
        final JLabel field = (JLabel)component;
        if ("GENRE".equalsIgnoreCase(field.getName())) {
          final String text = field.getText().trim();
          field.setText("  " + text);
          field.setVisible(true);
          field.setFont(FONT_DISABLED);
        }
      } else if (component instanceof ToolBarButton) {
        final ToolBarButton button = (ToolBarButton)component;
        button.setVisible(false);
      }
      
    }
      
      this.updateUI();
    }
    
    /**
     * Recurse through a component and build a list of all the components 
     * underneath of it.
     * <p>
     * @param aTop the top container
     * @return the collection of all components under the container
     */
    private Collection getAllComponents(Container aTop) {
      final Component[] comp = aTop.getComponents();
      final ArrayList list = new ArrayList();
      
      if (comp.length == 0) {
      return list;
    }
      
      for (int i = 0; i < comp.length; i++) {
        list.add(comp[i]);
        if (comp[i] instanceof Container) {
        list.addAll(getAllComponents((Container)comp[i]));
      }
    }
      return list;
    }

    /**
     * Deactivates this viewer.
     */
    public void deactivate() {
      //AZ: Do not refresh the object if no changes were made
      /**
        // refresh the object if there are errors when leaving
        if (this.hasErrors()) {
            this.rollback();
        } else {**/
      
          //if dirty prompt the user to save changes
            if (validationModel.isDirty()) {
                if (MessageUtil.promptYesNo(getMainFrame(), Resources.getString("messages.promptSaveChanges"))) {
                    this.commit();
                } else {
                  //if they don't want to save then refresh this object
                  this.rollback();
                }
            }
        //AZ }
    }

    /**
     * Delete the object and its descendants contained by this editor.
     */
    public void delete() {
        // Do nothing by default; subclasses may override.
    }

    /**
     * Tries to find a new cover for the disc.
     */
    public void findCover() {
        // Do nothing by default; subclasses may override.
    }

    /**
     * Renames any files this editor owns.
     */
    public void renameFiles() {
        // Do nothing by default; subclasses may override.
    }

    /**
     * Rollback any changes made to this editor
     */
    public void rollback() {
        // Do nothing by default; subclasses may override.
      this.lock();
    }

    /**
     * Perform the web service search to look for disc info.
     */
    public void webSearch() {
        // Do nothing by default; subclasses may override.
    }
    
    /** AZ
     * Perform the web service search to look for disc info.
     */
    public void freeDBSearch() {
        // Do nothing by default; subclasses may override.
    }

    /**
     * Returns a suffix for this editor's title.
     *
     * @return a suffix for this editor's title
     */
    abstract protected String getTitleSuffix();

    /**
     * Builds this panel.
     */
    abstract protected void build();

    /**
     * Writes the view contents to the underlying model.
     */
    abstract protected void updateModel();

    /**
     * Reads the view contents from the underlying model.
     */
    abstract protected void updateView();

    /**
     * Gets the MainFrame for the application.
     * <p>
     * @return the MainFrame object
     */
    protected MainFrame getMainFrame() {
        return (MainFrame)Application.getDefaultParentFrame();
    }

    /**
     * Gets the MainModule for the application.
     * <p>
     * @return the MainModule object
     */
    protected MainModule getMainModule() {
        return getMainFrame().getMainModule();
    }

    /**
     * Gets the settings for the application.
     * <p>
     * @return the Settings object of user defined settings
     */
    protected Settings getSettings() {
        return MainModule.SETTINGS;
    }

    /**
     * Gets the validationModel.
     * <p>
     * @return Returns the validationModel.
     */
    protected AbstractValidationModel getValidationModel() {
        return this.validationModel;
    }

    /**
     * Sets the cursor to hourglass for true and default for false.  Used for
     * long operations such as saves.
     * <p>
     * @param aBusy true for busy cursor, false for default
     */
    protected void setBusyCursor(boolean aBusy) {
        if (aBusy) {
            getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        } else {
            getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }

    /**
     * Builds the audit information panel which displays the created by, and
     * modified by info of a ORM record.
     * <p>
     * @return the panel to display the audit info
     */
    protected JComponent buildAuditInfoPanel() {
        // create the labels as BOLD
        createdDateLabel = UIFactory.createBoldLabel("");
        createdByLabel = UIFactory.createBoldLabel("");
        modifiedDateLabel = UIFactory.createBoldLabel("");
        modifiedByLabel = UIFactory.createBoldLabel("");

        FormLayout layout = new FormLayout("right:max(40dlu;pref), 3dlu, 100dlu, 7dlu, "
                                           + "right:max(40dlu;pref), 3dlu, 100dlu", "p, 3dlu, p, 3dlu, p, 3dlu, p");
        PanelBuilder builder = new PanelBuilder(layout);
        CellConstraints cc = new CellConstraints();

        int row = 1;
        builder.addLabel(Resources.getString("label.createdby") + ": ", cc.xy(1, row));
        builder.add(createdByLabel, cc.xy(3, row));
        builder.addLabel(Resources.getString("label.createddate") + ": ", cc.xy(5, row));
        builder.add(createdDateLabel, cc.xy(7, row++));
        row++;

        builder.addLabel(Resources.getString("label.modifiedby") + ": ", cc.xy(1, row));
        builder.add(modifiedByLabel, cc.xy(3, row));
        builder.addLabel(Resources.getString("label.modifieddate") + ": ", cc.xy(5, row));
        builder.add(modifiedDateLabel, cc.xy(7, row++));
        row++;
        
        JComponent component = builder.getPanel();
        component.setVisible(this.getSettings().isAuditInfo());

        return component;
    }

    /**
     * Builds the hint area panel where validation hints are displayed.
     * <p>
     * @return the panel to display the hints
     */
    protected JComponent buildHintAreaPane() {
        hintLabel = new JLabel(ValidationResultViewFactory.getInfoIcon());
        hintArea = new JTextArea(1, 38);
        hintArea.putClientProperty(HINT, HINT);
        hintArea.setEditable(false);
        hintArea.setOpaque(false);

        FormLayout layout = new FormLayout("pref, 2dlu, default", "pref");
        PanelBuilder builder = new PanelBuilder(layout);
        CellConstraints cc = new CellConstraints();
        builder.add(hintLabel, cc.xy(1, 1));
        builder.add(hintArea, cc.xy(3, 1));

        hintAreaPane = builder.getPanel();
        hintAreaPane.setVisible(false);
        return hintAreaPane;
    }

    /**
     * Does this editor pass validation right now. True if so false otherwise.
     * <p>
     * @return true if passes validation
     */
    protected boolean hasErrors() {
        return getValidationModel().getValidationResultModel().getResult().hasErrors();
    }

    /**
     * Initializes any event handling.
     */
    protected void initEventHandling() {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(new FocusChangeHandler());
    }


    /**
     * Displays an input hint for components that get the focus permanently.
     */
    private final class FocusChangeHandler
        implements PropertyChangeListener {

        public void propertyChange(PropertyChangeEvent evt) {
            String propertyName = evt.getPropertyName();
            if (!"permanentFocusOwner".equals(propertyName)) {
                return;
            }
            Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
            String focusHint = (focusOwner instanceof JComponent)
                               ? (String)ValidationComponentUtils.getInputHint((JComponent)focusOwner) : null;
                        
            hintArea.setText(focusHint);
            hintAreaPane.setVisible(focusHint != null);
        }
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.