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

📄 rtextarea.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
   * from the caret position.  If a match is found, it is selected in this
   * text area.
   *
   * @param text The string literal or regular expression to search for.
   * @param forward Whether to search forward from the caret position or
   *                backward from it.
   * @param matchCase Whether the search should be case-sensitive.
   * @param wholeWord Whether there should be spaces or tabs on either side
   *                  of the match.
   * @param regex Whether <code>text</code> is a Java regular expression to
   *              search for.
   * @return Whether a match was found (and thus selected).
   */
  public boolean find(String text, boolean forward, boolean matchCase,
                      boolean wholeWord, boolean regex) {

    // Be smart about what position we're "starting" at.  For example,
    // if they are searching backwards and there is a selection such that
    // the dot is past the mark, and the selection is the text for which
    // you're searching, this search will find and return the current
    // selection.  So, in that case we start at the beginning of the
    // selection.
    Caret c = getCaret();
    int caretPosition = c.getDot();
    int start = (!forward && (c.getDot() != c.getMark())) ?
        getSelectionStart() : caretPosition;

    // Be smart about the text we grab to search in.  We grab more than
    // a single line because our searches can return multiline results.
    // We copy only the chars that will be searched through.
    String findIn = null;
    if (forward) {
      try {
        findIn = getText(start, getDocument().getLength() - start);
      }
      catch (BadLocationException ble) {
        ble.printStackTrace();
        return false;
      }
      start = 0;
    }
    else { // backward
      try {
        findIn = getText(0, start + 1);
      }
      catch (BadLocationException ble) {
        ble.printStackTrace();
        return false;
      }
    }

    // Find the next location of the text we're searching for.  If we're
    // looking for a regular expression, the returned match has a
    // possibly varying width, so we return its start and end positions
    // in a Point.
    int pos = -1;
    java.awt.Point regExPos = null;
    if (regex == false) {
      pos = FindDialog.getNextMatchPos(text, findIn, start,
                                       forward, matchCase, wholeWord);
    }
    else {
      regExPos = FindDialog.getNextMatchPosRegEx(text, findIn, start,
                                                 forward, matchCase, wholeWord);
    }

    findIn = null; // May help garbage collecting.

    // If a match was found, select it and return!
    if (pos != -1) {
      // Without this, if JTextArea isn't in focus, selection won't
      // appear selected.
      c.setSelectionVisible(true);
      pos = forward ? caretPosition + pos : pos;
      c.setDot(pos);
      c.moveDot(pos + text.length());
      return true;
    }
    else if (regExPos != null) {
      // Without this, if JTextArea isn't in focus, selection won't
      // appear selected.
      c.setSelectionVisible(true);
      if (forward) {
        regExPos.translate(caretPosition, caretPosition);
      }
      c.setDot(regExPos.x);
      c.moveDot(regExPos.y);
      return true;
    }

    // No match.
    return false;

  }

      /*****************************************************************************/

  /**
   * Notifies all listeners that a caret change has occured.
   *
   * @param e The caret event.
   */
  protected void fireCaretUpdate(CaretEvent e) {

    // Decide whether we need to repaint the current line background.
    possiblyUpdateCurrentLineHighlightLocation();

    // Now, if there is a highlighted region of text, allow them to cut
    // and copy.
    if (e != null && e.getDot() != e.getMark()) { // && !cutAction.isEnabled()) {
      cutAction.setEnabled(true);
      copyAction.setEnabled(true);
    }

    // Otherwise, if there is no highlighted region, don't let them cut
    // or copy.  The condition here should speed things up, because this
    // way, we will only enable the actions the first time the selection
    // becomes nothing.
    else if (cutAction.isEnabled() == true) {
      cutAction.setEnabled(false);
      copyAction.setEnabled(false);
    }

    super.fireCaretUpdate(e);

  }

      /*****************************************************************************/

  /**
   * Removes the "Ctrl+H <=> Backspace" behavior that Java shows, for some
   * odd reason...
   */
  private void fixCtrlH() {
    InputMap inputMap = getInputMap();
    KeyStroke char010 = KeyStroke.getKeyStroke("typed \010");
    InputMap parent = inputMap;
    while (parent != null) {
      parent.remove(char010);
      parent = parent.getParent();
    }
    KeyStroke backspace = KeyStroke.getKeyStroke("BACK_SPACE");
    inputMap.put(backspace, DefaultEditorKit.deletePrevCharAction);
  }

      /*****************************************************************************/

  /**
   * Provides a way to gain access to the editor actions on the right-click
   * popup menu.  This way you can make toolbar/menu bar items use the actual
   * actions used by all <code>RTextArea</code>s, so that icons stay
   * synchronized and you don't have to worry about enabling/disabling them
   * yourself.<p>
   * Keep in mind that these actions are shared across all instances of
   * <code>RTextArea</code>, so a change to any action returned by this
   * method is global across all <code>RTextArea</code> editors in your
   * application.
   *
   * @param action The action to retrieve, such as <code>CUT_ACTION</code>.
   *               If the action name is invalid, <code>null</code> is
   *               returned.
   * @return The action, or <code>null</code> if an invalid action is
   *         requested.
   */
  public static RecordableTextAction getAction(int action) {
    if (action < MIN_ACTION_CONSTANT || action > MAX_ACTION_CONSTANT) {
      return null;
    }
    switch (action) {
      case CUT_ACTION:
        return cutAction;
      case COPY_ACTION:
        return copyAction;
      case PASTE_ACTION:
        return pasteAction;
      case DELETE_ACTION:
        return deleteAction;
      case UNDO_ACTION:
        return undoAction;
      case REDO_ACTION:
        return redoAction;
      case SELECT_ALL_ACTION:
        return selectAllAction;
    }
    return null;
  }

      /*****************************************************************************/

  /**
   * Returns the macro currently stored in this <code>RTextArea</code>.
   * Since macros are shared, all <code>RTextArea</code>s in the currently-
   * running application are using this macro.
   *
   * @return The current macro, or <code>null</code> if no macro has been
   *         recorded/loaded.
   * @see #loadMacro
   */
  public static synchronized Macro getCurrentMacro() {
    return currentMacro;
  }

      /*****************************************************************************/

  /**
   * Returns the default color used for "mark all."
   *
   * @return The color.
   * @see #getMarkAllHighlightColor
   * @see #setMarkAllHighlightColor
   */
  public static final Color getDefaultMarkAllHighlightColor() {
    return DEFAULT_MARK_ALL_COLOR;
  }

      /*****************************************************************************/

  /**
   * Returns the icon group being used for the actions of this text area.
   *
   * @return The icon group.
   * @see #setIconGroup
   */
  public static IconGroup getIconGroup() {
    return iconGroup;
  }

      /*****************************************************************************/

  /**
   * Returns the color used in "mark all."
   *
   * @return The color.
   * @see #setMarkAllHighlightColor
   */
  public Color getMarkAllHighlightColor() {
    return (Color) markAllHighlightPainter.getPaint();
  }

      /*****************************************************************************/

  /**
   * Returns the maximum ascent of all fonts used in this text area.  In
   * the case of a standard <code>RTextArea</code>, this is simply the
   * ascent of the current font.<p>
   *
   * This value could be useful, for example, to implement a line-numbering
   * scheme.
   *
   * @return The ascent of the current font.
   */
  public int getMaxAscent() {
    return getFontMetrics(getFont()).getAscent();
  }

      /*****************************************************************************/

  /**
   * Returns the text mode this editor pane is currently in.
   *
   * @return Either <code>RTextArea.INSERT_MODE</code> or
   *         <code>RTextArea.OVERWRITE_MODE</code>.
   */
  public final int getTextMode() {
    return textMode;
  }

      /*****************************************************************************/

  /**
   * Does the actual dirtywork of replacing the selected text in this
   * text area (i.e., in its document).  This method provides a hook for
   * subclasses to handle this in a different way.
   *
   * @param content The content to add.
   */
  protected void handleReplaceSelection(String content) {
    Document doc = getDocument();
    if (doc != null) {
      try {
        Caret c = getCaret();
        int dot = c.getDot();
        int mark = c.getMark();
        int p0 = Math.min(dot, mark);
        int p1 = Math.max(dot, mark);
        ( (RTextAreaDocument) doc).replace(p0, p1 - p0,
                                           content, null);
      }
      catch (BadLocationException e) {
        UIManager.getLookAndFeel().
            provideErrorFeedback(RTextArea.this);
      }
    }
  }

      /*****************************************************************************/

  private static boolean first = false;
  /**
   * Creates and localizes our shared actions.
   *
   * @param ta The text area being created.
   */
  private static final synchronized void initActions(RTextArea ta) {

    // We only need to initialize the actions for the first created
    // text area, since they're shared among all text areas.
    if (!first) {

      first = true;

      ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
      cantUndoText = bundle.getString("CantUndo");
      cantRedoText = bundle.getString("CantRedo");

      // Create actions for right-click popup menu.
      // 1.5.2004/pwy: Replaced the CTRL_MASK with the cross-platform version...
      int defaultModifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

      String name = bundle.getString("CutActionName");
      char mnemonic = bundle.getString("CutActionMnemonic").charAt(0);
      cutAction = new RTextAreaEditorKit.CutAction(name, null, name,
          new Integer(mnemonic),
          KeyStroke.getKeyStroke(KeyEvent.VK_X, defaultModifier));

      name = bundle.getString("CopyActionName");
      mnemonic = bundle.getString("CopyActionMnemonic").charAt(0);
      copyAction = new RTextAreaEditorKit.CopyAction(name, null, name,
          new Integer(mnemonic),
          KeyStroke.getKeyStroke(KeyEvent.VK_C, defaultModifier));

      name = bundle.getString("PasteActionName");
      mnemonic = bundle.getString("PasteActionMnemonic").charAt(0);
      pasteAction = new RTextAreaEditorKit.PasteAction(name, null, name,
          new Integer(mnemonic),
          KeyStroke.getKeyStroke(KeyEvent.VK_V, defaultModifier));

      name = bundle.getString("DeleteActionName");
      mnemonic = bundle.getString("DeleteActionMnemonic").charAt(0);
      deleteAction = new RTextAreaEditorKit.DeleteNextCharAction(name, null,
          name,
          new Integer(mnemonic), KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));

      undoAction = new RTextAreaEditorKit.UndoAction(cantUndoText, null, "Undo",
          new Integer(KeyEvent.VK_Z),
          KeyStroke.getKeyStroke(KeyEvent.VK_Z, defaultModifier));

      redoAction = new RTextAreaEditorKit.RedoAction(cantRedoText, null, "Redo",
          new Integer(KeyEvent.VK_Y),
          KeyStroke.getKeyStroke(KeyEvent.VK_Y, defaultModifier));

      name = bundle.getString("SAActionName");
      mnemonic = bundle.getString("SAActionMnemonic").charAt(0);
      selectAllAction = new RTextAreaEditorKit.SelectAllAction(name, null, name,
          new Integer(mnemonic),
          KeyStroke.getKeyStroke(KeyEvent.VK_A, defaultModifier));

      bundle = null;

    } // End of if (!first).

  }

      /*****************************************************************************/

  /**
   * Returns whether or not RText is in the middle of an undo or redo
   * operation.  This method is package-private so that
   * <code>ConfigurableCaret</code> can know whether an insert or
   * removal is part of an undo or redo.  This method is also a giant HACK
   * to get around the fact that there is no way for a Caret to know that
   * an event is coming from an undo/redo unless the DocumentEvent passed
   * to it says so.  In J2SE5.0, DefaultCaret knows because the event is of
   * type UndoRedoDocumentEvent, but that class is (of course) package-
   * private, so we can't get to it.  So we work around it by having the
   * caret poll the text area directly.
   *
   *@return Whether the text area is currently doing an undo or redo.
   */
  boolean inUndoRedo() {
    return inUndoRedo;
  }

      /*****************************************************************************/

  /**
   * Returns whether or not a macro is being recorded.
   *
   * @return Whether or not a macro is being recorded.
   * @see #beginRecordingMacro
   * @see #endRecordingMacro
   */
  public static synchronized boolean isRecordingMacro() {
    return recordingMacro;
  }

      /*****************************************************************************/

  /**
   * Loads a macro to be used by all <code>RTextArea</code>s in the current
   * application.
   *
   * @param macro The macro to load.
   * @see #getCurrentMacro
   */
  public static synchronized void loadMacro(Macro macro) {
    currentMacro = macro;
  }

      /*****************************************************************************/

  /**
   * Marks all instances of the specified text in this text area.
   *
   * @param toMark The text to mark.
   * @param matchCase Whether the match should be case-sensitive.
   * @param wholeWord Whether the matches should be surrounded by spaces or

⌨️ 快捷键说明

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