Package nl.lxtreme.ols.util.swing

Source Code of nl.lxtreme.ols.util.swing.StandardActionFactory$AbstractStatusAction

/*
* OpenBench LogicSniffer / SUMP project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
*
*
* Copyright (C) 2010-2011 - J.W. Janssen, http://www.lxtreme.nl
*/
package nl.lxtreme.ols.util.swing;


import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import nl.lxtreme.ols.util.*;
import nl.lxtreme.ols.util.swing.StandardActionFactory.CloseAction.Closeable;


/**
* Provides a Swing {@link Action}-factory for some commonly used actions.
*/
public final class StandardActionFactory
{
  // INNER TYPES

  /**
   * Denotes an action for an "Cancel" button.
   */
  public static final class CancelAction extends AbstractStatusAction
  {
    // CONSTANTS

    private static final long serialVersionUID = 1L;

    // CONSTRUCTORS

    /**
     * Creates a new {@link CancelAction} instance.
     */
    public CancelAction()
    {
      super( DialogStatus.CANCEL );
    }
  }

  /**
   * Provides a generic close dialog action.
   */
  public static final class CloseAction extends AbstractAction
  {
    // INNER TYPES

    /**
     * Denotes a window/dialog/frame that can be closed through a
     * {@link CloseAction}.
     */
    public static interface Closeable
    {
      /**
       * Closes this dialog, effectively setting its visibilty to
       * <code>false</code> and disposes it.
       */
      void close();
    }

    // CONSTANTS

    private static final long serialVersionUID = 1L;

    // CONSTRUCTORS

    /**
     * Creates a new {@link CloseAction} instance.
     */
    public CloseAction()
    {
      super( "Close" );
      putValue( SHORT_DESCRIPTION, "Closes this dialog" );

      if ( HostUtils.getHostInfo().isMacOS() )
      {
        // On Mac OS, the default Window-close accelerator is CMD + W
        putValue( ACCELERATOR_KEY, SwingComponentUtils.createMenuKeyMask( KeyEvent.VK_W ) );
      }
      else
      {
        // On Windows/Linux platforms it is ESCape...
        putValue( ACCELERATOR_KEY, KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ) );
      }
    }

    // METHODS

    /**
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed( final ActionEvent aEvent )
    {
      if ( aEvent.getSource() instanceof Component )
      {
        final Component source = ( Component )aEvent.getSource();

        final Closeable closeableParent = findCloseableParent( source, Closeable.class );
        if ( closeableParent == null )
        {
          throw new RuntimeException( "Failed to find closeable parent?!" );
        }

        closeableParent.close();

        // Make sure the resources held by the window are released...
        if ( closeableParent instanceof Window )
        {
          ( ( Window )closeableParent ).dispose();
        }
      }
    }
  }

  /**
   * Denotes the result status of a dialog.
   */
  public static enum DialogStatus
  {
    OK, CANCEL;

    /**
     * @return <code>true</code> if this status equals to {@link #CANCEL},
     *         <code>false</code> otherwise.
     */
    public boolean isCancel()
    {
      return this == CANCEL;
    }

    /**
     * @return <code>true</code> if this status equals to {@link #OK},
     *         <code>false</code> otherwise.
     */
    public boolean isOk()
    {
      return this == OK;
    }
  }

  /**
   * Denotes an action for an "Ok"/"Apply" button.
   */
  public static final class OkAction extends AbstractStatusAction
  {
    // CONSTANTS

    private static final long serialVersionUID = 1L;

    // CONSTRUCTORS

    /**
     * Creates a new {@link OkAction} instance.
     */
    public OkAction()
    {
      super( DialogStatus.OK );
    }
  }

  /**
   *
   */
  public static interface StatusAwareCloseableDialog extends Closeable
  {
    /**
     * Reports back what the status of a dialog is.
     *
     * @param aStatus
     *          the status of the dialog, never <code>null</code>.
     * @return <code>true</code> if setting the dialog status was acknowledged,
     *         <code>false</code> if it was not (in which case the dialog will
     *         not be closed).
     */
    boolean setDialogStatus( DialogStatus aStatus );
  }

  /**
   * Denotes an action for an "Ok"/"Apply" button.
   */
  abstract static class AbstractStatusAction extends AbstractAction
  {
    // CONSTANTS

    private static final long serialVersionUID = 1L;

    // VARIABLES

    private final DialogStatus status;

    /**
     * Creates a new {@link AbstractStatusAction} instance.
     */
    public AbstractStatusAction( final DialogStatus aStatus )
    {
      super( aStatus.name().substring( 0, 1 ).concat( aStatus.name().substring( 1 ).toLowerCase() ) );

      this.status = aStatus;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void actionPerformed( final ActionEvent aEvent )
    {
      if ( aEvent.getSource() instanceof Component )
      {
        final Component source = ( Component )aEvent.getSource();

        final StatusAwareCloseableDialog closeableParent = findCloseableParent( source,
            StatusAwareCloseableDialog.class );
        if ( closeableParent == null )
        {
          throw new RuntimeException( "Failed to find closeable parent?!" );
        }

        if ( closeableParent.setDialogStatus( this.status ) )
        {
          closeableParent.close();

          // Make sure the resources held by the window are released...
          if ( closeableParent instanceof Window )
          {
            ( ( Window )closeableParent ).dispose();
          }
        }
      }
    }
  }

  // CONSTANTS

  /** Denotes the ID of a "close"/"cancel" action. */
  public static final String CLOSE_ACTION_ID = "CloseAction";

  // CONSTRUCTORS

  /**
   * Creates a new StandardActionFactory; never used.
   */
  private StandardActionFactory()
  {
    // NO-op
  }

  // METHODS

  /**
   * Creates a new cancel action instance.
   *
   * @return a cancel action instance, never <code>null</code>.
   */
  public static final Action createCancelAction()
  {
    return new CancelAction();
  }

  /**
   * Creates a new button instance with a cancel action assigned to it.
   *
   * @return a new cancel-button instance, never <code>null</code>.
   */
  public static final JButton createCancelButton()
  {
    final Action action = createCancelAction();
    return createButton( action );
  }

  /**
   * Creates a new close action instance.
   * <p>
   * The close action will have a default shortcut key of CTRL/CMD + W on Mac OS
   * platforms, and ESC on other platforms.
   * </p>
   *
   * @return a close action instance, never <code>null</code>.
   */
  public static final Action createCloseAction()
  {
    return new CloseAction();
  }

  /**
   * Creates a new button instance with a close action assigned to it.
   * <p>
   * The close action shortcut will be set as default operation on the returned
   * button.
   * </p>
   *
   * @return a new close-button instance, never <code>null</code>.
   */
  public static final JButton createCloseButton()
  {
    final Action action = createCloseAction();
    return createButton( action );
  }

  /**
   * Creates a new OK action instance.
   *
   * @return an OK action instance, never <code>null</code>.
   */
  public static final Action createOkAction()
  {
    return new OkAction();
  }

  /**
   * Creates a new button instance with an OK action assigned to it.
   *
   * @return a new OK-button instance, never <code>null</code>.
   */
  public static final JButton createOkButton()
  {
    final Action action = createOkAction();
    return createButton( action );
  }

  /**
   * Creates a new button with the given action and registers the (optional)
   * shortcut key as default action for the returned button.
   *
   * @param aAction
   *          the action of the button to create, cannot be <code>null</code>.
   * @return a new JButton instance, never <code>null</code>.
   */
  private static JButton createButton( final Action aAction )
  {
    String actionName = ( String )aAction.getValue( Action.NAME );
    if ( actionName == null )
    {
      actionName = aAction.toString();
    }

    final JButton button = new JButton( aAction );
    SwingComponentUtils.registerKeystroke( button, aAction, actionName );
    return button;
  }

  /**
   * Tries to find a parent container/component that implements the
   * {@link Closeable} interface.
   *
   * @param aComponent
   *          the component to find the closeable parent for, may be
   *          <code>null</code>.
   * @return the closeable parent, or <code>null</code> if no such parent was
   *         found (or the given component was <code>null</code>).
   */
  private static <T extends Closeable> T findCloseableParent( final Component aComponent,
      final Class<T> aImplementingType )
  {
    T closeableParent;

    // Some magic in order to also be able to find the parent's of menu items
    // or popup menu items...
    if ( aComponent instanceof JMenuItem )
    {
      final Component parent = ( ( JMenuItem )aComponent ).getParent();
      closeableParent = findCloseableParent( parent, aImplementingType );
    }
    else if ( aComponent instanceof JPopupMenu )
    {
      final Component invoker = ( ( JPopupMenu )aComponent ).getInvoker();
      closeableParent = findCloseableParent( invoker, aImplementingType );
    }
    else
    {
      closeableParent = SwingComponentUtils.getAncestorOfClass( aImplementingType, aComponent );
    }

    return closeableParent;
  }
}
TOP

Related Classes of nl.lxtreme.ols.util.swing.StandardActionFactory$AbstractStatusAction

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.