Oracle在JTextPane类中并没有直接提供显示行号的方法,所以这个功能应该由程序员自己来完成,笔者发现网上很多的显示行号的代码都存在一个问题,就是不准确,特别是在行数变多了以后。
笔者先贴出代码:
importjava.awt.Color;importjava.awt.Font;importjava.awt.Graphics;importjava.awt.Insets;importjavax.swing.ImageIcon;importjavax.swing.JTextPane;importjavax.swing.text.AttributeSet;importjavax.swing.text.Element;importjavax.swing.text.Position;importjavax.swing.text.StyleConstants;importjavax.swing.text.StyledDocument;public class EditPanel extendsJTextPane {/*** 是否实现行号,默认不显示*/
private boolean showLineNumber = false;private int fontSize = 16;//默认为16号字体
publicEditPanel() {super();
}public void setShowLineNumber(booleanisShow) {this.showLineNumber =isShow;
}public booleangetShowLineNumber() {return this.showLineNumber;
}
@Overridepublic voidpaint(Graphics g) {super.paint(g);
StyleConstants.setFontSize(getInputAttributes(), getFontSize());if(getShowLineNumber()) {
drawLineNumber(g);
}
}protected voiddrawLineNumber(Graphics g) {
setMargin(new Insets(0, 35, 0, 0));//绘制行号的背景色
g.setColor(new Color(180, 180, 180));
g.fillRect(0, 0, 30, getHeight());//获得有多少行
StyledDocument docu =getStyledDocument();
Element element=docu.getDefaultRootElement();int rows =element.getElementCount();//绘制行号的颜色//System.out.println("y:" + getY());
g.setColor(new Color(90, 90, 90));
g.setFont(new Font(getFont().getName(), getFont().getStyle(), 16));for (int row = 0; row < rows; row++) {
g.drawString((row+ 1)+"",2, getPositionY(row + 1));
}
}public void setFontSize(intfontSize) {if(fontSize!=12 &&fontSize!=14 &&fontSize!=16 &&fontSize!=18 &&fontSize!=20 &&fontSize!=22 &&fontSize!=24){throw new RuntimeException("该行号不能识别");
}this.fontSize =fontSize;
}public intgetFontSize() {returnfontSize;
}/*** 获得行号中y坐标的位置
* 在计算的过程中,有一个比率值,该比率值是根据getY()的返回值之差决定的。
*@paramrow 第几行
*@return该行的y坐标位置*/
private int getPositionY(introw) {int y = 0;switch(getFontSize()) {case 12:
y= (row * 18) - 4;break;case 14:
y= (row * 20) - 5;break;case 16:
y= (row * 23) - 6;break;case 18:
y= (row * 26) - 8;break;case 20:
y= (row * 29) - 10;break;case 22:
y= (row * 31) - 11;break;case 24:
y= (row * 34) - 12;break;
}returny;
}
}
EditPanel.java
测试为:
public static voidmain(String[] args) {
JFrame jf=new JFrame("行号测试");
EditPanel panel=newEditPanel();
panel.setShowLineNumber(true);//显示行号
jf.add(newJScrollPane(panel));
jf.setPreferredSize(new Dimension(600,400));
jf.pack();
jf.setVisible(true);
}
效果图:
一般在绘制行号的时候,都会牵扯到一个问题,就是如何定位Y的位置。笔者对这个问题的解决思路已经体现在上面的代码中了,下面再详细说一下。
首先贴出的EditPanel类中getPostionY()方法的部分代码:
switch(getFontSize()) {case 12:
y= (row * 18) - 4;break;
这里需要注意,这个18是由getY()获取得来的,在paint(Griphics g)中,打印getY()的值,然后得出变化的差值。经过笔者的测试发现,若字体设置为12号,那么getY()的变化差值就是18,那么每次行号Y的位置就是就是(第几行*18)的值,就可以让行号在每一行的前面了。然后再减4,是为了把行号往上提一点,显得好看。
其他的值以此类推。