JTextArea 中显示行号

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JTextArea 中显示行号相关的知识,希望对你有一定的参考价值。

如题,我要写个编译器,用swing做,希望能够在JTextArea中输入,能像在eclipse一样自动显示行号,查了很多资料也没有办法,希望高手指教一下,最好能够有简单的代码

//package tryLineNumber;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
//import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

/**
* A class illustrating running line number count on JTextPane. Nothing
is painted on the pane itself,
* but a separate JPanel handles painting the line numbers.<br>
*
* @author Daniel Sj?blom<br>
* Created on Mar 3, 2004<br>
* Copyright (c) 2004<br>
* @version 1.0<br>
*/
public class LineNr extends JPanel

// for this simple experiment, we keep the pane + scrollpane as members.
//JTextPane pane;
JTextArea pane;
JScrollPane scrollPane;

public LineNr()

super();
setMinimumSize(new Dimension(30, 30));
setPreferredSize(new Dimension(30, 30));
setMinimumSize(new Dimension(30, 30));
//pane = new JTextPane() // we need to override paint so that the linenumbers stay in sync
pane = new JTextArea()

public void paint(Graphics g)

super.paint(g);
LineNr.this.repaint();

;
scrollPane = new JScrollPane(pane);


public void paint(Graphics g)

super.paint(g);

// We need to properly convert the points to match the viewport
// Read docs for viewport
int start =pane.viewToModel(scrollPane.getViewport().getViewPosition()); // starting pos in document
int end =
pane.viewToModel(
new Point(
scrollPane.getViewport().getViewPosition().x + pane.getWidth(),
scrollPane.getViewport().getViewPosition().y + pane.getHeight()));
// end pos in doc

// translate offsets to lines
Document doc = pane.getDocument();
int startline = doc.getDefaultRootElement().getElementIndex(start) + 1;
int endline = doc.getDefaultRootElement().getElementIndex(end) + 1;

int fontHeight = g.getFontMetrics(pane.getFont()).getHeight();
int fontDesc = g.getFontMetrics(pane.getFont()).getDescent();
int starting_y = -1;

try

starting_y = pane.modelToView(start).y -
scrollPane.getViewport().getViewPosition().y + fontHeight - fontDesc;

catch (BadLocationException e1)

e1.printStackTrace();


for (int line = startline, y = starting_y; line <= endline; y += fontHeight, line++)

g.drawString(Integer.toString(line), 0, y);




// test main
public static void main(String[] args)

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
final LineNr nr = new LineNr();
frame.getContentPane().add(nr, BorderLayout.WEST);
frame.getContentPane().add(nr.scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setSize(new Dimension(400, 400));
frame.setVisible(true);




JTextArea本身应该不支持的,可以自己显示在JPanel上面
参考技术A 我看过一个c++显示行好的代码。
它是用记录做的,就是输入时记录输入了多少字,然后每行有多少字,从而得到当前位置是第几行。
你试试看。

Java:光标当前位置的列号和行号

【中文标题】Java:光标当前位置的列号和行号【英文标题】:Java: column number and line number of cursor's current position 【发布时间】:2011-07-05 15:06:22 【问题描述】:

我想知道JTextArea中光标所在的列号和行号。 IE。在记事本中,当我在第一行时,状态栏显示 Ln 1, Col 1。

提前谢谢...

【问题讨论】:

【参考方案1】:

Here 是代码

import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.*;

public class caretDemo extends JFrame 
    // Two controls, one is the editor and the other is our little status bar at the bottom.
    // When we update the editor, the change in caret will update the status text field.
    private JTextArea editor;
    private JTextField status;

    // Start of our caretDemo class
    public caretDemo() 
        setTitle("Caret Demo");
        setSize(500,500);

        // Lets create a border layout to make positioning of items easy and quick.
        setLayout(new BorderLayout());
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        editor = new JTextArea();

        // Add a caretListener to the editor. This is an anonymous class because it is inline and has no specific name.
        editor.addCaretListener(new CaretListener() 
            // Each time the caret is moved, it will trigger the listener and its method caretUpdate.
            // It will then pass the event to the update method including the source of the event (which is our textarea control)
            public void caretUpdate(CaretEvent e) 
                JTextArea editArea = (JTextArea)e.getSource();

                // Lets start with some default values for the line and column.
                int linenum = 1;
                int columnnum = 1;

                // We create a try catch to catch any exceptions. We will simply ignore such an error for our demonstration.
                try 
                    // First we find the position of the caret. This is the number of where the caret is in relation to the start of the JTextArea
                    // in the upper left corner. We use this position to find offset values (eg what line we are on for the given position as well as
                    // what position that line starts on.
                    int caretpos = editArea.getCaretPosition();
                    linenum = editArea.getLineOfOffset(caretpos);

                    // We subtract the offset of where our line starts from the overall caret position.
                    // So lets say that we are on line 5 and that line starts at caret position 100, if our caret position is currently 106
                    // we know that we must be on column 6 of line 5.
                    columnnum = caretpos - editArea.getLineStartOffset(linenum);

                    // We have to add one here because line numbers start at 0 for getLineOfOffset and we want it to start at 1 for display.
                    linenum += 1;
                
                catch(Exception ex)  

                // Once we know the position of the line and the column, pass it to a helper function for updating the status bar.
                updateStatus(linenum, columnnum);
            
        );

        // Add the fields to the layout, the editor in the middle and the status at the bottom.
        add(editor, BorderLayout.CENTER);

        status = new JTextField();
        add(status, BorderLayout.SOUTH);

        // Give the status update value
        updateStatus(1,1);
    

    // This helper function updates the status bar with the line number and column number.
    private void updateStatus(int linenumber, int columnnumber) 
        status.setText("Line: " + linenumber + " Column: " + columnnumber);
    

    // Entry point to the program. It kicks off by creating an instance of our class and making it visible.
    public static void main(String args[]) 
        caretDemo caretDemoApp = new caretDemo();
        caretDemoApp.setVisible(true);
    


输出

【讨论】:

【参考方案2】:

您需要使用Utilities.getRowStart 以及插入符号位置,如下所示:

获取行号:

int caretPos = textArea.getCaretPosition();
int rowNum = (caretPos == 0) ? 1 : 0;
for (int offset = caretPos; offset > 0;) 
    offset = Utilities.getRowStart(textArea, offset) - 1;
    rowNum++;

System.out.println("Row: " + rowNum);    

获取列号:

int offset = Utilities.getRowStart(textArea, caretPos);
int colNum = caretPos - offset + 1;
System.out.println("Col: " + colNum);

【讨论】:

【参考方案3】:

你试过getCaretPosition吗?

您必须计算\n 才能知道您有哪一行,并且您必须计算当前插入符号位置与上次出现\n 字符之间的差异。

【讨论】:

以上是关于JTextArea 中显示行号的主要内容,如果未能解决你的问题,请参考以下文章

linuxvim显示行号,linux vim设置行号

Linux小技巧:如何在 Vim 中显示行号?

如何让VIM显示行号

loadrunner 如何在回放是显示行号

linux 查看文件显示行号

linux中 vi / vim显示行号或取消行号命令