[Swing] [JOptionPane] - problème de focus

Résolu
urikane Messages postés 16 Date d'inscription lundi 15 décembre 2003 Statut Membre Dernière intervention 24 août 2004 - 3 août 2004 à 10:46
urikane Messages postés 16 Date d'inscription lundi 15 décembre 2003 Statut Membre Dernière intervention 24 août 2004 - 3 août 2004 à 15:45
Bonjour à tous, mon problème est le suivant:

L'application que je dois faire comporte une fenêtre principale (IHM) dérivée de JFrame qui possède une barre de menu depuis laquelle une fenêtre de réglages peut être appelée. (IHM_Decompte)
Cette fenêtre contient des JTextField. Seulement, je voudrais que lorsque l'utilisateur "sort" d'un des ces champs de saisie pour cliquer sur un bouton (par ex...) ou faire je ne sais quelle autre chose, un message d'avertissement apparaisse et que le champ de saisie en question garde le focus. (sauf si l'utilisateur clique sur le bouton Annuler ou sur la croix de fermeture de la fenêtre)

Voici un extrait du code de IHM_Decompte:

public void focusLost(FocusEvent fe)
{
Object source= fe.getSource();
if(source==tDuree){
if(tDuree.getText().equals("")){
if(!fe.getOppositeComponent().equals(bAnnule)){
JOptionPane.showMessageDialog(this, "champ vide!","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
System.out.println("zone de saisie vide");
tDuree.requestFocus();
}
}
}
if(source==tHeure){
if(tHeure.getText().equals("")){
if(!fe.getOppositeComponent().equals(bAnnule)){
JOptionPane.showMessageDialog(this, "zone de saisie vide!","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
System.out.println("Zone de saisie vide");
tHeure.requestFocus();
}
}
}
}
(tDuree et tHeure étant les deux JTextField)

Seulement voila, au lieu de m'afficher la boîte de dialogue puis de remettre le focus sur le champ de texte concerné, la boîte de dialogue s'ouvre une 1ere fois, je clique sur Ok, puis elle se s'ouvre une 2eme fois, je clique sur Ok et là je retourne enfin dans ma fenêtre IHM_Decompte avec le focus qui est bien dans le champ de texte.
A noter que la 2eme fois, j'ai tout un tas d'exceptions

Je ne comprend pas pourquoi ça me fais cà. Et surtout pourquoi deux fois :question)
J'ai essayé de changer le this par null ou bien par une référence à IHM => aucune amélioration
Une seule chose marche (et encore...): une fois IHM_Decompte ouverte, je vide le champ de texte puis je clique en dehors des fenêtres de mon application (par exemple sur le bureau ou dans une fenêtre....)
Ensuite lorsque je reviens à IHM_Decompte, je donne le focus au champ de texte, et après avoir fais ça, si je sort du champ alors qu'il est vide, ça marche comme je veux.
Mais bon, ce n'est pas une solution acceptable.
D'après se que j'ai pu chercher sur le net, se serait peut-être un problème de java qui gère mal le focus avec les fênetres modales.
Mais ça ne me dis pas comment solutionner mon problème :sad)
Si quelqu'un a une idée... merci
A voir également:

4 réponses

urikane Messages postés 16 Date d'inscription lundi 15 décembre 2003 Statut Membre Dernière intervention 24 août 2004
3 août 2004 à 15:45
Je rectifie: InputVerifier est pas mal mais elle bloque seulement les évènements clavier (tels que Tab,....) et pas les évènements souris

J'ai trouvé la solution:
http://www.javaworld.com/javaworld/jw-06-2001/jw-0622-traps_p.html
Il faut créer une classe interne implémentant Runnable, ceci afin de pourvoir invoquer la méthode SwingUtilities.invokeLater() qui prend en paramètres un Runnable.
Ca marche pour mon application.

