Wie kann man die Zeile und Spalte der Cursorposition in einer JTextArea ermitteln?

Das Prinzip besteht darin, erst die Zeile festzustellen und dann die Länge des Strings zwischen Zeilenanfang und Cursorposition auszulesen.

Die Beispielklasse erweitert JFrame und definiert in initComponents() je eine JTextArea und ein JLabel zur Anzeige der Position. Zur Ermittlung der Cursorposition implementiert die Beispielklasse das Interface CaretListener und meldet die JTextArea bei diesem an. JTextArea stellt drei Methoden zum Auslesen des numerischen Offset der Cursorposition bereit:

getLineEndOffset(int line) Offset (Zeichenzahl) des Zeilenendes der gegebenen Zeile
getLineStartOffset(int line) Offset des Zeilenbeginns (Zeichenzahl bis zum Zeilenbeginn) der gegebenen Zeile
getLineOfOffset(int offset) Zeilennummer der Cursorposition

Geschickt eingesetzt können mit diesen Methoden Zeile und Spalte der Cursorposition ausgelesen werden. Der CaretListener sorgt mit seiner Methode caretUpdate(CaretEvent e) dafür, dass dies nach jeder Änderung der Cursorposition erfolgt.
Zuerst wird mittels getCaretPosition() der Offset der Cursorposition ausgelesen. Offset bezeichnet hier die Gesamtzahl der Zeichen, die sich in der Komponente vor dem Cursor befinden. Das Zählen beginnt also bei 0. Anschließend werden die Zeilennummer der aktuellen Cursorposition und dann der Offset des Zeilenbeginns ermittelt.

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;

public class CursorPosition extends JFrame implements CaretListener {
    
    private JTextArea area;
    private JLabel label;
    
    public CursorPosition(){
        initComponents();
        this.setSize(new Dimension(400,300));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    private void initComponents() {
        area = new JTextArea();
        area.addCaretListener(this);
        label = new JLabel();
        this.add(area, BorderLayout.CENTER);
        this.add(label, BorderLayout.NORTH);
    }

    public void caretUpdate(CaretEvent e) {
        int cPos = area.getCaretPosition();

        try {
            int lineNumber = area.getLineOfOffset(cPos); // beginnt bei 0
            int startOffset = area.getLineStartOffset(lineNumber);
            String str = area.getText(startOffset, (cPos - startOffset));
            int len = str.length();

            label.setText("Zeile: " + new Integer(lineNumber + 1).toString()
                    + " | Spalte: " + new Integer(len + 1).toString());
        } catch (BadLocationException e1) {
        }
    }

    public static void main(String[] args) {
        new CursorPosition();
    }
}

In der Folge stellt man die Länge des Textes zwischen Zeilenbeginn und Cursorposition fest. Diese ist identisch mit der Spaltenzahl der Cursorposition. Die Stringlänge ermittelt die Methode getText(int beginn, int ende). Bei der Ausgabe addiert man nach Belieben 1, um die jeweilige Position bei 1 beginnen zu lassen.