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 + -
显示快捷键?