Package DisplayProject.actions

Source Code of DisplayProject.actions.CommandType$PasteAction

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$PasteAction

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.