JTextField: Get previous caret position when mouse is pressed

48 Views Asked by At

I add a MouseListener to my JTextField in which I need to know the caret position before the mouse was pressed. My listener gets invoked when the caret position has already changed. Apparently it's not possibile to set some priority to the listener so that it gets invoked before the caret is changed.
Adding a CaretListener does not help since that one is invoked only when the mouse is released.

Running the code below you can easily verify my problem when pressing and releasing the mouse within the text field.

Any suggestions?

package test;

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

@SuppressWarnings("serial")
public class TestCaret extends JFrame
{
  public TestCaret()
  {
    JTextField   text;
    TestListener listener;
    text = new JTextField("This is my text");
    listener = new TestListener();
    text.addMouseListener(listener);
    text.addCaretListener(listener);
    add(text);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  private class TestListener extends MouseAdapter implements CaretListener
  {
    @Override
    public void caretUpdate(CaretEvent e)
    {
      System.out.println("Got CaretEvent " + e);
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
      JTextField textField;
      textField = (JTextField)e.getComponent();
      System.out.println("Got MouseEvent with caret position " + textField.getCaretPosition());
    }

  }

  public static void main(String[] args)
  {
    Runnable runner;
    runner = new Runnable()
    {
      @Override
      public void run()
      {
        TestCaret frame;
        frame = new TestCaret();
        frame.pack();
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);

  }

} // class TestCaret
1

There are 1 best solutions below

0
Grinding For Reputation On

I simplified your code by

  1. Using Lambdas
  2. Removing the unnecessary code
  3. Removing the MouseListener
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Main extends JFrame {
    
    int previousPos;
    int currentPos;

    public Main() {
        JTextField text = new JTextField("This is my text");
        text.addCaretListener(e -> {
            
            previousPos = currentPos;
            currentPos = e.getDot();
            
            System.out.println("Previous Position: " + previousPos + ", Current Position:" + currentPos);
            
        });
        
        add(text);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Main().setVisible(true));
    }

}

I handle the caret event by setting the previousPos to the currentPos (Remember, I haven't updated the currentPos yet). Next I set the value of currentPos to the caret position which I retrieve from e.getDot(). This is a very simple fix and should solve your issue.