Reputation: 563
the normal behaviour of native text fields in many environments is as follows:
Textfield with text "abcdefg". I use the mouse to select "efg" from left to right. The caret is now behind "g". When I move the caret to the left by pressing the cursor left key once, the selection is removed and the caret is right before "e". When I do the same in a JTextField or JTextArea (tested on Mac OS) doing the exact same thing results in the caret being right before "g".
I know how I could change that programmatically by using a KeyListener and registering it with each component but I am looking for a way to change that for my entire application. Is that possible? Is there a Flag, I am not finding or do I have to hack my look and feel?
Thanks
Upvotes: 3
Views: 327
Reputation: 324128
I am looking for a way to change that for my entire application
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class CaretAction extends TextAction
{
private boolean caretForward;
public CaretAction(boolean caretForward)
{
super(caretForward ? "Caret Forward" : "Caret Backward");
this.caretForward = caretForward;
}
public void actionPerformed(ActionEvent e)
{
JTextComponent textComponent = getFocusedComponent();
int start = textComponent.getSelectionStart();
int end = textComponent.getSelectionEnd();
int offset = textComponent.getCaretPosition();
if (start != end)
{
if (caretForward)
offset = (offset == end) ? offset + 1 : end;
else
offset = (offset == start) ? offset -1 : start;
}
else
{
offset += (caretForward) ? 1 : -1;
}
offset = Math.max(offset, 0);
offset = Math.min(offset, textComponent.getDocument().getLength());
textComponent.setCaretPosition( offset );
}
private static void createAndShowUI()
{
JTextField textField1 = new JTextField(10);
JTextField textField2 = new JTextField(10);
JPanel panel = new JPanel();
panel.add( textField1 );
panel.add( textField2 );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
ActionMap map = (ActionMap)UIManager.get("TextField.actionMap");
map.put(DefaultEditorKit.backwardAction, new CaretAction(false));
map.put(DefaultEditorKit.forwardAction, new CaretAction(true));
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You would also need to change the ActionMap for JTextArea, JFormattedTextField ...
Upvotes: 2
Reputation: 3566
What you can do is addCaretListener
:
anyField.addCaretListener(new CaretListener() {
public void caretUpdate(CaretEvent evt) {
anyFieldCaretUpdate(evt);
}
});
And set the Caret at the last again:
private void anyFieldCaretUpdate(CaretEvent evt) {
anyField.setCaretPosition(anyField.getText().length());
}
Upvotes: 1