How to position the cursor at the beginning of the field?

2

How can I make a component ( JTextField , JFormattedTextField and others) when clicked / gain focus, position the cursor in the 0 position of the component, especially when the component is already filled and the user clicks on it again? I'm trying to use setCaretPosition(0);

What I've tried:

package geral;

import java.awt.Dimension;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

public class SetaPosicao extends JFrame implements FocusListener {

    private final JTextField campo = new JTextField();
    private final JFormattedTextField campo2 = new JFormattedTextField();

    public static void main(String[] args) {
        SetaPosicao tela = new SetaPosicao();
        tela.setVisible(true);
    }

    public SetaPosicao() {
        add(colocaCampo());
        setSize(500, 150);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        try {
            MaskFormatter mf = new MaskFormatter("#####-###");
            mf.install(campo2);
        } catch (Exception e) {

        }
    }

    private JComponent colocaCampo() {
        JPanel painel = new JPanel();
        JLabel label = new JLabel("TextField");
        JLabel label2 = new JLabel("Formatted");

        painel.add(label);
        painel.add(campo);
        campo.setPreferredSize(new Dimension(120, 22));
        //campo.setCaretPosition(0);

        painel.add(label2);
        painel.add(campo2);
        campo2.setPreferredSize(new Dimension(80, 22));
        //campo2.setCaretPosition(0);
        return painel;
    }

    @Override
    public void focusGained(FocusEvent e) {
        campo.setCaretPosition(0);
        campo2.setCaretPosition(0);
    }

    @Override
    public void focusLost(FocusEvent e) {
    }
}
    
asked by anonymous 16.06.2017 / 17:00

2 answers

2

I think the problem occurs because you're trying to change the position when the container field gets focused, then when the text component gains focus with a click, the mouse will be positioned where it was clicked .

One way to resolve this is to apply the focus event to the two text fields separately, and for this you can create a class that extends from FocusAdapter and apply to both fields:

class CaretPosition extends FocusAdapter{

    @Override
    public void focusGained(FocusEvent e) {

        JTextComponent comp = (JTextComponent) e.getSource();           
        comp.setCaretPosition(0);
    }       
} 

Then just apply this class to the fields:

campo.addFocusListener(new CaretPosition());
campo2.addFocusListener(new CaretPosition());

Another problem I found in your code is that you set the preferred size of the fields after adding them. I recommend that you define features of all fields before adding them to containers.

The code with all the modifications looks like this:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;
import javax.swing.text.MaskFormatter;

public class SetaPosicao extends JFrame {

    private final JTextField campo = new JTextField();
    private final JFormattedTextField campo2 = new JFormattedTextField();

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            SetaPosicao tela = new SetaPosicao();
            tela.setVisible(true);
        });

    }

    public SetaPosicao() {
        add(colocaCampo());
        setSize(500, 150);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        try {
            MaskFormatter mf = new MaskFormatter("#####-###");
            mf.install(campo2);
        } catch (Exception e) {

        }
    }

    private JComponent colocaCampo() {

        JPanel painel = new JPanel();
        JLabel label = new JLabel("TextField");
        JLabel label2 = new JLabel("Formatted");

        campo.setPreferredSize(new Dimension(120, 22));

        campo.addFocusListener(new CaretPosition());
        campo2.addFocusListener(new CaretPosition());
        campo2.setPreferredSize(new Dimension(80, 22));

        painel.add(label);
        painel.add(campo);

        painel.add(label2);     
        painel.add(campo2);

        return painel;
    }

    class CaretPosition extends FocusAdapter{

        @Override
        public void focusGained(FocusEvent e) {

            JTextComponent comp = (JTextComponent) e.getSource();           
            comp.setCaretPosition(0);
        }       
    } 
}

It's never too late to also tell you which swing applications should always be started within the Thread specify for it, EDT

    
16.06.2017 / 17:17
-3

What I think I'm looking for is in the event of Click something like

controlo.requestFocus()
The setCaretPosition control should automatically focus on index 0, but only after requestFocus () / p>     
16.06.2017 / 17:09