Package hermes.browser.dialog

Source Code of hermes.browser.dialog.AbstractOptionDialog

package hermes.browser.dialog;

/**
* Title:       JOptionsDialog Utility Abstract Class
* Description: An abstract base class that provides the basic plumbing for an
*              options dialog. Specifically, it manages the creation, layout, display
*              and event handling of the three option buttons OK, APPLY and CANCEL.
* Copyright:   Copyright (c) 2001
**/

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;

/**
* <p>
* An abstract base class which provides the basic plumbing for an options
* dialog. Specifically, it manages the creation, layout, display and event
* handling of the three option buttons OK, APPLY and CANCEL.
* </p>
*
* <p>
* The appearance and features of the dialog can be configured using the various
* style flags defined in the class. The configuration can be performed during
* both compile-time and run-time. The user can choose to show any combination
* of the option buttons. The user can also change the alignment and size of
* these buttons.
* </p>
*
* <p>
* This class features the "dirty behaviour". The "dirty behaviour" defines two
* states; DIRTY and NOT DIRTY. When in the NOT DIRTY state (e.g. when the
* dialog was first initialized), the apply button is disabled and clicking on
* the OK button will not call <code>updateData(true)</code>. When in the
* DIRTY state (e.g. by calling <code>setDirty()</code>), the apply button
* will be enabled and clicking on the OK button will result in a call to
* <code>updateData(true)</code>. Use the style flag BEHAVE_DIRTYALWAYS to
* cause the dialog to be in the DIRTY state at all times.
* </p>
*
* @author Sidney Chong
* @version $Revision: 1.3 $ $Date: 2007/01/10 15:59:49 $
*/
abstract public class AbstractOptionDialog extends JDialog
{
    /**
   *
   */
  private static final long serialVersionUID = 5881175544998150130L;
  /**
     * Constant for declaring the OK button. Used in the setDialogProperties()
     * method.
     */
    public static final int OPTION_OK = 1;
    /**
     * Constant for declaring the Cancel button. Used in the
     * setDialogProperties() method.
     */
    public static final int OPTION_CANCEL = 2;
    /**
     * Constant for declaring the Apply button. Used in the
     * setDialogProperties() method.
     */
    public static final int OPTION_APPLY = 4;
    /**
     * Ease-of-use constant for declaring a combination of the OK and Cancel
     * buttons. Used in the setDialogProperties() method.
     */
    public static final int OPTION_OK_CANCEL = OPTION_OK | OPTION_CANCEL;
    /**
     * Ease-of-use constant for declaring a combination of the OK, Cancel, Apply
     * buttons. Used in the setDialogProperties() method.
     */
    public static final int OPTION_OK_CANCEL_APPLY = OPTION_OK | OPTION_CANCEL | OPTION_APPLY;
    /**
     * Constant for declaring a "left align" style for the option buttons
     * layout. Used in the setDialogProperties() method.
     */
    public static final int STYLE_LEFT_ALIGN = 8;
    /**
     * Constant for declaring a "right align" style for the option buttons
     * layout. Used in the setDialogProperties() method.
     */
    public static final int STYLE_RIGHT_ALIGN = 16;
    /**
     * Constant for declaring a "center align" style for the option buttons
     * layout. Used in the setDialogProperties() method.
     */
    public static final int STYLE_CENTER_ALIGN = 32;
    /**
     * Constant for declaring a "center align" style for the option buttons
     * layout. Used in the setDialogProperties() method.
     */
    public static final int DISPLAY_CENTER_DIALOG = 64;
    /**
     * Constant for declaring the behaviour "always dirty", which in essense,
     * turns OFF the "dirty behaviour". i.e. The apply button will always be
     * enabled and clicking on the OK button will always call
     * <code>updateData(true)</code>. Used in the setDialogProperties()
     * method.
     */
    public static final int BEHAVE_DIRTY_ALWAYS = 1073741824;

