7
votes

Jformattedtextfield Caret Position au focus

J'utilise quelques jormattedtextFields dans mon programme. Pour une raison quelconque lorsque le champ de texte gagne de la mise au point après un clic sur le champ de texte, la position du caret saute toujours à gauche (position 0). J'aimerais que le caret se retrouve à l'emplacement cliqué par l'utilisateur. Donc, si je clique entre deux chiffres, le caret doit se retrouver entre ces deux chiffres.

J'ai donc mis en place un focallistener qui obtiendrait l'emplacement du clic et définir la position de Caret. P>

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) {}

    });


0 commentaires

4 Réponses :


12
votes

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);


7 commentaires

Bonne réponse! Mais pourquoi avez-vous besoin de le faire dans invoqater ()? Mousousilleuse n'est-elle pas invoquée de l'événement-thread de toute façon?


@Sanoj, le délai introduit par invoqater est nécessaire pour qu'il fonctionne. Normalement, lorsque le champ est cliqué, il gagne la mise au point, ce qui entraîne le format de la valeur et met à jour le texte du champ. Un effet secondaire est que le caret est déplacé. Avec invoqater , cette méthode exécutée () n'exécute pas tant que la gestion de l'événement de mise au point n'est terminée, alors vous savez qu'une fois que vous avez mis le caret au bon endroit, il y restera .


Cette solution ne fonctionne pas si le jformattedtextfield est utilisé dans un TapeCeleritor mais les solutions de FINNW font.


@Jonas en fait, il le fait (en supposant que votre commentaire est lié à votre question récente Stackoverflow.com/questions/8598504/... ) - Vous avez Soit être recouverte d'une convertie (sur les coordonnées du champ de texte) MouseEveillant ou effectuez manuellement le réglage de la // fait une partie de ma réponse :-)


@ keopatra: il ne fonctionne pas sans votre "hack" tandis que la solution de Finnw fonctionne bien sans modifications .


@Jonas hmm ... que voulez-vous dire par "hack"? BTW, oui, j'aime aussi l'approche de la formatrice :-) Bien que cela puisse avoir besoin d'un peu plus de vernis pour être plus généralement USEABL.


Cette solution introduit un autre petit problème. Il enfreint la manipulation de sélection d'un champ de texte. Double-cliquez sur Sélectionner un mot et triple Cliquez sur le texte entier. Avec cette solution d'événement de souris, les sélections ne fonctionnent pas.



7
votes

Ceci arrive réellement dans abstractformatter.install (jformattedtextfield) , appelé lorsque le champ gagne la mise au point.

Je ne sais pas pourquoi il est conçu de cette façon, mais vous pouvez remplacer cela Comportement (tant que votre formateur ne change pas la longueur de la chaîne dans le champ.)

exemple (en supposant que la valeur de champ est un int ): < Pré> xxx

Notez que ce n'est pas le même que le formateur integer par défaut. La formatrice par défaut utilise un décimalformat qui sépare des groupes de chiffres, par ex. "1 000 000" . Cela rend la tâche plus difficile car elle modifie la longueur de la chaîne.


0 commentaires

1
votes

améliore un peu la solution de Finnw. Exemple: xxx


0 commentaires

0
votes

Si vous ne pouvez pas ou ne voulez pas remplacer le formateur:

    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import java.text.NumberFormat;
    
    import javax.swing.JFormattedTextField;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;
    import javax.swing.text.NumberFormatter;
    
    public class TestJFormattedTextFieldFocus {
    
        public static void main(String[] args) {
            NumberFormat format = NumberFormat.getInstance();
            NumberFormatter formatter = new NumberFormatter(format);
            JFormattedTextField field = new JFormattedTextField(formatter);
            field.addFocusListener(new FocusListener() {
    
                @Override
                public void focusLost(FocusEvent e) {
                }
    
                @Override
                public void focusGained(FocusEvent e) {
                    restoreCaretPosition();
                }
    
                private void restoreCaretPosition() {
                    int caretPosition = field.getCaretPosition();
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            field.setCaretPosition(caretPosition);
                        }
                    });
                }
            });
            field.setValue(1234567890);
            JOptionPane.showMessageDialog(null, field);
        }
    
    }


0 commentaires