Question

Je suis en utilisant quelques JFormattedTextFields dans mon programme. Pour une raison quelconque lorsque les gains de champ de texte focus après un clic sur le champ de texte, la position du curseur saute toujours à gauche (position 0). Je voudrais que le caret pour finir à l'endroit cliqué par l'utilisateur. Donc, si je clique entre deux chiffres, le caret devrait se retrouver entre ces deux chiffres.

Je mis en place un focusListener qui transmettrait l'emplacement de clic et régler la position de caret là.

FocusListener focusListener = new FocusListener(){


    public void focusGained(FocusEvent evt) {

        JFormettedTextField jftf = (JFormattedTextField) evt.getSource();

        //This is where the caret needs to be.
        int dot = jftf.getCaret().getDot(); 

        SwingUtilities.invokeLater( new Runnable() {

        public void run() {
'the textField that has focus'.setCaretPosition('Some how get the evt or dot');              
              }
           });
        }

    public void focusLost (FocusEvent evt) {}

    });

J'ai essayé un certain nombre de choses pour obtenir son à travailler. Je l'ai essayé d'utiliser le mot-clé final, qui fonctionne, mais seulement pour un seul champ de texte.

Je l'ai utilisé set / get méthodes à l'intérieur de l'auditeur de mise au point d'affecter l'objet courant, mais ne suis pas sûr de savoir comment faire cette « sécurité » (par exemple doivent-ils être synchronisés?).

Peut-être il y a quelque chose que je suis absent?

Était-ce utile?

La solution

Vous devez utiliser un MouseListener:

MouseListener ml = new MouseAdapter()
{
    public void mousePressed(final MouseEvent e)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                JTextField tf = (JTextField)e.getSource();
                int offset = tf.viewToModel(e.getPoint());
                tf.setCaretPosition(offset);
            }
        });
    }
};

formattedTextField.addMouseListener(ml);

Autres conseils

Cela se fait dans AbstractFormatter.install(JFormattedTextField), qui est appelée lorsque les gains se concentrent sur le terrain.

Je ne sais pas pourquoi il est conçu de cette façon, mais vous pouvez modifier ce comportement (à condition que votre formatter ne change pas la longueur de la chaîne dans le champ.)

Exemple (en supposant que la valeur de champ est un int):

class IntFormatter extends AbstractFormatter {
    @Override
    public void install(final JFormattedTextField ftf) {
        int prevLen = ftf.getDocument().getLength();
        int savedCaretPos = ftf.getCaretPosition();
        super.install(ftf);
        if (ftf.getDocument().getLength() == prevLen) {
            ftf.setCaretPosition(savedCaretPos);
        }
    }

    public Object stringToValue(String text) throws ParseException {
        return Integer.parseInt(text);
    }

    public String valueToString(Object value) throws ParseException {
        return Integer.toString(((Number) value).intValue());
    }
}

Notez que ce n'est pas le même que le défaut de formatter Integer. La mise en forme par défaut utilise un DecimalFormat qui sépare les groupes de chiffres, par exemple "1,000,000". Cela rend la tâche plus difficile car il modifie la longueur de la chaîne.

Amélioration de la solution de finnw un peu je pense. Exemple:

public static void main(String[] args) {
    NumberFormat format = NumberFormat.getInstance();
    NumberFormatter formatter = new NumberFormatter(format) {
        @Override
        public void install(JFormattedTextField pField) {
            final JFormattedTextField oldField = getFormattedTextField();
            final int oldLength = pField.getDocument().getLength();
            final int oldPosition = pField.getCaretPosition();

            super.install(pField);

            if (oldField == pField && oldLength == pField.getDocument().getLength()) {
                pField.setCaretPosition(oldPosition);
            }
        }
    };
    JFormattedTextField field = new JFormattedTextField(formatter);
    field.setValue(1234567890);

    JOptionPane.showMessageDialog(null, field);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top