++
3
urikane Messages postés 16 Date d'inscription lundi 15 décembre 2003 Statut Membre Dernière intervention 24 août 2004
3 août 2004 à 10:53
hummm euh dsl pour le code qui n'était pas très lisible
public void focusLost(FocusEvent fe)
{
        Object source=fe.getSource();
        if(source==tDuree){
                if(tDuree.getText().equals("")){
                        if(!fe.getOppositeComponent().equals(bAnnule)){
                                JOptionPane.showMessageDialog(this, "champ vide!","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
                                System.out.println("Zone de saisie vide");
                                tDuree.requestFocus();
                        }
                }
        }
        if(source==tHeure){
                if(tHeure.getText().equals("")){
                        if(!fe.getOppositeComponent().equals(bAnnule)){
                                JOptionPane.showMessageDialog(this, "champ vide!","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
                                System.out.println("Zone de saisie vide");
                                tHeure.requestFocus();
                        }
                }
        }
}


ps: on peut pas éditer ses messages?
0
nataS22 Messages postés 66 Date d'inscription jeudi 24 juin 2004 Statut Membre Dernière intervention 28 février 2005
3 août 2004 à 11:08
Si ta JOptionPane s'ouvre deux fois avant de te perdre c que tu doit surement activer ton focusListenner deux fois sur les champs en question. Mais là on ne peut pas te dir comment tu fait puisque tu n'as passé que le code du listenner.

A mon avis tu devrais faire un System.out.rpintln ( " activation du listenner " ) ;

à côté de celui ci et tu verrais tout de suite si c à cause de ça.

Au lieu de faire un request Focus tu devrai faire un GrabFocus. C ce que j'utilise et je n'ai pas eu de problème avec.

Essaye déjà c deux possibilité et on verra après.

@++
0
urikane Messages postés 16 Date d'inscription lundi 15 décembre 2003 Statut Membre Dernière intervention 24 août 2004
3 août 2004 à 12:45
(dans le constructeur)
....
brDuree.addActionListener(this);
brHeure.addActionListener(this);
tDuree.addActionListener(this);
tDuree.addFocusListener(this);
tHeure.addActionListener(this);
tHeure.addFocusListener(this);
bOk.addActionListener(this);
bAnnule.addActionListener(this);
addWindowListener(new ecouteurFenetre());
....


public void actionPerformed(ActionEvent ae)
{
Object source=ae.getSource();
if(source==tDuree){ // validation du champ de texte (ie appuie sur 'Entrer')
bOk.requestFocus();
}

if(source==tHeure){
bOk.requestFocus();
}

if(source==brDuree){
tDuree.setEnabled(true);
tHeure.setEnabled(false);
}

if(source==brHeure){
tDuree.setEnabled(false);
tHeure.setEnabled(true);
}

if(source==bOk){ //sauvegarder les infos des champs de texte
boolean v1,v2;
int sav1=0;
String sav2="";
if(ihm.getEspion().isOccupe()){
JOptionPane.showMessageDialog(null, "En cours de recherche... patientez svp","AVERTISSEMENT",JOptionPane.INFORMATION_MESSAGE);
}
else{
if(brDuree.isSelected()){ //c'est le décompte qui est sélectionné
ihm.getOnglet().first(ihm.getAltern());
ihm.setType(1);
v1=verification(tDuree.getText(),1);
if(v1){
sav1=Integer.parseInt(tDuree.getText());
Configuration maj=new Configuration();
maj.setInfo("duree",String.valueOf(sav1));
maj.setInfo("type","1");
ihm.setDuree(sav1);
ihm.getLabelMinute().setText(String.valueOf(sav1));
ihm.getLabelSeconde().setText("00");
ihm.getEspion().interrupt();
ihm.setEspion(null);
ihm.setEspion(new Espion(sav1,ihm));
ihm.getEspion().start();
ihm.ihm_decp_ouv=false;
dispose();
}
else{
JOptionPane.showMessageDialog(null, "Durée invalide","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
}
}
else{ //c'est la date qui est sélectionnée
ihm.getOnglet().last(ihm.getAltern());
ihm.setType(2);
v2=verification(tHeure.getText(),2);
if(v2){
sav2=tHeure.getText();
Configuration maj=new Configuration();
maj.setInfo("heure",sav2);
maj.setInfo("type","2");
ihm.setHeure(sav2);
ihm.getLabelHeure().setText(sav2);
ihm.getEspion().interrupt();
ihm.setEspion(null);
ihm.setEspion(new Espion(sav2,ihm));
ihm.getEspion().start();
ihm.ihm_decp_ouv=false;
dispose();
}
else{
JOptionPane.showMessageDialog(null, "Heure invalide","AVERTISSEMENT",JOptionPane.ERROR_MESSAGE);
}
}
}
}

C'est ça que tu voulais?
En tout cas, grabFocus() donne le même résultat

Sinon, en recherche des informations sur grabFocus() dans la documentation du jdk, j'ai trouvé une classe intéressante qui me permettrais peut-être de contourner mon problème: "InputVerifier"
Cette classe permet de ne sortir du JTextField seulement si une certaine chaîne de caractère a été tapé et de bloquer le focus.
En tout cas quand même bien savoir où étais mon problème :sad)

Merci quand même
0
Rejoignez-nous