📄 linenumberlist.java~2~
字号:
// the first line.
int actualTopY = -(visibleRect.y%cellHeight);
Insets textAreaInsets = textArea.getInsets();
if (textAreaInsets!=null) {
actualTopY += textAreaInsets.top;
}
int y = actualTopY + ascent;
// Highlight the current line's line number, if desired.
if (textArea.isCurrentLineHighlightEnabled() && currentLine>=topLine &&
currentLine<bottomLine) {
g.setColor(textArea.getCurrentLineHighlightColor());
g.fillRect(0,actualTopY+(currentLine-topLine)*cellHeight, cellWidth,cellHeight);
}
// Paint the "border" line.
g.setColor(Color.BLACK);
g.drawLine(cellWidth-4,0, cellWidth-4,visibleRect.height);
g.setColor(getForeground());
FontMetrics metrics = g.getFontMetrics();
int rhs = getBounds().width - RHS_BORDER_WIDTH;
for (int i=topLine; i<bottomLine; i++) {
String number = Integer.toString(i);
int width = getTextWidth(number, metrics);
g.drawString(number, rhs-width,y);
y += 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 visibleRect The visible rectangle of the text area.
*/
/*
* FIXME: This method isn't as efficient as the version in
* LineNumberBorder, as it uses modelToView() a lot. Fix it to be like
* LineNumberBorder's version if you ever use this again.
*/
public void paintWrappedLineNumbers(Graphics g, Element root,
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, cellWidth-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.
int lineCount = root.getElementCount();
int topPosition = textArea.viewToModel(new Point(visibleRect.x,visibleRect.y));
int topLine = root.getElementIndex(topPosition);
Element line = root.getElement(topLine);
int topLineStartOffset = line.getStartOffset();
int topLineEndOffset = line.getEndOffset();
// Compute the y at which to begin painting text, taking into account scrolling.
Rectangle actualTop = null;
try {
actualTop = textArea.modelToView(topLineStartOffset); // Could be (0,-5), for example.
} catch (Exception e) {
e.printStackTrace();
return;
}
int offset = actualTop.y - visibleRect.y; // How much "higher" we are than the actual viewport (negative value).
int y = offset; // The y-coordinate at which we're painting.
g.setColor(getForeground());
FontMetrics metrics = g.getFontMetrics();
int rhs = getBounds().width - RHS_BORDER_WIDTH;
int visibleBottom = visibleRect.height;
// Keep painting lines until our y-coordinate is passed the visible end of
// the text area.
while (y < visibleBottom) {
// Compute the next y-value at which to paint a line number.
// This is also needed to know how much to highlight when
// highlighting the current line number.
Rectangle lineEndViewPos = null;
try {
lineEndViewPos = textArea.modelToView(topLineEndOffset - 1);
lineEndViewPos.y -= visibleRect.y; // Take into account we always start at y==0.
} catch (BadLocationException ble) {
ble.printStackTrace();
break;
}
// Highlight the current line's line number, if desired.
if (textArea.isCurrentLineHighlightEnabled() &&
topLine==currentLine-1) {
g.setColor(textArea.getCurrentLineHighlightColor());
g.fillRect(0,y, cellWidth,lineEndViewPos.y+lineEndViewPos.height-y);
g.setColor(getForeground());
}
// Paint the line number.
String number = Integer.toString(topLine+1);
int width = getTextWidth(number, metrics);
g.drawString(number, rhs-width,y+ascent);
// The next possible y-coordinate is just after the last line
// painted.
y = lineEndViewPos.y + lineEndViewPos.height;
// Update topLine (we're actually using it for our "current line" variable now).
topLine++;
if (topLine>=lineCount)
break;
topLineEndOffset = root.getElement(topLine).getEndOffset();
}
// Paint the "border" line. Remember that the line number list doesn't
// scroll and always has visible rect ==
// [0,0, cellWidth-1,visibleRect.height-1].
g.setColor(Color.BLACK);
int x = cellWidth - 4;
g.drawLine(x,0, x,visibleRect.height-1);
}
/*****************************************************************************/
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);
repaint();
}
// If they changed the background to an image.
if (name.equals("background.image")) {
setBackground(Color.WHITE);
repaint();
}
// They toggled lineWrap in the text area.
else if (name.equals("lineWrap")) {
lastY = -1; // Just to force a repaint if lineWrap is being enabled.
setSize(getWidth(), textArea.getHeight());
}
// 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)) {
repaint();
}
}
/*****************************************************************************/
/**
* 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;
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);
super.setFont(font);
}
/*****************************************************************************/
/**
* 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();
}
/*****************************************************************************/
/**
* Changes the height of the cells in the JList so that they are as tall as
* font. This function should be called whenever the user changes the Font
* of <code>textArea</code>.
*/
public void updateCellHeights() {
//FontMetrics fontMetrics = textArea.getFontMetrics(textArea.getFont());
cellHeight = textArea.getLineHeight();//fontMetrics.getHeight();
ascent = textArea.getMaxAscent();//fontMetrics.getAscent();
repaint();
}
/*****************************************************************************/
/**
* 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 = getFontMetrics(font);
int count = 0;
int numLines = textArea.getDocument().getDefaultRootElement().getElementCount();
while (numLines >= 10) {
numLines = numLines/10;
count++;
}
cellWidth = Math.max(fontMetrics.charWidth('9') * (count+2) + 5, MIN_CELL_WIDTH);
revalidate();
}
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -