Oracle在JTextPane类中并没有直接提供显示行号的方法,所以这个功能应该由程序员自己来完成,笔者发现网上很多的显示行号的代码都存在一个问题,就是不准确,特别是在行数变多了以后。

笔者先贴出代码:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets; import javax.swing.ImageIcon;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.Position;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument; public class EditPanel extends JTextPane {
/**
* 是否实现行号,默认不显示
*/
private boolean showLineNumber = false;
private int fontSize = 16;//默认为16号字体 public EditPanel() {
super();
}
public void setShowLineNumber(boolean isShow) {
this.showLineNumber = isShow;
}
public boolean getShowLineNumber() {
return this.showLineNumber;
}
@Override
public void paint(Graphics g) {
super.paint(g);
StyleConstants.setFontSize(getInputAttributes(), getFontSize());
if (getShowLineNumber()) {
drawLineNumber(g);
}
}
protected void drawLineNumber(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(int fontSize) {
if(fontSize!=12 &&
fontSize!=14 &&
fontSize!=16 &&
fontSize!=18 &&
fontSize!=20 &&
fontSize!=22 &&
fontSize!=24 ){
throw new RuntimeException("该行号不能识别");
}
this.fontSize = fontSize;
}
public int getFontSize() {
return fontSize;
}
/**
* 获得行号中y坐标的位置<br/>
* 在计算的过程中,有一个比率值,该比率值是根据getY()的返回值之差决定的。
* @param row 第几行
* @return 该行的y坐标位置
*/
private int getPositionY(int row) {
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;
}
return y;
}
}

EditPanel.java

测试为:

    public static void main(String[] args) {
JFrame jf=new JFrame("行号测试");
EditPanel panel=new EditPanel();
panel.setShowLineNumber(true);//显示行号 jf.add(new JScrollPane(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,是为了把行号往上提一点,显得好看。

其他的值以此类推。

【Java】Swing中JTextPane中如何绘制行号的更多相关文章

  1. Sqlite中使用rowid来表示行号,用于分页。

    在SQLite的查询结果中显示行号,可以使用select rowid as RowNumber ,* from WSCLanguage: select rowid as RowNumber ,* fr ...

  2. Java Swing:JPanel中添加JPanel

    1. JPanel默认布局是FlowLayout,如果不设置父JPanel的布局,则子JPanel自动填满父JPanel. JPanel jpanel = new JPanel(); jpanel.s ...

  3. EXTJS中的grid显示实际行号

    添加一个新的功能 Ext.grid.PageRowNumberer = Ext.extend(Ext.grid.RowNumberer, { width : 40, renderer:function ...

  4. Xtrareport绘制行号

    需要是用事件beforePrint (在打印数据之前的事件) private void xrTableCell12_BeforePrint(object sender, System.Drawing. ...

  5. JTextpane 加入的行号

    最近项目需求,在需求JTextPane加入行号等信息,网上找了半天才发现JTextArea加入行号信息.copy正在研究在线程序.他发现自己能够做出改变来改变JTextPane显示行号. 代码: pa ...

  6. VIM 中鼠标选择不选中行号

    VIM 中鼠标选择不选中行号 在Vim中,我们一般会使用 :set nu 打开行号开关. 但是打开行号后,有个弊端,那就是在用鼠标进行选择的时候,会将前面的行号也一起进行拷贝了.但是在gVim中进行选 ...

  7. C# DataGridView显示行号的三种方法

    方法一: 网上最常见的做法是用DataGridView的RowPostPaint事件在RowHeaderCell中绘制行号: private void dgGrid_RowPostPaint( obj ...

  8. DataGridView显示行号的几种方法来自http://www.soaspx.com/dotnet/csharp/csharp_20100204_2740.html

    方法一: 网上最常见的做法是用DataGridView的RowPostPaint事件在RowHeaderCell中绘制行号: private void dataGridView1_RowPostPai ...

  9. 【转】DataGridView显示行号

    ref:http://blog.csdn.net/xieyufei/article/details/9769631 方法一: 网上最常见的做法是用DataGridView的RowPostPaint事件 ...

随机推荐

  1. system函数的应用一例

    system函数的应用一例

  2. Mongoose Connection best practice

    There is often quite a lot of confusion about how best to set up a database connection with Mongoose ...

  3. wget获取整站

    wget -m -e robots=off https://www.baidu.com -m是克隆整个网站,-e robots=off是让wget忽视robots.txt 如果网站有中文路径,最好用以 ...

  4. Refuses to install for WTP10

    Refuses to install for WTP10   description http://imgur.com/a/QN4iM I am a WTP10 user. I’m running b ...

  5. ASP入门(九)-Request对象小案例

    我们将制作一个能够记住访问者姓名的页面,在这个小案例中,你将学会如何使用Request对象的Cookies.Form以及ServerVariables集合的值,还可以学习到如何使用Response对象 ...

  6. IE6.0 PNG背景透明图片插件

    <!--[if lte IE 6]><script src="http://xian.qq.com/js/2013js/2013index/DD_belatedPNG_0. ...

  7. CSS 之 伪类及伪元素

    伪类和伪元素用起来非常的方便,在查阅资料及测试后整理下来. 一.伪类 CSS 伪类用于向某些选择器添加特殊的效果.伪类对元素进行分类是基于特征(characteristics)而不是它们的名字.属性或 ...

  8. 低危漏洞- X-Frame-Options Header未配置

    原文链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/X-Frame-Options?redirectlocale=en-US&redi ...

  9. 简单的tcp聊天

    package com.pers.tcptest; import java.io.IOException; import java.io.InputStream; import java.io.Out ...

  10. 请指出document load和document ready的区别?

    共同点:这两种事件都代表的是页面文档加载时触发. 异同点: ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件). onload 事件的触发,表示页面包含图片等文件在内的所有 ...