33 votes

Comment sélectionner tout le texte d'un JFormattedTextField lorsqu'il obtient le focus?

J'ai une petite Java application de bureau qui utilise Swing. Il y a une entrée de données boîte de dialogue avec un champ de saisie de différents types (component swing jtextfield, JComboBox, JSpinner, JFormattedTextField). Quand j'active le JFormattedTextFields soit en surbrillance par le biais du formulaire ou en cliquant avec la souris, je l'aime pour sélectionner tout le texte qu'elle contient. De cette façon, les utilisateurs peuvent commencer à taper et écraser les valeurs par défaut.

Comment puis-je le faire? J'ai eu un FocusListener/FocusAdapter que les appels selectAll() sur le JFormattedTextField, mais il ne sélectionnez rien, bien que le FocusAdapter de focusGained() la méthode est appelée (voir l'exemple de code ci-dessous).

private javax.swing.JFormattedTextField pricePerLiter;
// ...
pricePerLiter.setFormatterFactory(
    new JFormattedTextField.AbstractFormatterFactory() {
    private NumberFormatter formatter = null;
    public JFormattedTextField.AbstractFormatter 
        getFormatter(JFormattedTextField jft) {
        if (formatter == null) {
            formatter = new NumberFormatter(new DecimalFormat("#0.000"));
            formatter.setValueClass(Double.class);
        }
        return formatter;
    }
});
// ...
pricePerLiter.addFocusListener(new java.awt.event.FocusAdapter() {
    public void focusGained(java.awt.event.FocusEvent evt) {
        pricePerLiter.selectAll();
    }
});

Des idées? Le plus drôle, c'est que la sélection de l'ensemble de son texte, en apparence, est le comportement par défaut pour les deux component swing jtextfield et JSpinner, au moins lors de la tabulation par le biais du formulaire.

67voto

eugener Points 10531

Emballez votre appel avec SwingUtilities.invokeLater afin qu'il se produise une fois que tous les événements AWT en attente ont été traités:

 pricePerLiter.addFocusListener(new java.awt.event.FocusAdapter() {
    public void focusGained(java.awt.event.FocusEvent evt) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                pricePerLiter.selectAll();
            }
        });
    }
});
 

14voto

camickr Points 137095

En plus de ce qui précède, si vous voulez ceci pour tous les champs de texte, vous pouvez simplement faire:

 KeyboardFocusManager.getCurrentKeyboardFocusManager()
    .addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener()
{
    public void propertyChange(final PropertyChangeEvent e)
    {
    	if (e.getNewValue() instanceof JTextField)
    	{
    		SwingUtilities.invokeLater(new Runnable()
    		{
    			public void run()
    			{
    				JTextField textField = (JTextField)e.getNewValue();
    				textField.selectAll();
    			}
    		});

    	}
    }
});
 

7voto

Adrien Clerc Points 571

Je sais que c'est un peu vieux, mais je suis venu avec une solution plus propre, sans invokeLater:

 private class SelectAllOfFocus extends FocusAdapter {

    @Override
    public void focusGained(FocusEvent e) {
        if (! e.isTemporary()) {
            JFormattedTextField textField; // Get your text field here, it depends on your own code
            // This is needed to put the text field in edited mode, so that its processFocusEvent doesn't
            // do anything. Otherwise, it calls setValue, and the selection is lost.
            textField.setText(textField.getText());
            textField.selectAll();
        }
    }

}
 

6voto

pavan Points 122

C’est parce que JFormattedTextfield substitue processFocusEvent pour formater le focus obtenu / perdu.

Un moyen sûr consiste à étendre JFormattedTextField et à remplacer la méthode processFocusEvent:

 new JFormattedTextField("...") {  
	    protected void processFocusEvent(FocusEvent e) {  
			super.processFocusEvent(e);  
			if (e.isTemporary())  
				return;  
			SwingUtilities.invokeLater(new Runnable() {  
				@Override  
				public void run() {  
					selectAll();  
				}   
			});  
		}  
	};
 

L'utilisation d'un focusListener peut ne pas toujours fonctionner ... dans la mesure où cela dépend du moment où il est appelé par rapport à processFocusEvent.

2voto

user231765 Points 21

Le code de camickr peut être légèrement amélioré. Lorsque le focus passe d'un JTextField à un autre type de composant (tel qu'un bouton), la dernière sélection automatique n'est pas effacée. Il peut être corrigé de cette façon:

     KeyboardFocusManager.getCurrentKeyboardFocusManager()
        .addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener()
    {
        @Override
        public void propertyChange(final PropertyChangeEvent e)
        {

            if (e.getOldValue() instanceof JTextField)
            {
                    SwingUtilities.invokeLater(new Runnable()
                    {
                            @Override
                            public void run()
                            {
                                    JTextField oldTextField = (JTextField)e.getOldValue();
                                    oldTextField.setSelectionStart(0);
                                    oldTextField.setSelectionEnd(0);
                            }
                    });

            }

            if (e.getNewValue() instanceof JTextField)
            {
                    SwingUtilities.invokeLater(new Runnable()
                    {
                            @Override
                            public void run()
                            {
                                    JTextField textField = (JTextField)e.getNewValue();
                                    textField.selectAll();
                            }
                    });

            }
        }
    });
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X