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

📄 linenumberborder.java~2~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~2~
📖 第 1 页 / 共 2 页
字号:
      return;
    }

    // Get the first and last lines to paint.
    int topLine = visibleRect.y / cellHeight + 1;
    int bottomLine = Math.min(topLine + visibleRect.height / cellHeight,
                              root.getElementCount()) + 1;

    // Get where to start painting (top of the row), and where to paint
    // the line number (drawString expects y==baseline).
    // We need to be "scrolled up" up just enough for the missing part of
    // the first line.
    int actualTopY = y - (visibleRect.y % cellHeight);
    Insets textAreaInsets = textArea.getInsets();
    if (textAreaInsets != null) {
      actualTopY += textAreaInsets.top;
    }
    int y2 = actualTopY + ascent;

    // Highlight the current line's line number, if desired.
    if (textArea.isCurrentLineHighlightEnabled() && currentLine >= topLine &&
        currentLine < bottomLine) {
      g.setColor(textArea.getCurrentLineHighlightColor());
      g.fillRect(x, actualTopY + (currentLine - topLine) * cellHeight,
                 insets.left, cellHeight);
    }

    // Paint the "border" line.
    g.setColor(Color.BLACK);
    g.drawLine(x + insets.left - 4, 0, x + insets.left - 4,
               visibleRect.height + 1);

    g.setColor(getForeground());
    FontMetrics metrics = g.getFontMetrics();
    int rhs = x + insets.left - RHS_BORDER_WIDTH;
    for (int i = topLine; i < bottomLine; i++) {
      String number = Integer.toString(i);
      int w = (int) metrics.getStringBounds(number, g).getWidth();
      g.drawString(number, rhs - w, y2);
      y2 += cellHeight;
    }

  }

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

  /**
   * Paints line numbers for text areas with line wrap enabled.
   *
   * @param g The graphics context.
   * @param root The root element of the document being painted.
   * @param x The x-coordinate of the border.
   * @param y The y-coordinate of the border.
   * @param visibleRect The visible rectangle of the text area.
   */
  public void paintWrappedLineNumbers(Graphics g, Element root, int x, int y,
                                      Rectangle visibleRect) {

    // The variables we use are as follows:
    // - visibleRect is the "visible" area of the text area; e.g.
    // [0,100, 300,100+(numLines*cellHeight)-1].
    // actualTop.y is the topmost-pixel in the first logical line we
    // paint.  Note that we may well not paint this part of the logical
    // line, as it may be broken into many physical lines, with the first
    // few physical lines scrolled past.  Note also that this is NOT the
    // visible rect of this line number list; this line number list has
    // visible rect == [0,0, insets.left-1,visibleRect.height-1].
    // - offset (<=0) is the y-coordinate at which we begin painting when
    // we begin painting with the first logical line.  This can be
    // negative, signifying that we've scrolled past the actual topmost
    // part of this line.

    // The algorithm is as follows:
    // - Get the starting y-coordinate at which to paint.  This may be
    //   above the first visible y-coordinate as we're in line-wrapping
    //   mode, but we always paint entire logical lines.
    // - Paint that line's line number and highlight, if appropriate.
    //   Increment y to be just below the are we just painted (i.e., the
    //   beginning of the next logical line's view area).
    // - Get the ending visual position for that line.  We can now loop
    //   back, paint this line, and continue until our y-coordinate is
    //   past the last visible y-value.

    // We avoid using modelToView/viewToModel where possible, as these
    // methods trigger a parsing of the line into syntax tokens, which is
    // costly.  It's cheaper to just grab the child views' bounds.

    // Some variables we'll be using.
    RTextAreaUI ui = (RTextAreaUI) textArea.getUI();
    Rectangle visibleEditorRect = ui.getVisibleEditorRect();
    View v = ui.getRootView(textArea).getView(0);
    boolean currentLineHighlighted = textArea.
        isCurrentLineHighlightEnabled();
    int lineCount = root.getElementCount();
    int topPosition = textArea.viewToModel(
        new Point(visibleRect.x, visibleRect.y));
    int topLine = root.getElementIndex(topPosition);

    // Compute the y at which to begin painting text, taking into account
    // that 1 logical line => at least 1 physical line, so it may be that
    // y<0.  The computed y-value is the y-value of the top of the first
    // (possibly) partially-visible view.
    Rectangle r = LineNumberBorder.getChildViewBounds(v, topLine,
        visibleEditorRect);
    int offset = r.y - visibleRect.y;
    int y2 = y + offset; // The y-coordinate at which we're painting.

    FontMetrics metrics = g.getFontMetrics();
    int rhs = x + insets.left - RHS_BORDER_WIDTH;
    int visibleBottom = y2 + visibleRect.height;

    // Keep painting lines until our y-coordinate is passed the visible
    // end of the text area.
    g.setColor(getForeground());
    while (y2 < visibleBottom) {

      r = LineNumberBorder.getChildViewBounds(v, topLine,
                                              visibleEditorRect);
      int lineEndY = (r.y + r.height) - visibleRect.y;

      // Highlight the current line's line number, if desired.
      if (currentLineHighlighted && topLine == currentLine - 1) {
        g.setColor(textArea.getCurrentLineHighlightColor());
        // FIXME:  Why is the "+2" needed???
        g.fillRect(x, y2, insets.left, lineEndY - y2 + 2);
        g.setColor(getForeground());
      }

      // Paint the line number.
      String number = Integer.toString(topLine + 1);
      int width = (int) metrics.getStringBounds(number, g).getWidth();
      g.drawString(number, rhs - width, y2 + ascent);

      // The next possible y-coordinate is just after the last line
      // painted.
      y2 += r.height;

      // Update topLine (we're actually using it for our "current line"
      // variable now).
      topLine++;
      if (topLine >= lineCount) {
        break;
      }

    }

    // Paint the "border" line.  Remember that the line number list
    // doesn't scroll and always has visible rect ==
    // [0,0, insets.left-1,visibleRect.height-1].
    g.setColor(Color.BLACK);
    int x2 = x + insets.left - 4;
    g.drawLine(x2, y, x2, y + visibleRect.height - 1);

  }

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

  /**
   * Called whenever the text area fires a property change event.
   *
   * @param e The event.
   */
  public void propertyChange(PropertyChangeEvent e) {

    String name = e.getPropertyName();

    // If they changed the background color of the text area.
    if (name.equals("background")) {
      Color bg = textArea.getBackground();
      setBackground(bg == null ? Color.WHITE : bg);
      scrollPane.repaint();
    }

    // If they changed the background to an image.
    if (name.equals("background.image")) {
      setBackground(Color.WHITE);
      scrollPane.repaint();
    }

    // If they change the text area's font, we need to update cell heights
    // to match the font's height.
    else if (name.equals("font")) {
      updateCellHeights();
    }

    // If they change the current line highlight in any way...
    else if (name.equals(RTextArea.CURRENT_LINE_HIGHLIGHT_PROPERTY) ||
             name.equals(RTextArea.CURRENT_LINE_HIGHLIGHT_COLOR_PROPERTY)) {
      scrollPane.repaint();
    }

    // If they change the text area's syntax scheme (i.e., it is an
    // RSyntaxTextArea), update cell heights.
    else if (name.equals(RSyntaxTextArea.SYNTAX_SCHEME_PROPERTY)) {
      updateCellHeights();
    }

  }

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

  /**
   * Called whenever a character is removed (ie backspace, delete) in the
   * text document we're line-numbering.
   */
  public void removeUpdate(DocumentEvent e) {
    int newNumLines = textArea.getDocument().getDefaultRootElement().
        getElementCount();
    if (newNumLines < currentNumLines) { // Used to be <=
      // Adjust the amount of space the line numbers take up, if necessary.
      if (newNumLines / 10 < currentNumLines / 10) {
        updateCellWidths();
      }
      currentNumLines = newNumLines;
      // Need to repaint in case they removed a line by pressing
      // delete.
      scrollPane.repaint();
    }
  }

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

  /**
   * Sets the background color of the line number list.
   *
   * @param color The background color.
   * @see #getBackground
   */
  public void setBackground(Color background) {
    if (background != null && !background.equals(this.background)) {
      this.background = background;
      //repaint();
    }
  }

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

  /**
   * Sets the font used to render the line numbers.
   *
   * @param font The <code>java.awt.Font</code> to use to to render the line
   *             numbers.  If <code>null</code>, a 10-point monospaced font
   *             will be used.
   * @see #getFont
   */
  public void setFont(Font font) {
    if (font == null) {
      font = new Font("monospaced", Font.PLAIN, 10);
    }
    this.font = font;
    //repaint();
  }

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

  /**
   * Sets the foreground color of the line number list.
   *
   * @param color The foreground color.
   * @see #getForeground
   */
  public void setForeground(Color foreground) {
    if (foreground != null && !foreground.equals(this.foreground)) {
      this.foreground = foreground;
      //repaint();
    }
  }

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

  /**
   * Sets the color to use to paint line numbers.
   *
   * @param color The color to use when painting line numbers.
   * @see #getLineNumberColor
   */
  public void setLineNumberColor(Color color) {
    setForeground(color);
    //repaint();
  }

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

  /**
   * Messages from the viewport.
   *
   * @param change The change event.
   */
  public void stateChanged(ChangeEvent e) {
    scrollPane.repaint();
  }

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

  /**
   * Changes the height of the cells in the JList so that they are as tall as
   * the height of a line of text in the text area.  This should be called
   * whenever the user changes the font in an <code>RTextArea</code> or a
   * syntax style in an <code>RSyntaxTextArea</code>.
   */
  public void updateCellHeights() {
    cellHeight = textArea.getLineHeight();
    ascent = textArea.getMaxAscent();
  }

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

  /**
   * Changes the width of the cells in the JList so you can see every digit
   * of each.
   */
  public void updateCellWidths() {

    // Adjust the amount of space the line numbers take up, if necessary.
    Font font = getFont();
    if (font != null) {
      FontMetrics fontMetrics = textArea.getFontMetrics(font);
      int count = 0;
      int numLines = textArea.getDocument().getDefaultRootElement().
          getElementCount();
      while (numLines >= 10) {
        numLines = numLines / 10;
        count++;
      }
      insets.left = Math.max(fontMetrics.charWidth('9') * (count + 2) + 5,
                             MIN_CELL_WIDTH);
      //revalidate();
    }

  }

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

}

⌨️ 快捷键说明

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