下面类的实现是在网上找的,目前实现的原理看不太懂,先用起来。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
/**
*
* XX
*/
public class JLineNumTextPane extends javax.swing.JComponent {
/**
* JAVA TextArea行数显示插件
*/
private static final long serialVersionUID = 1L;
public final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 11);
public final Color DEFAULT_BACKGROUD = new Color(228, 228, 228);
public final Color DEFAULT_FOREGROUD = Color.BLACK;
public final int nHEIGHT = Integer.MAX_VALUE - 1000000;
public final int MARGIN = 5;
private int lineHeight;
private int fontLineHeight;
private int currentRowWidth;
private FontMetrics fontMetrics;
public JLineNumTextPane() {
setFont(DEFAULT_FONT);
setForeground(DEFAULT_FOREGROUD);
setBackground(DEFAULT_BACKGROUD);
setPreferredSize(9999);
}
public void setPreferredSize(int row) {
int width = fontMetrics.stringWidth(String.valueOf(row));
if (currentRowWidth < width) {
currentRowWidth = width;
setPreferredSize(new Dimension(2 * MARGIN + width + 1, nHEIGHT));
}
}
@Override
public void setFont(Font font) {
super.setFont(font);
fontMetrics = getFontMetrics(getFont());
fontLineHeight = fontMetrics.getHeight();
}
public int getLineHeight() {
if (lineHeight == 0) {
return fontLineHeight;
}
return lineHeight;
}
public void setLineHeight(int lineHeight) {
if (lineHeight > 0) {
this.lineHeight = lineHeight;
}
}
public int getStartOffset() {
return 4;
}
@Override
protected void paintComponent(Graphics g) {
int nlineHeight = getLineHeight();
int startOffset = getStartOffset();
Rectangle drawHere = g.getClipBounds();
g.setColor(getBackground());
g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
g.setColor(getForeground());
int startLineNum = (drawHere.y / nlineHeight) + 1;
int endLineNum = startLineNum + (drawHere.height / nlineHeight);
int start = (drawHere.y / nlineHeight) * nlineHeight + nlineHeight - startOffset;
for (int i = startLineNum; i <= endLineNum; ++i) {
String lineNum = String.valueOf(i);
int width = fontMetrics.stringWidth(lineNum);
g.drawString(lineNum + " ", MARGIN + currentRowWidth - width - 1, start);
start += nlineHeight;
}
setPreferredSize(endLineNum);
}
}
使用: 编辑器空间(JTextArea、JTextPane等)放在JScrollPane内,给JScrollPane设置JViewport,JViewpo放入JLineNumTextPane。
jViewport2 = new JViewport();
jLineNumTextPane1 = new JLineNumTextPane();
jViewport2.add(jLineNumTextPane1);
jScrollPane1.setRowHeader(jViewport2);
最后,为了内容和行号对齐,设置内间距和字体:
jTextPane1.setFont(jLineNumTextPane1.DEFAULT_FONT);
jTextPane1.setMargin(new Insets( 0,jLineNumTextPane1.MARGIN,0,jLineNumTextPane1.MARGIN));