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

📄 textarea.java

📁 ErGo是一个很早的Java通用围棋服务器(IGS/NNGS)客户端程序。有全部源码和文档
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      int widthsofar = 0;
      short prevwhite = 0;
      char[] text = e.getChars();
      short i = 0;
      short rightmost = 0;
      while (i < text.length) {
	char c = text[i];
	int charwidth = (int) c < 256 ? widths[(int) c] : m.charWidth(0x4E00);
	widthsofar += charwidth;
	if (i - prevwhite > 0) { // don't ever wrap line before 1st char
	  boolean iswhite = Character.isWhitespace(c);
	  if (widthsofar >= insideWidth) {
	    if (prevwhite != 0 && !iswhite) {
	      v.addElement(new Short(prevwhite));
	      // start computing next line at prevwhite.
	      i = prevwhite;
	    }
	    else {
	      v.addElement(new Short(i));
	      rightmost = i;
	    }
	    maxLineWidth = Math.max(maxLineWidth, widthsofar - charwidth);
	    widthsofar = 0;
	  }
	  if (iswhite)
	    prevwhite = i;
	}
	++i;
      }
      lines = new short[v.size()];
      for (int j = 0; j < lines.length; j++)
	lines[j] = ((Short) v.elementAt(j)).shortValue();
      e.setLines(lines);
      // Add 1 to historyLines for each *extra* line displayed.
      // Remember that lines doesn't contain an entry for the 1st line.
      historyLines += lines.length;
    }
    return lines;
  }

  // Get the number of lines in the given HistoryElement.
  private int numLines (HistoryElement e, FontMetrics m) {
    if (wrap) {
      short[] lines = computeLines(e, m);
      return lines.length + 1;
    }
    else
      return 1;			// no line wrap.  1 line/element
  }


  private void invalidateHistory () {
    history.invalidate();
    maxLineWidth = 0;
    // historyLines gets reset to this approximation and gets incrementally
    // updated to be more accurate.
    historyLines = history.size();
  }

  public void scrollTo (int linenum) {
    int linemax = wrap ? (historyLines - 1) : (history.size() - 1);

    linenum = Math.max(0, Math.min(linenum, linemax));
/***
 +++ Don't second guess the caller.  Need to fix TextArea for this.
    if (linenum < getRows() - 1 && linemax >= getRows() - 1)
      linenum = getRows() - 1;
 ***/
    if (wrap) {
      // In the normal case (?) the user will be scrolling by a page
      // or less, so scanning from bottomLine to linenum shouldn't be
      // expensive.  +++ An optimization would be to check whether 
      // linenum is closer to 0 or linemax than it is to bottomLine
      // and if so, scan from there instead.
      int[] vals = findLineRelative(hbot, lbot, linenum - bottomLine);
      hbot = vals[0];
      lbot = vals[1];
      bottomLine = vals[2];
    }
    else {
      bottomLine = linenum;
      hbot = linenum;
      lbot = 0;
    }
    redisplay();
  }

  // Go backward one page in the history.  Find the line that is
  // rows-1 lines before hbot/lbot and put it at hbot/lbot.
  public void pageUp () {
    moveViewportUp(rows - 1);
  }

  // Go forward one page in the history.
  public void pageDown () {
    moveViewportDown(rows - 1);
  }

  // Find the line nlines distant from startIndex/startLine.
  // nlines may be positive or negative (or zero).
  private int[] findLineRelative (int startIndex, int startLine, int nlines) {
    //Debug.println("findLineRelative: " + startIndex + "," + startLine
    //	  + "," + bottomLine + ", delta=" + nlines);
    int[] result = new int[3];  // multiple value kludge
    int requested = nlines;
    if (!wrap) {
      result[0] = Math.min(Math.max(0, startIndex + nlines),
			   history.size() - 1);
      result[1] = 0;
      result[2] = result[0];
    }
    else { // wrapping
      HistoryElement elem = history.elementAt(startIndex);
      FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(offg.getFont());
      int hsize = history.size();
      //if (startLine >= numLines(elem, metrics))
      //Debug.println("findLineRelative called with invalid arg: startLine");
      if (nlines > 0) {
        while (nlines > 0) {
          --nlines;
	  ++startLine;
          if (startLine >= numLines(elem, metrics)) {
            startLine = 0;
	    ++startIndex;
            if (startIndex >= hsize) {
	      startIndex = hsize - 1;
	      startLine = numLines(elem, metrics) - 1;
	      ++nlines;  // undo the previous decrement; it was too much.
              break;
	    }
          }
	  elem = history.elementAt(startIndex);
        }
      }
      else {                    // nlines <= 0
        while (nlines < 0) {
	  ++nlines;
	  --startLine;
          if (startLine < 0) {
	    --startIndex;
            if (startIndex < 0) {
	      startIndex = 0;
	      startLine = 0;
	      --nlines;  // undo the previous increment; it was too much.
              break;
	    }
	    elem = history.elementAt(startIndex);
	    startLine = numLines(elem, metrics) - 1;
	  }
	}
      }
      result[0] = startIndex;	// new hbot
      result[1] = startLine;	// new lbot
      result[2] = bottomLine + (requested - nlines); // new bottomLine value
    }
    //Debug.println("findLineRelative found "
    //	  + result[0] + "," + result[1] + "," + result[2]);
    return result;
  }

  /*
   * Scrolling
   *
   * Note: In Java terminology scrolling UP means moving the viewport
   * onto the window history UP, which moves the window history DOWN.
   * I just mention this because I've always thought of it the other
   * way around...
   */

  // Move forward in the output history.
  // +++ Should use copyArea when nlines is small, rather than
  //     just calling redisplay()?
  public void moveViewportDown (int nlines) {
    if (history.size() > 0) {
      //Debug.println("moveViewportDown(" + nlines + ") from " + hbot + "," + lbot);
      int[] pos = findLineRelative(hbot, lbot, nlines);
      hbot = pos[0];
      lbot = pos[1];
      bottomLine = pos[2];
      redisplay();
    }
  }

  // Move backward in the output history.
  public void moveViewportUp (int nlines) {
    if (bottomLine - nlines < rows - 1)
      moveViewportToBeginning();
    else
      moveViewportDown(-nlines);
  }

  public void moveViewportToBeginning () {
    hbot = lbot = bottomLine = 0;
    scrollTo(rows - 1);
  }

  public void moveViewportToEnd () {
    hbot = history.size() - 1;
    HistoryElement elem = history.elementAt(hbot);
    lbot = numLines(elem, Toolkit.getDefaultToolkit().getFontMetrics(getFont())) - 1;
    bottomLine = historyLines;
    redisplay();
  }

  // atBottom is true if the viewport fully contains the last line in the
  // history.  In other words, if the user has not scrolled backward at
  // all.  This controls whether scrolling is done automatically when
  // appendLine() is called.
  private boolean atBottom () {
    int last = history.endIndex();
    if (last == -1 || !isInitialized())
      return true;
    else {
      //Debug.println("atBottom: " + hbot + "," + lbot + "," + last + ","
      // + (numLines(history.elementAt(last), null) - 1));
      return (last == hbot &&
	      (lbot + 1) == numLines(history.elementAt(last), null));
    }
  }

  // Kludge to deal with tabs.  Assumes tab stops every 8 chars.
  private String expandTabs (String s) {
    int i = s.indexOf('\t');
    if (i == -1)
      return s;  // no tabs, just return it
    else {
      int len = s.length();
      StringBuffer b = new StringBuffer(len + 20);  // 20 reasonable?
      for (int j = 0; j < len; j++) {
	char c = s.charAt(j);
	if (c == '\t') {
	  int nspaces = 8 - (b.length() % 8);
	  for (int k = 0; k < nspaces; k++)
	    b.append(' ');
	}
	else
	  b.append(c);
      }
      return b.toString();
    }
  }

  // Append a string (that contains no Newline chars) to the end of
  // the TextCanvas.  The string may be displayed on > 1 physical line.
  public void appendLine (String str, boolean repaint, Color color) {
    synchronized (this) {
      str = expandTabs(str);
      HistoryElement elem = new HistoryElement(str, color);
      // If offg is null the canvas hasn't been made visible yet.  When
      // it does become visible we want it to be at the end of the history
      // so set hbot.
      if (offg == null) {
	hbot = history.addElement(elem);
      }
      // If not at the bottom of the history, then the user has scrolled
      // back.  Just tack the new element onto the end, without setting hbot.
      else if (!atBottom()) {
	history.addElement(elem);
      }
      else {
	hbot = history.addElement(elem);
	int nlines = numLines(elem, Toolkit.getDefaultToolkit()
			            .getFontMetrics(offg.getFont()));
	bottomLine += nlines;
	lbot = wrap ? (nlines - 1) : 0;
      }
      historyLines += 1; // if it wraps, computeLines will add more to this.
      if (repaint)
	repaint();
    }  // synchronized
  }

  /**
   * Appends the given text to the end of the current text.  If the 
   * viewport is currently at the end of the TextCanvas the viewport
   * is moved down and the new text displayed at the end.  Otherwise
   * the new text is added to the end without changing to contents
   * of the viewport.
   *
   * @param text the text to insert
   */
  public void appendText (String text) {
    appendText(text, Color.black);
  }

  public void appendText (String text, Color color) {
    int saved = 0;
    int length = text.length();
    for (int i = saved; i <= length; i++) {
      if (i >= length)
        appendLine(text.substring(saved), true, color);
      else if (text.charAt(i) == '\n') {
        appendLine(text.substring(saved, i), true, color);
        if (i + 1 >= length)
          break;
        saved = i + 1;  // skip the Newline char.
      }
    }
    // repaint not needed since passed true to appendLine()
    //repaint();
  }

  /**
   * Inserts the specified text at the specified position.
   * @param str the text to insert.
   * @param pos the position at which to insert.
   */
  public void insertText (String str, int pos) {
    // ---*** Fill this in.
  }

  /**
   * Replaces text from the indicated start to end position with the
   * new text specified.
   *
   * @param str the text to use as the replacement.
   * @param start the start position.
   * @param end the end position.
   */
  public void replaceText (String str, int start, int end) {
    // ---*** Fill this in.
  }

  public void clearCanvas (Graphics g) {
    g.setColor(getBackground());
    g.fillRect(0, 0, width, height);

⌨️ 快捷键说明

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