1. 程式人生 > >【Java】Swing中JTextPane中如何繪制行號

【Java】Swing中JTextPane中如何繪制行號

代碼 name panel 9.png 自己 顯示行號 led att gin

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中如何繪制行號