inputhandler.java

来自「java写的多功能文件编辑器」· Java 代码 · 共 1,230 行 · 第 1/3 页

JAVA
1,230
字号
/* * InputHandler.java - Manages key bindings and executes actions * Copyright (C) 1999 Slava Pestov * * 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package org.gjt.sp.jedit.textarea;import javax.swing.text.*;import javax.swing.JPopupMenu;import java.awt.event.*;import java.awt.Component;import java.util.*;import org.jext.*;/** * An input handler converts the user's key strokes into concrete actions. * It also takes care of macro recording and action repetition.<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.4 2003/07/08 18:55:50 blaisorblade Exp $ * @see org.gjt.sp.jedit.textarea.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.   */  public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";  public static final ActionListener BACKSPACE = new backspace();  public static final ActionListener BACKSPACE_WORD = new backspace_word();  public static final ActionListener DELETE = new delete();  public static final ActionListener DELETE_WORD = new delete_word();  public static final ActionListener END = new end(false);  public static final ActionListener DOCUMENT_END = new document_end(false);  public static final ActionListener SELECT_END = new end(true);  public static final ActionListener SELECT_DOC_END = new document_end(true);  public static final ActionListener INSERT_BREAK = new insert_break();  public static final ActionListener INSERT_TAB = new insert_tab();  public static final ActionListener HOME = new home(false);  public static final ActionListener DOCUMENT_HOME = new document_home(false);  public static final ActionListener SELECT_HOME = new home(true);  public static final ActionListener SELECT_DOC_HOME = new document_home(true);  public static final ActionListener NEXT_CHAR = new next_char(false);  public static final ActionListener NEXT_LINE = new next_line(false);  public static final ActionListener NEXT_PAGE = new next_page(false);  public static final ActionListener NEXT_WORD = new next_word(false);  public static final ActionListener SELECT_NEXT_CHAR = new next_char(true);  public static final ActionListener SELECT_NEXT_LINE = new next_line(true);  public static final ActionListener SELECT_NEXT_PAGE = new next_page(true);  public static final ActionListener SELECT_NEXT_WORD = new next_word(true);  public static final ActionListener OVERWRITE = new overwrite();  public static final ActionListener PREV_CHAR = new prev_char(false);  public static final ActionListener PREV_LINE = new prev_line(false);  public static final ActionListener PREV_PAGE = new prev_page(false);  public static final ActionListener PREV_WORD = new prev_word(false);  public static final ActionListener SELECT_PREV_CHAR = new prev_char(true);  public static final ActionListener SELECT_PREV_LINE = new prev_line(true);  public static final ActionListener SELECT_PREV_PAGE = new prev_page(true);  public static final ActionListener SELECT_PREV_WORD = new prev_word(true);  public static final ActionListener REPEAT = new repeat();  // Default action  public static final ActionListener INSERT_CHAR = new insert_char();  private static Hashtable actions;  static  {    actions = new Hashtable();    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("insert-char",INSERT_CHAR);  }  /**   * Returns a named text area action.   * @param name The action name   */  public static ActionListener getAction(String name)  {    return (ActionListener)actions.get(name);  }  /**   * Returns the name of the specified text area action.   * @param listener The action   */  public static String getActionName(ActionListener listener)  {    Enumeration enum = getActions();    while(enum.hasMoreElements())    {      String name = (String)enum.nextElement();      ActionListener _listener = getAction(name);      if(_listener == listener)        return name;    }    return null;  }  /**   * Returns an enumeration of all available actions.   */  public 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 action The action   */  public void grabNextKeyStroke(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 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.   */  public void setRepeatEnabled(boolean repeat)  {    this.repeat = repeat;    if(!repeat)      repeatCount = 0;  }  /**   * Returns the number of times the next action will be repeated.   */  public 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   */  public void setRepeatCount(int repeatCount)  {    this.repeatCount = repeatCount;  }  /**   * Returns the action used to handle text input.   */  public ActionListener getInputAction()  {    return inputAction;  }  /**   * Sets the action used to handle text input.   * @param inputAction The new input action   */  public void setInputAction(ActionListener inputAction)  {    this.inputAction = inputAction;  }    /**   * Returns the macro recorder. If this is non-null, all executed   * actions should be forwarded to the recorder.   */  public InputHandler.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 void setMacroRecorder(InputHandler.MacroRecorder recorder)  {    this.recorder = recorder;  }  public void executeOneClickAction(org.jext.OneClickAction listener, Object source,    String actionCommand)  {    // create event    ActionEvent evt = new ActionEvent(source,      ActionEvent.ACTION_PERFORMED,      actionCommand);    listener.oneClickActionPerformed(evt);  }  /**   * 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   */  public void executeAction(ActionListener listener, Object source, String actionCommand)  {    // create event    ActionEvent evt = new ActionEvent(source, ActionEvent.ACTION_PERFORMED, actionCommand);    if (listener instanceof EditAction && !getTextArea(evt).isEditable())      return;    getTextArea(evt).setOneClick(null);    // 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    boolean _repeat = repeat;    int _repeatCount = getRepeatCount();    // execute the action    if(listener instanceof InputHandler.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 InputHandler.NonRecordable))        {          if(_repeatCount != 1)            recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));          recorder.actionPerformed(listener,actionCommand);        }      }      // If repeat was true originally, clear it      // Otherwise it might have been set by the action, etc      if(_repeat)        setRepeatEnabled(false);    }  }  /**   * Returns the text area that fired the specified event.   * @param evt The event   */  public static JEditTextArea getTextArea(EventObject evt)  {    if(evt != null)    {      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 if (c instanceof JextFrame)            c = ((JextFrame) c).getTextArea();          else            c = c.getParent();        }      }    }    // this shouldn't happen    System.err.println("BUG: getTextArea() returning null");    System.err.println("Report this to Romain Guy <romain.guy@jext.org>");    return null;  }  // protected members  protected ActionListener inputAction = INSERT_CHAR;  protected ActionListener grabAction;  protected boolean repeat;  protected int repeatCount;  protected InputHandler.MacroRecorder recorder;  /**   * 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 void handleGrabAction(KeyEvent evt)  {    // Clear it *before* it is executed so that executeAction()    // resets the repeat count    ActionListener _grabAction = grabAction;    grabAction = null;    char keyChar = evt.getKeyChar();    int keyCode = evt.getKeyCode();    String arg;    if(keyChar != KeyEvent.VK_UNDEFINED)      arg = String.valueOf(keyChar);    else if(keyCode == KeyEvent.VK_TAB)      arg = "\t";    else if(keyCode == KeyEvent.VK_ENTER)      arg = "\n";

⌨️ 快捷键说明

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