    /**
     * Stores the dimension for the OK, Cancel and Apply buttons.
     */
    private Dimension m_buttonDim;
    /**
     * The panel that contains all the option buttons.
     */
    private JPanel m_optionsPane;
    /**
     * The generic container that stores the other components which make up the
     * body of the dialog.
     */
    private Container m_bodyPane;
    /**
     * The individual option buttons.
     */
    private JButton m_applyButton, m_okButton, m_cancelButton;
    /**
     * The style of the dialog. It should contain an ORed combination of the
     * available style constants.
     */
    private int m_dialogProperties = OPTION_OK_CANCEL_APPLY | STYLE_RIGHT_ALIGN;
    /**
     * The style of the dialog. It should contain an ORed combination of the
     * available style constants.
     */
    private boolean m_bIsDirty = false;
    /**
     * Indicates the last option button clicked by the user.
     */
    private int m_returnCode = -1;

    /**
     * Class constructor.
     *
     * @param parent
     *            the parent of this dialog.
     * @param name
     *            the text to be displayed in the title bar of the dialog.
     * @param modal
     *            whether the dialog show be modal or not.
     */
    public AbstractOptionDialog(Frame parent, String name, boolean modal)
    {
        super(parent, name, modal);

        /*
         * addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent evt) {
         * System.out.println ("keytyped event hit!"); int keycode =
         * evt.getKeyCode(); if (keycode == KeyEvent.VK_ACCEPT || keycode ==
         * KeyEvent.VK_ENTER) { //fake a mouse hit on OK button
         * System.out.println ("enter hit!"); } if (keycode ==
         * KeyEvent.VK_CANCEL || keycode == KeyEvent.VK_ESCAPE) { //fake a mouse
         * hit on CANCEL button System.out.println ("cancel hit!"); } } });
         */
    }

    public void init()
    {
        initComponents();
        setDialogProperties(m_dialogProperties, false);
        setButtonDimension(new Dimension(73, 27), false);
      
        //pack();
    }

    /**
     * Convenience method to show the dialog in a modal loop and returns the
     * code of the option button that was last clicked when the dialog closes.
     *
     * @return the code of the last option button that was clicked. -1 if none
     *         of the buttons were clicked (or if the CLOSE button on title bar
     *         was clicked).
     */
    public int doModal()
    {
        //reset variables
        m_returnCode = -1;
        boolean tmpVar = isModal();

        setModal(true);
        show();

        setModal(tmpVar);
        return m_returnCode;
    }

    /**
     * A helper function to center the dialog box relative to its owner. Note
     * that if its owner is not visible or is null, then the dialog box is
     * centered relative to the screen.
     */
    public void centerDialog()
    {
        Window owner = getOwner();
        Dimension dim;
        if (owner == null || owner.isVisible() == false)
        {
            dim = getToolkit().getScreenSize();
        }
        else
        {
            dim = owner.getSize();
        }

        setLocation((dim.width - getWidth()) / 2, (dim.height - getHeight()) / 2);
    }

    /**
     * Returns the dimension of the buttons. Note that all buttons share the
     * same dimension.
     *
     * @return the dimension of the buttons.
     */
    public Dimension getButtonDimension()
    {
        return m_buttonDim;
    }

    /**
     * Convenience method for
     * <code>setButtonDimension(Dimension dim, boolean shouldPack)
     * </code> with
     * <code>shouldPack</code> set to <code>true</code>.
     *
     * @param dim
     *            the new dimension of the buttons.
     */
    public void setButtonDimension(Dimension dim)
    {
        setButtonDimension(dim, true);
    }

    /**
     * Sets the dimension of the buttons. Note that all buttons share the same
     * dimension.
     *
     * @param dim
     *            the new dimension of the buttons.
     * @param shouldPack
     *            if true, the method will call the <code>pack()</code> method
     *            after setting the dimension of the buttons.
     */
    public void setButtonDimension(Dimension dim, boolean shouldPack)
    {
        m_buttonDim = dim;
        m_okButton.setPreferredSize(m_buttonDim);
        m_applyButton.setPreferredSize(m_buttonDim);
        m_cancelButton.setPreferredSize(m_buttonDim);
        if (shouldPack) pack();
    }

    /**
     * Returns the dialog style.
     *
     * @return an integer representing the dialog style.
     */
    public int getDialogStyle()
    {
        return m_dialogProperties;
    }

    /**
     * Convenience method for
     * <code>setDialogProperties(int flags, boolean shouldPack)
     * </code> with
     * <code>shouldPack</code> set to <code>true</code>.
     *
     * @param flags
     *            the new dialog styles to be set.
     */
    public void setDialogProperties(int flags)
    {
        setDialogProperties(flags, true);
    }

    /**
     * Sets the style of the dialog. Note that the dialog defaults to
     * STYLE_RIGHT_ALIGN and OPTION_OK_CANCEL_APPLY if an invalid flag is passed
     * in.
     *
     * @param flags
     *            the new dialog styles to be set.
     * @param shouldPack
     *            if true, the method will call the <code>pack()</code> method
     *            after setting the style of the dialog.
     */
    public void setDialogProperties(int flags, boolean shouldPack)
    {
        //reset our style flag
        m_dialogProperties = 0;

        if (((flags & STYLE_RIGHT_ALIGN) > 0 ? true : false) || ((flags & (STYLE_LEFT_ALIGN | STYLE_CENTER_ALIGN)) == 0 ? true : false))
        {
            m_optionsPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            m_dialogProperties |= STYLE_RIGHT_ALIGN; //set right align style in
                                                     // our style flag
        }
        else
        {
            if ((flags & STYLE_LEFT_ALIGN) > 0 ? true : false)
            {
                m_optionsPane.setLayout(new FlowLayout(FlowLayout.LEFT));
                m_dialogProperties |= STYLE_LEFT_ALIGN; //set left align style
                                                        // in our style flag
            }
            else
            {
                m_optionsPane.setLayout(new FlowLayout(FlowLayout.CENTER));
                m_dialogProperties |= STYLE_CENTER_ALIGN; //set center align
                                                          // style in our style
                                                          // flag
            }
        }

        if (((flags & OPTION_OK) > 0 ? true : false) //is ok button specified?
                || ((flags & OPTION_OK_CANCEL_APPLY) == 0 ? true : false))
        { //OR no buttons specified?
            m_okButton.setVisible(true);
            m_dialogProperties |= OPTION_OK;
        }
        else
        {
            m_okButton.setVisible(false);
        }

        if (((flags & OPTION_CANCEL) > 0 ? true : false) //is cancel button
                                                         // specified?
                || ((flags & OPTION_OK_CANCEL_APPLY) == 0 ? true : false))
        { //OR no buttons specified?
            m_cancelButton.setVisible(true);
            m_dialogProperties |= OPTION_CANCEL;
        }
        else
        {
            m_cancelButton.setVisible(false);
        }

        if (((flags & OPTION_APPLY) > 0 ? true : false) //is apply button
                                                        // specified?
                || ((flags & OPTION_OK_CANCEL_APPLY) == 0 ? true : false))
        { //OR no buttons specified?
            m_applyButton.setVisible(true);
            m_dialogProperties |= OPTION_APPLY;
        }
        else
        {
            m_applyButton.setVisible(false);
        }

        if ((flags & BEHAVE_DIRTY_ALWAYS) > 0 ? true : false)
        {
            m_applyButton.setEnabled(true);
            m_dialogProperties |= BEHAVE_DIRTY_ALWAYS;
        }
        else
        {
            if (m_bIsDirty)
                m_applyButton.setEnabled(true);
            else
                m_applyButton.setEnabled(false);
        }

        if ((flags & DISPLAY_CENTER_DIALOG) > 0 ? true : false)
        {
            centerDialog();
        }

        if (shouldPack) pack();
    }

    /**
     * Initializes the body pane. The implementation should create, layout and
     * set up the event handling functions for the body pane's UI components. No
     * default implementation is provided for this method.
     *
     * @return a container that holds all the body pane's UI components.
     */
    abstract protected Container initBodyPane();

    /**
     * Updates the data model. The implementation should be able to update the
     * data model in both directions. i.e. FROM the UI components TO the data
     * model and vice versa. No default implementation is provided for this
     * method.
     *
     * @param toModel
     *            a flag which determines the direction of the data flow. If
     *            <code>
     * true</code>, then the update should be FROM UI
     *            components TO the data model.
     */
    abstract protected void updateData(boolean toModel);

    /**
     * Initializes the dialog components. It is usually called in the class
     * constructor to create the various UI components and add them to the
     * content pane.
     */
    protected void initComponents()
    {
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(initBodyPane(), BorderLayout.CENTER);
        getContentPane().add(initOptionsPane(), BorderLayout.SOUTH);
    }

