⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inputhandler.java

📁 报表设计软件,很好的
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package org.jfree.designer.text.jedit;

/*
 * InputHandler.java - Manages key bindings and executes actions
 * Copyright (C) 1999 Slava Pestov
 *
 * You may use and modify this package for any purpose. Redistribution is
 * permitted, in both source and binary form, provided that this notice
 * remains intact in all source distributions of this package.
 */

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Enumeration;
import java.util.EventObject;
import java.util.Hashtable;
import javax.swing.JPopupMenu;
import javax.swing.text.BadLocationException;

/**
 * An input handler converts the user's key strokes into concrete actions. It also takes
 * care of macro recording and action repetition.<p>
 * <p/>
 * This class provides all the necessary support code for an input handler, but doesn't
 * actually do any key binding logic. It is up to the implementations of this class to do
 * so.
 *
 * @author Slava Pestov
 * @version $Id: InputHandler.java,v 1.3 2004/04/20 18:54:42 taqua Exp $ //@see
 *          com.efs.transfix.gui.components.jEditTextArea.DefaultInputHandler
 */
public abstract class InputHandler
        extends KeyAdapter
{
  /**
   * If this client property is set to Boolean.TRUE on the text area, the home/end keys
   * will support 'smart' BRIEF-like behaviour (one press = start/end of line, two presses
   * = start/end of viewscreen, three presses = start/end of document). By default, this
   * property is not set.
   */
  private static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";

  protected static final ActionListener BACKSPACE = new BackspaceAction();
  protected static final ActionListener BACKSPACE_WORD = new BackspaceWordAction();
  protected static final ActionListener DELETE = new DeleteAction();
  protected static final ActionListener DELETE_WORD = new DeleteWordAction();
  protected static final ActionListener END = new EndAction(false);
  protected static final ActionListener DOCUMENT_END = new DocumentEndAction(false);
  protected static final ActionListener SELECT_END = new EndAction(true);
  protected static final ActionListener SELECT_DOC_END = new DocumentEndAction(true);
  protected static final ActionListener INSERT_BREAK = new InsertBreakAction();
  protected static final ActionListener INSERT_TAB = new InsertTabAction();
  protected static final ActionListener HOME = new HomeAction(false);
  protected static final ActionListener DOCUMENT_HOME = new DocumentHomeAction(false);
  protected static final ActionListener SELECT_HOME = new HomeAction(true);
  protected static final ActionListener SELECT_DOC_HOME = new DocumentHomeAction(true);
  protected static final ActionListener NEXT_CHAR = new NextCharAction(false);
  protected static final ActionListener NEXT_LINE = new NextLineAction(false);
  protected static final ActionListener NEXT_PAGE = new NextPageAction(false);
  protected static final ActionListener NEXT_WORD = new NextWordAction(false);
  protected static final ActionListener SELECT_NEXT_CHAR = new NextCharAction(true);
  protected static final ActionListener SELECT_NEXT_LINE = new NextLineAction(true);
  protected static final ActionListener SELECT_NEXT_PAGE = new NextPageAction(true);
  protected static final ActionListener SELECT_NEXT_WORD = new NextWordAction(true);
  protected static final ActionListener OVERWRITE = new OverwriteAction();
  protected static final ActionListener PREV_CHAR = new PrevCharAction(false);
  protected static final ActionListener PREV_LINE = new PrevLineAction(false);
  protected static final ActionListener PREV_PAGE = new PrevPageAction(false);
  protected static final ActionListener PREV_WORD = new PrevWordAction(false);
  protected static final ActionListener SELECT_PREV_CHAR = new PrevCharAction(true);
  protected static final ActionListener SELECT_PREV_LINE = new PrevLineAction(true);
  protected static final ActionListener SELECT_PREV_PAGE = new PrevPageAction(true);
  protected static final ActionListener SELECT_PREV_WORD = new PrevWordAction(true);
  protected static final ActionListener REPEAT = new RepeatAction();
  protected static final ActionListener TOGGLE_RECT = new ToogleRectAction();

  //
  protected static final ActionListener COPY = new CopyAction();
  protected static final ActionListener PASTE = new PasteAction();
  protected static final ActionListener CUT = new CutAction();

  // Default action
  protected static final ActionListener INSERT_CHAR = new InsertCharAction();

  private static final Hashtable actions = new Hashtable();

  static
  {
    actions.put("backspace", BACKSPACE);
    actions.put("backspace-word", BACKSPACE_WORD);
    actions.put("delete", DELETE);
    actions.put("delete-word", DELETE_WORD);
    actions.put("end", END);
    actions.put("select-end", SELECT_END);
    actions.put("document-end", DOCUMENT_END);
    actions.put("select-doc-end", SELECT_DOC_END);
    actions.put("insert-break", INSERT_BREAK);
    actions.put("insert-tab", INSERT_TAB);
    actions.put("home", HOME);
    actions.put("select-home", SELECT_HOME);
    actions.put("document-home", DOCUMENT_HOME);
    actions.put("select-doc-home", SELECT_DOC_HOME);
    actions.put("next-char", NEXT_CHAR);
    actions.put("next-line", NEXT_LINE);
    actions.put("next-page", NEXT_PAGE);
    actions.put("next-word", NEXT_WORD);
    actions.put("select-next-char", SELECT_NEXT_CHAR);
    actions.put("select-next-line", SELECT_NEXT_LINE);
    actions.put("select-next-page", SELECT_NEXT_PAGE);
    actions.put("select-next-word", SELECT_NEXT_WORD);
    actions.put("overwrite", OVERWRITE);
    actions.put("prev-char", PREV_CHAR);
    actions.put("prev-line", PREV_LINE);
    actions.put("prev-page", PREV_PAGE);
    actions.put("prev-word", PREV_WORD);
    actions.put("select-prev-char", SELECT_PREV_CHAR);
    actions.put("select-prev-line", SELECT_PREV_LINE);
    actions.put("select-prev-page", SELECT_PREV_PAGE);
    actions.put("select-prev-word", SELECT_PREV_WORD);
    actions.put("repeat", REPEAT);
    actions.put("toggle-rect", TOGGLE_RECT);
    actions.put("insert-char", INSERT_CHAR);
  }

  /**
   * Returns a named text area action.
   *
   * @param name The action name
   */
  private static ActionListener getAction (final String name)
  {
    return (ActionListener) actions.get(name);
  }

  /**
   * Returns the name of the specified text area action.
   *
   * @param listener The action
   */
  public static String getActionName (final ActionListener listener)
  {
    final Enumeration enum = getActions();
    while (enum.hasMoreElements())
    {
      final String name = (String) enum.nextElement();
      final ActionListener localAction = getAction(name);
      if (localAction == listener)
      {
        return name;
      }
    }
    return null;
  }

  /**
   * Returns an enumeration of all available actions.
   */
  private static Enumeration getActions ()
  {
    return actions.keys();
  }

  /**
   * Adds the default key bindings to this input handler. This should not be called in the
   * constructor of this input handler, because applications might load the key bindings
   * from a file, etc.
   */
  public abstract void addDefaultKeyBindings ();

  /**
   * Adds a key binding to this input handler.
   *
   * @param keyBinding The key binding (the format of this is input-handler specific)
   * @param action     The action
   */
  public abstract void addKeyBinding (String keyBinding, ActionListener action);

  /**
   * Removes a key binding from this input handler.
   *
   * @param keyBinding The key binding
   */
  public abstract void removeKeyBinding (String keyBinding);

  /**
   * Removes all key bindings from this input handler.
   */
  public abstract void removeAllKeyBindings ();

  /**
   * Grabs the next key typed event and invokes the specified action with the key as a the
   * action command.
   *
   * @param listener The action
   */
  public final void grabNextKeyStroke (final ActionListener listener)
  {
    grabAction = listener;
  }

  /**
   * Returns if repeating is enabled. When repeating is enabled, actions will be executed
   * multiple times. This is usually invoked with a special key stroke in the input
   * handler.
   */
  public final boolean isRepeatEnabled ()
  {
    return repeat;
  }

  /**
   * Enables repeating. When repeating is enabled, actions will be executed multiple
   * times. Once repeating is enabled, the input handler should read a number from the
   * keyboard.
   */
  private void setRepeatEnabled (final boolean repeat)
  {
    this.repeat = repeat;
  }

  /**
   * Returns the number of times the next action will be repeated.
   */
  public final int getRepeatCount ()
  {
    return (repeat ? Math.max(1, repeatCount) : 1);
  }

  /**
   * Sets the number of times the next action will be repeated.
   *
   * @param repeatCount The repeat count
   */
  private void setRepeatCount (final int repeatCount)
  {
    this.repeatCount = repeatCount;
  }

  /**
   * Returns the macro recorder. If this is non-null, all executed actions should be
   * forwarded to the recorder.
   */
  public final MacroRecorder getMacroRecorder ()
  {
    return recorder;
  }

  /**
   * Sets the macro recorder. If this is non-null, all executed actions should be
   * forwarded to the recorder.
   *
   * @param recorder The macro recorder
   */
  public final void setMacroRecorder (final MacroRecorder recorder)
  {
    this.recorder = recorder;
  }

  /**
   * Returns a copy of this input handler that shares the same key bindings. Setting key
   * bindings in the copy will also set them in the original.
   */
  public abstract InputHandler copy ();

  /**
   * Executes the specified action, repeating and recording it as necessary.
   *
   * @param listener      The action listener
   * @param source        The event source
   * @param actionCommand The action command
   */
  protected final void executeAction (final ActionListener listener, final Object source,
                                final String actionCommand)
  {
    // create event
    final ActionEvent evt = new ActionEvent(source,
            ActionEvent.ACTION_PERFORMED,
            actionCommand);

    // don't do anything if the action is a wrapper
    // (like EditAction.Wrapper)
    if (listener instanceof Wrapper)
    {
      listener.actionPerformed(evt);
      return;
    }

    // remember old values, in case action changes them
    final boolean oldRepeat = repeat;
    final int oldRepeatCount = getRepeatCount();

    // execute the action
    if (listener instanceof NonRepeatable)
    {
      listener.actionPerformed(evt);
    }
    else
    {
      for (int i = 0; i < Math.max(1, repeatCount); i++)
      {
        listener.actionPerformed(evt);
      }
    }

    // do recording. Notice that we do no recording whatsoever
    // for actions that grab keys
    if (grabAction == null)
    {
      if (recorder != null)
      {
        if (!(listener instanceof NonRecordable))
        {
          if (oldRepeatCount != 1)
          {
            recorder.actionPerformed(REPEAT, String.valueOf(oldRepeatCount));
          }

          recorder.actionPerformed(listener, actionCommand);
        }
      }

      // If repeat was true originally, clear it
      // Otherwise it might have been set by the action, etc
      if (oldRepeat)
      {
        repeat = false;
        repeatCount = 0;
      }
    }
  }

  /**
   * Returns the text area that fired the specified event.
   *
   * @param evt The event
   */
  private static JEditTextArea getTextArea (final EventObject evt)
  {
    if (evt != null)
    {
      final Object o = evt.getSource();
      if (o instanceof Component)
      {
        // find the parent text area
        Component c = (Component) o;
        for (; ;)
        {
          if (c instanceof JEditTextArea)
          {
            return (JEditTextArea) c;
          }
          else if (c == null)
          {
            break;
          }
          if (c instanceof JPopupMenu)
          {
            c = ((JPopupMenu) c).getInvoker();
          }
          else
          {
            c = c.getParent();
          }
        }
      }
    }

    // this shouldn't happen
    System.err.println("BUG: getTextArea() returning null");
    System.err.println("Report this to Slava Pestov <sp@gjt.org>");
    return null;
  }

  // protected members

  /**
   * If a key is being grabbed, this method should be called with the appropriate key
   * event. It executes the grab action with the typed character as the parameter.
   */
  protected final void handleGrabAction (final KeyEvent evt)
  {
    // Clear it *before* it is executed so that executeAction()
    // resets the repeat count
    final ActionListener orgGrabAction = grabAction;
    grabAction = null;
    executeAction(orgGrabAction, evt.getSource(),
            String.valueOf(evt.getKeyChar()));
  }

  // protected members
  protected ActionListener grabAction;
  protected boolean repeat;
  protected int repeatCount;
  private MacroRecorder recorder;

  /**
   * If an action implements this interface, it should not be repeated. Instead, it will
   * handle the repetition itself.
   */
  public interface NonRepeatable
  {
  }

  /**
   * If an action implements this interface, it should not be recorded by the macro

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -