defaultinputhandler.java

来自「java写的多功能文件编辑器」· Java 代码 · 共 393 行

JAVA
393
字号
/* * DefaultInputHandler.java - Default implementation of an input handler * 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.KeyStroke;import java.awt.event.*;import java.awt.Toolkit;import java.util.Hashtable;import java.util.StringTokenizer;import org.jext.*;/** * The default input handler. It maps sequences of keystrokes into actions * and inserts key typed events into the text area. * @author Slava Pestov * @version $Id: DefaultInputHandler.java,v 1.6 2002/08/09 14:16:38 orangeherbert Exp $ */public class DefaultInputHandler extends InputHandler{  /**   * Creates a new input handler with no key bindings defined.   */  public DefaultInputHandler()  {    bindings = currentBindings = new Hashtable();  }  /**   * Creates a new input handler with the same set of key bindings   * as the one specified. Note that both input handlers share   * a pointer to exactly the same key binding table; so adding   * a key binding in one will also add it to the other.   * @param copy The input handler to copy key bindings from   */  public DefaultInputHandler(DefaultInputHandler copy)  {    bindings = currentBindings = copy.bindings;  }  /**   * Sets up the default key bindings.   */  public void addDefaultKeyBindings()  {    addKeyBinding("BACK_SPACE",BACKSPACE);    addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);    addKeyBinding("DELETE",DELETE);    addKeyBinding("C+DELETE",DELETE_WORD);    addKeyBinding("ENTER",INSERT_BREAK);    addKeyBinding("TAB",INSERT_TAB);    addKeyBinding("INSERT",OVERWRITE);    addKeyBinding("HOME",HOME);    addKeyBinding("END",END);    addKeyBinding("S+HOME",SELECT_HOME);    addKeyBinding("S+END",SELECT_END);    addKeyBinding("C+HOME",DOCUMENT_HOME);    addKeyBinding("C+END",DOCUMENT_END);    addKeyBinding("CS+HOME",SELECT_DOC_HOME);    addKeyBinding("CS+END",SELECT_DOC_END);    addKeyBinding("PAGE_UP",PREV_PAGE);    addKeyBinding("PAGE_DOWN",NEXT_PAGE);    addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);    addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);    addKeyBinding("LEFT",PREV_CHAR);    addKeyBinding("S+LEFT",SELECT_PREV_CHAR);    addKeyBinding("C+LEFT",PREV_WORD);    addKeyBinding("CS+LEFT",SELECT_PREV_WORD);    addKeyBinding("RIGHT",NEXT_CHAR);    addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);    addKeyBinding("C+RIGHT",NEXT_WORD);    addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);    addKeyBinding("UP",PREV_LINE);    addKeyBinding("S+UP",SELECT_PREV_LINE);    addKeyBinding("DOWN",NEXT_LINE);    addKeyBinding("S+DOWN",SELECT_NEXT_LINE);    addKeyBinding("C+ENTER",REPEAT);  }  /**   * Adds a key binding to this input handler. The key binding is   * a list of white space separated key strokes of the form   * <i>[modifiers+]key</i> where modifier is C for Control, A for Alt,   * or S for Shift, and key is either a character (a-z) or a field   * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)   * @param keyBinding The key binding   * @param action The action   */  public void addKeyBinding(String keyBinding, ActionListener action)  {    Hashtable current = bindings;    StringTokenizer st = new StringTokenizer(keyBinding);    while(st.hasMoreTokens())    {      KeyStroke keyStroke = parseKeyStroke(st.nextToken());      if (keyStroke == null)        return;      if (st.hasMoreTokens())      {        Object o = current.get(keyStroke);        if(o instanceof Hashtable)          current = (Hashtable)o;        else        {          o = new Hashtable();          current.put(keyStroke,o);          current = (Hashtable)o;        }      } else        current.put(keyStroke,action);    }  }  /**   * Removes a key binding from this input handler. This is not yet   * implemented.   * @param keyBinding The key binding   */  public void removeKeyBinding(String keyBinding)  {    throw new InternalError("Not yet implemented");  }  /**   * Removes all key bindings from this input handler.   */  public void removeAllKeyBindings()  {    bindings.clear();  }  /**   * Handle a key pressed event. This will look up the binding for   * the key stroke and execute it.   */  public void keyPressed(KeyEvent evt)  {    int keyCode = evt.getKeyCode();    int modifiers = evt.getModifiers();    if (keyCode == KeyEvent.VK_CONTROL ||        keyCode == KeyEvent.VK_SHIFT ||        keyCode == KeyEvent.VK_ALT ||        keyCode == KeyEvent.VK_META)      return;    if (evt.isShiftDown())    {      if (grabAction != null)      {        handleGrabAction(evt);        return;      }      KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers);      Object o = currentBindings.get(keyStroke);      if (o == null)      {        // Don't beep if the user presses some        // key we don't know about unless a        // prefix is active. Otherwise it will        // beep when caps lock is pressed, etc.        if (currentBindings != bindings)        {          Toolkit.getDefaultToolkit().beep();          // F10 should be passed on, but C+e F10          // shouldn't          repeatCount = 0;          repeat = false;          evt.consume();        }        currentBindings = bindings;        return;      } else if(o instanceof ActionListener) {        currentBindings = bindings;        ((JextTextArea) getTextArea(evt)).endCurrentEdit();        executeAction(((ActionListener)o), evt.getSource(), null);        evt.consume();        return;      } else if(o instanceof Hashtable) {        currentBindings = (Hashtable)o;        evt.consume();        return;      }    }     else if (!evt.isShiftDown()        || evt.isActionKey()        || keyCode == KeyEvent.VK_BACK_SPACE        || keyCode == KeyEvent.VK_DELETE        || keyCode == KeyEvent.VK_ENTER        || keyCode == KeyEvent.VK_TAB        || keyCode == KeyEvent.VK_ESCAPE)    {      if (grabAction != null)      {        handleGrabAction(evt);        return;      }      KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers);      Object o = currentBindings.get(keyStroke);      if (o == null)      {        // Don't beep if the user presses some        // key we don't know about unless a        // prefix is active. Otherwise it will        // beep when caps lock is pressed, etc.        if (currentBindings != bindings)        {          Toolkit.getDefaultToolkit().beep();          // F10 should be passed on, but C+e F10          // shouldn't          repeatCount = 0;          repeat = false;          evt.consume();        }        currentBindings = bindings;        return;      } else if(o instanceof ActionListener) {        currentBindings = bindings;        ((JextTextArea) getTextArea(evt)).endCurrentEdit();        executeAction(((ActionListener)o), evt.getSource(), null);        evt.consume();        return;      } else if(o instanceof Hashtable) {        currentBindings = (Hashtable)o;        evt.consume();        return;      }    }  }  /**   * Handle a key typed event. This inserts the key into the text area.   */  public void keyTyped(KeyEvent evt)  {    char c = evt.getKeyChar();    if (c != KeyEvent.CHAR_UNDEFINED && !evt.isAltDown())    {      if (c >= 0x20 && c != 0x7f)      {        KeyStroke keyStroke = KeyStroke.getKeyStroke(Character.toUpperCase(c));        Object o = currentBindings.get(keyStroke);        if (o instanceof Hashtable)        {          currentBindings = (Hashtable)o;          return;        } else if (o instanceof org.jext.OneClickAction) {          currentBindings = bindings;          ((JextTextArea) getTextArea(evt)).endCurrentEdit();          executeOneClickAction((org.jext.OneClickAction) o, evt.getSource(), String.valueOf(c));          return;        } else if (o instanceof ActionListener) {          currentBindings = bindings;          ((JextTextArea) getTextArea(evt)).endCurrentEdit();          executeAction((ActionListener)o, evt.getSource(), String.valueOf(c));          return;        }        currentBindings = bindings;        if (grabAction != null)        {          handleGrabAction(evt);          return;        }        // 0-9 adds another 'digit' to the repeat number        if (repeat && Character.isDigit(c))        {          setRepeatCount(repeatCount * 10 + (c - '0'));          evt.consume();          return;        }         executeAction(inputAction, evt.getSource(), String.valueOf(evt.getKeyChar()));        //if (!evt.isControlDown())        //System.out.println(evt.isControlDown());        ((JextTextArea) getTextArea(evt)).userInput(c);        repeatCount = 0;        repeat = false;      }    }  }  /**   * Converts a string to a keystroke. The string should be of the   * form <i>modifiers</i>+<i>shortcut</i> where <i>modifiers</i>   * is any combination of A for Alt, C for Control, S for Shift   * or M for Meta, and <i>shortcut</i> is either a single character,   * or a keycode name from the <code>KeyEvent</code> class, without   * the <code>VK_</code> prefix.   * @param keyStroke A string description of the key stroke   */  public static KeyStroke parseKeyStroke(String keyStroke)  {    if (keyStroke == null)      return null;    int modifiers = 0;    int index = keyStroke.indexOf('+');    if (index != -1)    {      for(int i = 0; i < index; i++)      {        switch(Character.toUpperCase(keyStroke.charAt(i)))        {          case 'A':            modifiers |= InputEvent.ALT_MASK;            break;          case 'C':            modifiers |= Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); //InputEvent.CTRL_MASK;            break;          case 'M':            modifiers |= InputEvent.META_MASK;            break;          case 'S':            modifiers |= InputEvent.SHIFT_MASK;            break;        }      }    }    String key = keyStroke.substring(index + 1);    if (key.length() == 1)    {      char ch = Character.toUpperCase(key.charAt(0));      if(modifiers == 0)        return KeyStroke.getKeyStroke(ch);      else        return KeyStroke.getKeyStroke(ch,modifiers);    } else if(key.length() == 0) {      System.err.println("Invalid key stroke: " + keyStroke);      return null;    } else {      int ch;      try      {        ch = KeyEvent.class.getField("VK_".concat(key)).getInt(null);      } catch(Exception e) {        System.err.println("Invalid key stroke: " + keyStroke);        return null;      }      return KeyStroke.getKeyStroke(ch,modifiers);    }  }  // private members  private Hashtable bindings;  private Hashtable currentBindings;}

⌨️ 快捷键说明

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