    /**
     * Initializes the options pane. This method creates and set up the event
     * handling function of the option buttons.
     *
     * @return a container which holds all the option buttons.
     */
    protected Container initOptionsPane()
    {

        m_optionsPane = new JPanel();

        //setting up ok button
        m_okButton = new JButton();
        m_okButton.setText("OK");
        m_okButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent evt)
            {
                m_returnCode = OPTION_OK;
                onOK(evt);
            }
        });
        //set the OK button as the default button
        addComponentListener(new ComponentListener()
        {
            public void componentHidden(ComponentEvent evt)
            {
            }

            public void componentResized(ComponentEvent evt)
            {
            }

            public void componentMoved(ComponentEvent evt)
            {
            }

            public void componentShown(ComponentEvent evt)
            {
                getRootPane().setDefaultButton(m_okButton);
            }
        });
        m_optionsPane.add(m_okButton);

        //setting up cancel button
        m_cancelButton = new JButton();
        m_cancelButton.setText("Cancel");
        m_cancelButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent evt)
            {
                m_returnCode = OPTION_CANCEL;
                onCancel(evt);
            }
        });
        m_optionsPane.add(m_cancelButton);

        //setting up apply button
        m_applyButton = new JButton();
        m_applyButton.setText("Apply");
        m_applyButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent evt)
            {
                m_returnCode = OPTION_APPLY;
                onApply(evt);
            }
        });
        m_optionsPane.add(m_applyButton);

        return m_optionsPane;
    }

    /**
     * Triggers the WINDOW_CLOSING event on this dialog.
     */
    protected void fireWindowClosing()
    {
        dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }

    /**
     * Sets the dirty state. If BEHAVE_DIRTY_ALWAYS is not set, then enables the
     * apply button as well. This method should be called at least once when the
     * user inputs data in the dialog.
     */
    public void setDirty()
    {
        m_bIsDirty = true;
        if (!isDirtyAlways() && m_applyButton != null) m_applyButton.setEnabled(true);
    }

    /**
     * Event handler for the OK button clicked event. The default implementation
     * simply calls <code>updateData(true)</code> to update the data model (if
     * its in the DIRTY state and BEHAVE_DIRTY_ALWAYS is not set) before firing
     * the WINDOW_CLOSING event. The user may override this method to provide
     * more sophisticated handling of the event.
     *
     * @Param evt
     *            the event that triggered this action.
     */
    protected void onOK(ActionEvent evt)
    {
        if (isDirtyAlways() || m_bIsDirty) updateData(true);
        fireWindowClosing();
    }

    /**
     * Event handler for the apply button clicked event. The default
     * implementation simply calls <code>updateData(true)</code> to update the
     * data model and disables the apply button if BEHAVE_DIRTY_ALWAYS is not
     * set. The user may override this method to provide more sophisticated
     * handling of the event.
     *
     * @Param evt
     *            the event that triggered this action.
     */
    protected void onApply(ActionEvent evt)
    {
        updateData(true);
        m_bIsDirty = false;
        if (!isDirtyAlways()) m_applyButton.setEnabled(false);
    }

    /**
     * Event handler for the cancel button clicked event. The default
     * implementation simply fires the WINDOW_CLOSING event. The user may
     * override this method to provide more sophisticated handling of the event.
     *
     * @Param evt
     *            the event that triggered this action.
     */
    protected void onCancel(ActionEvent evt)
    {
        fireWindowClosing();
    }

    /**
     * Returns the container for the body pane.
     *
     * @return the container for the body pane.
     */
    protected Container getBodyPane()
    {
        return m_bodyPane;
    }

    /**
     * Returns the container for the options pane.
     *
     * @return the container for the options pane.
     */
    protected JPanel getOptionsPane()
    {
        return m_optionsPane;
    }

    /**
     * Convenience method to check for the BEHAVE_DIRTY_ALWAYS setting.
     *
     * @return true if flag is set. false otherwise.
     */
    private boolean isDirtyAlways()
    {
        return ((m_dialogProperties & BEHAVE_DIRTY_ALWAYS) > 0 ? true : false);
    }

}
TOP

Related Classes of hermes.browser.dialog.AbstractOptionDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.