Click here to Skip to main content
15,886,026 members
Articles / Desktop Programming / Swing
Tip/Trick

Using getMagicCaretPosition Without Getting Null Value

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
15 Mar 2014CPOL3 min read 10.8K   22   1   3
How to use getMagicCaretPosition without getting null value

Introduction

Sometimes, we need to find the exact location of the cursor (caret) in a text field or another similar control. Java provides us a set of methods to calculate it but, let’s be honest, who wants to waste a few minutes that can become days in calculating the caret position?

Back in time, about four or five days ago, I lost part of my hair and patience looking for a way to get the caret position in a JTextArea. One way was to do it with the Windows API but it’ll finish in a Windows dependent program. Another way was to calculate the current column from the offset of the current cursor position. It works but not fully, at least not for my purposes. Looking in books, internet and asking my teachers at school how to determine the caret position, I got no answers. Finally, I found the way to do it: Use the method getMagicCaretPosition() to get a Point structure with the actual position of the caret in the control.

Quick Start

As Oracle says in its Wiki, getMagicCaretPosition() gets the current caret visual location. The caret changes its position every time we write or delete a character in the control. My first error was to say ”It shouldn’t be a problem, I just need to acquire the caret position when the text changes (in the method changeUpdate(KeyEvent evt) included in DocumentListener interface at javax.swing.event)”. Why? Because when we write or delete a character in the control, the caret moves until the character is written or deleted. So, getting the caret position must be in the keyReleased event to avoid getting a null when calling the getMagicCaretPosition().

Using the Code

To see a little example, let’s make a Java project in NetBeans (7.4), add a new JFrame to the package and a JTextArea to the window. Then, implement the DocumentListener and KeyListener interfaces in the JFrame.

Java
public class getMagicCaretPositionGUI extends JFrame implements DocumentListener, KeyListener{...}

Of course, we must override the methods included in the implemented interfaces and subscribe the JTextArea to the listeners.

Java
public getMagicCaretPositionGUI() {
     initComponents();
     this.jTextArea1.addKeyListener(this);
     this.jTextArea1.getDocument().addDocumentListener(this);
}

@Override
public void insertUpdate(DocumentEvent e) {
     changedUpdate(e); 
}

@Override
public void removeUpdate(DocumentEvent e) {
     changedUpdate(e);
}
@Override
public void changedUpdate(DocumentEvent e) { }

@Override
public void keyTyped(KeyEvent e) { }

@Override
public void keyPressed(KeyEvent e) { }

@Override
public void keyReleased(KeyEvent e) { }

Focus on the changedUpdate(DocumentEvent e) method, let’s see what happens when we try to get the current position at this method.

Java
@Override 
public void changedUpdate(DocumentEvent e) { 
     Point p = this.jTextArea1.getCaret().getMagicCaretPosition();
     setTitle("Actual caret position : X: " + p. x + " , Y: " + p. y);
}

If we execute the project now, every time the text on the JTextArea changes will throw an exception like Exception in thread ”AWT- EventQueue-0” java.lang.NullPointerException.... Remember, when the document changes, the caret ”disappears” until the character is written or deleted.

Image 1

It must be really hard to get it at the first time (as I, expend 3 days of my life getting this). Comment the code in insertUpdate and removeUpdate; and move the code in changedUpdate to KeyReleased and try it again.

Java
@Override
public void keyReleased(KeyEvent e) {
    Point p = this.jTextArea1.getCaret().getMagicCaretPosition();
    this.setTitle("Actual caret position: X:" + p.x + ", Y: " + p.y);
}
Image 2

Now it works pretty good. Beautiful, isn’t it?

Points of Interest

Getting the caret position in the changedUpdate method is valid but you must set the caret position to 0,0 getting first the caret of the control in the constructor and setting the position with the method setMagicCaretPosition(Point p) like this:

Java
this.jTextArea1.getCaret().setMagicCaretPosition(new Point(0, 0)); 

I discovered it 10 minutes before uploading.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Mexico Mexico
Great things come from rare ideas. Wink | ;)

Comments and Discussions

 
SuggestionI found a simpler and reliable alternative Pin
Member 161338617-Nov-23 1:15
Member 161338617-Nov-23 1:15 
QuestiongetMagicCaretPosition in java Pin
Member 112883234-Dec-14 23:03
Member 112883234-Dec-14 23:03 
AnswerRe: getMagicCaretPosition in java Pin
Alain Peralta5-Dec-14 11:40
Alain Peralta5-Dec-14 11:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.