What is the best way to position the caret at the end of a JTextField on focus?

caret, focus, java, jtextfield, swing

Solution

Neither the actual behaviour nor the requirement are fully described:

when a JTextField gains focus the caret is positioned at the beginning of the text

that's not entirely true: when it gains focus by

- clicking, the caret is placed at the mouse location

- other means (tabbing, programmatic) it is placed at the position it had at the time focus was lost.

Consequently, the requirement:

the better behavior is to position it at the end, or to select all the text

needs a bit of thought for those cases to not detoriate usability, at least for the first users might be confused if a mouse gesture would be overruled. The second is arguable and probably OS/LAF dependent. Personally, I wouldn't touch the caret if its position is not at the start.

Technically, a solution to globally trigger changes of component state on focus changes is to register a PropertyChangeListener with the KeyboardFocusManager:

PropertyChangeListener pl = new PropertyChangeListener() {

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (!(evt.getNewValue() instanceof JTextField)) return;
        JTextField field = (JTextField) evt.getNewValue();
        // crude check to not overdo it
        int dot = field.getCaretPosition();
        if (dot == 0) {
            field.selectAll();
        }
    }
};
KeyboardFocusManager.getCurrentKeyboardFocusManager()
    .addPropertyChangeListener("permanentFocusOwner", pl);

Problem

By default, when a JTextField gains focus the caret is positioned at the beginning of the text. However, I think the better behavior is to position it at the end, or to select all the text, e.g. http://jsfiddle.net/Marcel/jvJzX/. What is a nice way to do this? Ideally, the solution would be applied globally to all JTextFields in the application. Example of the default behavior (hit tab to focus the field): ``` public static void main(String[] args) { JTextField field = new JTextField("hello world!"); JOptionPane.showMessageDialog(null, field); } ``` Edit: To clarify, it would be nice if I didn't have to search through my app and change all the text fields.

Original source