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

📄 linenumberlist.java~2~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~2~
📖 第 1 页 / 共 2 页
字号:
/*
 * 11/14/2003
 *
 * LineNumberList.java - Line numbers for a text area contained
 *                        in an RTextScrollPane.
 */
package org.fife.ui.rtextarea;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;


/**
 * Used by <code>RTextScrollPane</code> to display line numbers for a text
 * area.  This component is capable of displaying line numbers for any
 * <code>RTextArea</code>, with line wrap enabled or disabled.  You can also
 * choose the line number font, color, and choose whether or not to "highlight"
 * the current line number.<p>
 *
 * NOTE:  To speed things up a little, this component does not "scroll."  It
 * needs to be added to an <code>RTextScrollPane</code> inside a special
 * viewport, like so:<p>
 *
 * <pre>
 *	JViewport viewport = new JViewport() {
 *			public void setViewPosition(java.awt.Point p) {
 *				Component c = getView();
 *				if (c!=null)
 *					c.repaint();
 *			}
 *		};
 *	viewport.setView(lineNumberList);
 *	setRowHeader(viewport);
 * </pre>
 *
 * This needs to be done because this component figures out how to paint itself
 * from the current scroll-state of the text area, so there is no need to scroll
 * this guy himself.<p>
 *
 * This class is probably going to be replaced by
 * {@link org.fife.ui.LineNumberBorder}, as not only does that class not need
 * to be scrolled, but he is also not a <code>JComponent</code> (less memory)
 * and he doesn't require the additional overhead of a <code>JViewport</code>
 * (slower).
 *
 * @author Robert Futrell
 * @version 0.5
 */
class LineNumberList extends JComponent implements CaretListener,
							DocumentListener, PropertyChangeListener {

	/**
	 *
	 */
	private static final long serialVersionUID = -7969233269296717504L;

	private static final int MIN_CELL_WIDTH		= 24;
	private static final int RHS_BORDER_WIDTH	= 8;

	private RTextArea textArea;				// The text component for which we're displaying the line numbers.

	private int currentLine;					// The last line the caret was on.
	private int lastY = -1;					// Used to check if caret is on a new line when line wrap is enabled.

	private int cellHeight;					// The height of a "cell" for a line number when word wrap is off.
	private int cellWidth;					// The width used for all line number cells.
	private int ascent;						// The ascent to use when painting line numbers.

	private int currentNumLines;


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


	/**
	 * Constructs a new <code>LineNumberList</code> using default values for
	 * line number color (gray) and highlighting the current line.
	 *
	 * @param textArea The text component for which line numbers will be
	 *                 displayed.
	 */
	public LineNumberList(RTextArea textArea) {
		this(textArea, new Color(128,128,128));
	}


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


	/**
	 * Constructs a new <code>LineNumberList</code>.
	 *
	 * @param textArea The text component for which line numbers will be
	 *                 displayed.
	 * @param numberColor The color to use for the line numbers.
	 */
	public LineNumberList(RTextArea textArea, Color numberColor) {

		// Remember what text component we're keeping line numbers for.
		this.textArea = textArea;

		if (numberColor!=null)
			setForeground(numberColor);
		else
			setForeground(new Color(128,128,128));
		Color bg = textArea.getBackground();
		setBackground(bg==null ? Color.WHITE : bg);

		textArea.addCaretListener(this);
		textArea.addPropertyChangeListener(this);
		textArea.getDocument().addDocumentListener(this);

		// Initialize currentLine; otherwise, the current line won't start
		// off as highlighted.
		currentLine = 1;

		// Have the line number space be just enough space for '1' through '9'.
		updateCellHeights();
		updateCellWidths();

	}


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


	/**
	 * Called whenever the caret changes position; highlight the correct line
	 * number.
	 */
	public void caretUpdate(CaretEvent e) {

		int caretPosition = textArea.getCaretPosition();

		// We separate the line wrap/no line wrap cases because word wrap can
		// make a single line from the model (document) be on multiple lines
		// on the screen (in the view); thus, we have to enhance the logic for
		// that case a bit - we check the actual y-coordinate of the caret
		// when line wrap is enabled.  For the no-line-wrap case, getting the
		// line number of the caret suffices.  This increases efficiency in
		// the no-line-wrap case.

		if (textArea.getLineWrap()==false) {
			int line = textArea.getDocument().getDefaultRootElement().
									getElementIndex(caretPosition) + 1;
			if (currentLine!=line) {
				currentLine = line;
				repaint();
			}
		}
		else { // lineWrap is enabled; must check actual y-coord. of caret.
			try {
				int y = textArea.modelToView(caretPosition).y;
				if (y!=lastY) {
					lastY = y;
					currentLine = textArea.getDocument().
									getDefaultRootElement().
									getElementIndex(caretPosition) + 1;
					repaint();
				}
			} catch (BadLocationException ble) {
				ble.printStackTrace();
			}
		}

	}


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


	public void changedUpdate(DocumentEvent e) {}


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


	/**
	 * Returns the color to use to paint line numbers.
	 *
	 * @return The color used when painting line numbers.
	 * @see #setLineNumberColor
	 */
	public Color getLineNumberColor() {
		return getForeground();
	}


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


	public Dimension getPreferredSize() {
		return new Dimension(cellWidth, textArea.getHeight());
	}


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


	/**
	 * Returns the length of a string if it is drawn with the specified
	 * graphics context.  This method assumes that there are NO tabs in
	 * the string.<br><br>
	 *
	 * NOTE:  This is basically ripped off from
	 * <code>javax.swing.text.Utilities</code>, but slightly optimized for our
	 * situation.
	 *
	 * @param text The text to be painted.
	 * @param metrics The metrics with which to do the calculating.
	 * @return The width of the string when painted.
	 */
	public static final int getTextWidth(String text, FontMetrics metrics) {
		int width = 0;
		int end = text.length();
		for (int i=0; i<end; i++)
			width += metrics.charWidth(text.charAt(i));
		return width;
	}


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


	/**
	 * Called whenever a character is input (key is typed) in the text document
	 * we're line-numbering.
	 */
	public void insertUpdate(DocumentEvent e) {

		int newNumLines = textArea.getDocument().getDefaultRootElement().
												getElementCount();
		if (newNumLines > currentNumLines) {
			// Adjust the amount of space the line numbers take up,
			// if necessary.
			if (newNumLines/10 > currentNumLines/10)
				updateCellWidths();
			currentNumLines = newNumLines;
		}

	}


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


	// Returns the Component used as the JList cell.
	public void paint(Graphics g) {

		Element root = textArea.getDocument().getDefaultRootElement();
		Rectangle visibleRect = textArea.getVisibleRect();

		if (visibleRect==null)
			return;

		// Fill in the background the same color as the text component.
		g.setColor(getBackground());
		g.fillRect(0,0, cellWidth,visibleRect.height);

		if (textArea.getLineWrap()==true) {
			paintWrappedLineNumbers(g, root, visibleRect);
			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

⌨️ 快捷键说明

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