Package DisplayProject.actions

Source Code of DisplayProject.actions.CommandType

/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
 
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
   
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder

 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


*/
package DisplayProject.actions;

import java.awt.Component;
import java.awt.Container;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;

import DisplayProject.Constants;

/**
* This classes stores and accesses the CommandType
* @author Peter
* @author Tim
*@since 18/7/08
*/
//PM:18/07/2008: AXA-4
public class CommandType {
  private static final String CMD_TYPE = "qq_MenuCommandType";
 
  /**
   * An interface used to enable and disable menu picks based on the state of an action
   * @author Tim
   */
  private static interface MenuAwareTextAction {
    public abstract boolean shouldBeEnabled();
  }
 
  /**
   * Return the JTextComponent that currently has focus. If the current focus owner is
   * not a JTextComponent, then null will be returned. We tend not to use TextAction.getTextComponent
   * as there is no guarantee that the returned item will actually have the focus; instead it returns
   * the last focused text component
   * @return
   */
  private static JTextComponent getFocusedTextComponent() {
    Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
    if (owner instanceof JTextComponent) {
      return (JTextComponent)owner;
    }
    return null;
  }
 
  /**
   * Set the position of the caret on the text field. This will call <code>target.setCaretPosition</code>
   * however it will delay the setting. This is useful in situations where the target cursor position is
   * affected by a menu pick, and the focus change to the menu alters the caret position
   * @param target
   * @param position
   */
  private static void setCaretPosition(final JTextComponent target, final int position) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        target.setCaretPosition(position);
      }
    });
  }
  /**
   * Create a DeleteAction which can remove code from a text field. This will automatically
   * enable and disable the field based on whether there is some text selected and the field
   * is enabled and editable.
   * @author Tim
   *
   */
    @SuppressWarnings("serial")
  public static class DeleteAction extends TextAction implements MenuAwareTextAction {
      public DeleteAction() {
        super("Delete");
    }
     
        /**
         * The operation to perform when this action is triggered. Remove the information
         * from the field between the start and end of the selection
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getFocusedTextComponent();
            if (target != null && target.isEnabled() && target.isEditable()) {
              int dot = target.getCaret().getDot();
              int mark = target.getCaret().getMark();
              try {
          target.getDocument().remove(Math.min(dot, mark), Math.abs(mark-dot));
          setCaretPosition(target, Math.min(mark, dot));
        } catch (BadLocationException e1) {
          e1.printStackTrace();
        }
            }
        }
       
        /**
         * The delete action should be enabled on the menu only if we have selected text and the control is editable
         */
        public boolean shouldBeEnabled() {
          JTextComponent target = getFocusedTextComponent();
          return (target != null && target.isEditable() && target.isEnabled() && target.getSelectedText() != null);
        }
    }

  /**
   * Create a CopyAction which can copy code from a text field. This will automatically
   * enable and disable the field based on whether there is some text selected.
   * @author Tim
   *
   */
    @SuppressWarnings("serial")
  public static class CopyAction extends DefaultEditorKit.CopyAction implements MenuAwareTextAction {
      @Override
      public void actionPerformed(ActionEvent e) {
        super.actionPerformed(e);
            final JTextComponent target = getTextComponent(e);
            final int start = target.getSelectionStart();
            final int end = target.getSelectionEnd();
            SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                target.select(start, end);
              }
            });
      }
      public boolean shouldBeEnabled() {
          JTextComponent target = getFocusedTextComponent();
          return (target != null && target.isEnabled() && target.getSelectedText() != null);
      }
    }
   
  /**
   * Create a CutAction which can remove code from a text field. This will automatically
   * enable and disable the field based on whether there is some text selected and the field
   * is enabled and editable.
   * @author Tim
   */
    @SuppressWarnings("serial")
  public static class CutAction extends DefaultEditorKit.CutAction implements MenuAwareTextAction {
      @Override
      public void actionPerformed(ActionEvent e) {
        super.actionPerformed(e);
            JTextComponent target = getTextComponent(e);
        setCaretPosition(target, target.getCaretPosition());
      }
      public boolean shouldBeEnabled() {
          JTextComponent target = getFocusedTextComponent();
          return (target != null && target.isEditable() && target.isEnabled() && target.getSelectedText() != null);
      }
    }
   
  /**
   * Create a PasteAction which can insert code from a text field. This will automatically
   * enable and disable the field based on whether there is some text in the clipboard and
   * the field is enabled and editable.
   * @author Tim
   */
    @SuppressWarnings("serial")
  public static class PasteAction extends DefaultEditorKit.PasteAction implements MenuAwareTextAction {
      @Override
      public void actionPerformed(ActionEvent e) {
        super.actionPerformed(e);
            JTextComponent target = getTextComponent(e);
        setCaretPosition(target, target.getCaretPosition());
      }
      /**
       * The paste action will only be enabled if the control is editable and there is code in the clipboard
       */
      public boolean shouldBeEnabled() {
          JTextComponent target = getFocusedTextComponent();
          return (target != null && target.isEditable() && target.isEnabled() && Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null) != null);
      }
    }
   
    /**
     * Install a monitor for the parent on the menu command. When the parent menu is shown, this monitor will
     * invoke the <code>shouldBeEnabled</code> method on each MenuAwareTextAction, and enable or disable the
     * menu based on this information
     * @param menuCmd
     */
    private static void installMonitorForParent(final JMenuItem menuCmd) {
      Container c = menuCmd.getParent();
      if (c instanceof JPopupMenu) {
        c = (Container)((JPopupMenu)c).getInvoker();
      }
      if (c instanceof JMenu && menuCmd.getAction() instanceof MenuAwareTextAction) {
        JMenu parentMenu = (JMenu)c;
        parentMenu.addMenuListener(new MenuListener() {
          public void menuCanceled(MenuEvent e) {}
          public void menuDeselected(MenuEvent e) {}
          public void menuSelected(MenuEvent e) {
            boolean isEnabled = ((MenuAwareTextAction)menuCmd.getAction()).shouldBeEnabled();
            menuCmd.setEnabled(isEnabled);
          }
        });
      }
    }
    /**
     * We need to monitor this menu, so that when the menu which contains this menu item
     * is displayed, we need to invoke the isEnabled method on the action to enable / disable the menu
     * @param menuCmd
     */
    private static void monitor(final JMenuItem menuCmd) {
      installMonitorForParent(menuCmd);
      menuCmd.addHierarchyListener(new HierarchyListener() {
        public void hierarchyChanged(HierarchyEvent e) {
          if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED && (e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0) {
            installMonitorForParent(menuCmd);
          }
        }
      });
    }
   
    /**
     * Remove any action listeners from the control which are the same class as the passed type.
     * @param menuCmd
     * @param actionClass
     */
    private static void removeListener(JMenuItem menuCmd, Class<? extends AbstractAction> actionClass) {
      ActionListener[] list = menuCmd.getActionListeners();
      for (ActionListener item : list) {
        if (actionClass.isAssignableFrom(item.getClass())) {
          menuCmd.removeActionListener(item);
        }
      }
    }
   
    /**
     * Set the type of this menu item. This will possibly install handlers to enable and disable
     * menu items as appropriate, such as Cut, Copy, Delete and Paste menu items.
     * @param menuCmd
     * @param type
     */
  public static void set(JMenuItem menuCmd, int type){
    menuCmd.putClientProperty(CMD_TYPE, new Integer(type));
   
    // CONV:TF:21 Jul 2009:Extended this to cover the command types and update the menus
    switch (type) {
      case Constants.CT_DELETE:
        removeListener(menuCmd, DeleteAction.class);
        menuCmd.setAction(new DeleteAction());
        menuCmd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
        monitor(menuCmd);
        break;
       
      case Constants.CT_COPY:
        removeListener(menuCmd, DefaultEditorKit.CopyAction.class);
        menuCmd.setAction(new CopyAction());
        menuCmd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
        monitor(menuCmd);
        break;
       
      case Constants.CT_CUT:
        removeListener(menuCmd, DefaultEditorKit.CutAction.class);
        menuCmd.setAction(new CutAction());
        menuCmd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
        monitor(menuCmd);
        break;
       
      case Constants.CT_PASTE:
        removeListener(menuCmd, DefaultEditorKit.PasteAction.class);
        menuCmd.setAction(new PasteAction());
        menuCmd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), false));
        monitor(menuCmd);
        break;     
       
      case Constants.CT_HELPCONTENTS:
        // The help contents menus never appeared in Forte, so hide it
        menuCmd.setVisible(false);
        break;
    }
  }
 
  /**
   * Return the type of this menu item.
   * @param menuCmd
   * @return
   */
  public static int get(JMenuItem menuCmd){
    return ((Integer)menuCmd.getClientProperty(CMD_TYPE)).intValue();
  }
}
TOP

Related Classes of DisplayProject.actions.CommandType

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.