IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Un "faux" while(){} ?


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2013
    Messages : 6
    Par défaut Un "faux" while(){} ?
    Salut à tous !
    Tout d'abord, enchanté petite présentation rapide :
    Bien que l'étudiant de plus ou moins près depuis deux ans, je ne me suis intéressé à la programmation que depuis quelques semaines et je dois dire que je me suis plutôt pris au jeu (fin de la présentation).

    Et, comme premier programme, j'ai décidé de coder... : un cluedo !
    Je sais, je suis suicidaire, mais c'est le premier jeu qui m'est passé par la tête.
    Bref, j'en ai pas mal bavé, mais au final je suis arrivé à quelque chose de sympathique, on peut s'amuser un peu avec la console (ça n'a rien d'un vrai cluedo, il n'y a même pas de plateau, mais bon c'est plutôt pas mal... enfin, pour mon niveau, loin de moi l'idée de vous offenser !)

    Puis je me suis lancé dans les IHM. Ouïe !
    Bref encore, après moult essais, j'ai monté deux petites fenêtres avec lesquelles j'essaie maintenant d'interagir, par exemple pour récupérer la valeur d'un JComboBox, et j'en passe.

    Mon souci : je récupère un int d'un JComboBox. Le truc c'est qu'en gros j'essaie de dire au programme : "tant que je n'ai pas choisi une valeur en particulier dans la comboBox, ne passe pas à la suite" (puisqu'évidemment si je ne le fais pas, cet int en question vaut 0, et les divisions par zéro, youpi ! )
    Du coup, voilà ce que j'ai essayé :


    while (cluedo.choisi==false){};


    Comme vous vous en doutez, ça ne marche pas.
    (NB : Bien sûr, ce booléen "choisi", que j'ai défini dans le constructeur de ma fenêtre, devient vrai lorsque je choisi une valeur du comboBox.)

    Par contre, quand je mets quelque chose du genre :


    while (cluedo.choisi==false){System.out.println("YOLO");};


    là ça marche !!!
    Sauf que bien sûr, le temps que je choisisse une valeur dans la fenêtre, vous imaginez le nombre de lignes qui sortent dans la console...


    Pour finir, voilà donc ma question :
    Y a-t-il moyen de donner une "fausse instruction" au while(){}, pour bloquer le code ? Sans que ce soit un System.out.println

    PS : désolé pour la longue bafouille
    PPS : J'imagine qu'il y a un moyen d'ajouter le code qu'on veut montrer en mode "tout joli", mais je ne sais pas encore comment on fait ! Ne frappez pas le petit nouveau

  2. #2
    Membre expérimenté
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Par défaut
    La réponse courte et pragmatique : utilises un AtomicBoolean. En bonus, tu peux ajouter un petit Thread.sleep(250) à l’intérieur de ton while.

    Voilà, ça s’appelle une attente active et ça ne va pas t’emmener bien loin dans la construction d’une IHM qui tienne la route. Disons que c’est un premier pas dans ce qui est probablement ce qu’il y a de plus complexe et difficile à maîtriser dans la programmation : la concurrence.

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2013
    Messages : 6
    Par défaut
    Merci pour cette réponse rapide !
    Par contre je ne comprends pas vraiment ce qu'est un AtomicBoolean... Comment fonctionne-t-il, en quoi est-il différent d'un boolean ? "A boolean value that may be updated atomically.", ça ne me parle pas beaucoup ^^

  4. #4
    Membre expérimenté
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Par défaut
    Bien que deux threads d’une même application partage le même espace mémoire, ce dernier n’est synchronisé que de « temps en temps ». Ce n’est donc pas parce que le thread A modifie la variable cluedo.choisi que le thread B verra ce changement en tentant de la lire. Pour que ton code fonctionne, il faut à la fois indiquer au code qui modifie le booléen qu’il doit vider son cache mémoire et au code lisant ce même booléen qu’il doit rafraîchir le sien. Ça peut se faire de 3 manières :
    1. Déclarer cluedo.choisi comme « volatile » (pourvu que tu ne modifies la variable qu’à un seul endroit).
    2. Utiliser un AtomicBoolean.
    3. Utiliser des « synchronized » pour coder explicitement ce que fait par ailleurs AtomicBoolean.

  5. #5
    Membre Expert
    Avatar de olivier.pitton
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2012
    Messages
    355
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 355
    Par défaut
    Plop,

    Pourquoi ne pas créer un événement sur ton JCombobox. En utilisant les classes comme ActionListener entre autres, au moment où l'utilisateur modifie la valeur du JComboBox, tu seras notifié, donc tant qu'il ne fait rien, tu n'as pas de while à faire.

    Pour ce qui est du AtomicBoolean, c'est simplement une classe encapsulant un boolean et permettant de le lire / modifier de manière atomique, donc que plusieurs threads ne peuvent y toucher au même moment.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2013
    Messages : 6
    Par défaut
    Bonsoir !
    Eh bien, j'ai un ActionListener sur le ComboBox bien sûr (qui au passage transforme un boolean en true pour passer à la suite du code). Je ne vois pas comment en faire un autrement.
    En attendant, j'ai trouvé une roue de secours : si je mets un System.out.println(""); dans le while, rien ne sort dans la console et le code est bien bloqué comme je le souhaite.
    Ca fait très système D je sais, mais je m'en fiche tant que je me simplifie la vie sans avoir à utiliser des atomicBoolean ou autre x)

    En attendant j'ai un autre soucis concernant mon IHM et le CardLayout. Je vais poster ça sur la bonne partie du forum.

    Merci quand même pour vos réponses !

  7. #7
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Bonjour,

    la bonne solution a été fournie par olivier.pitton, tu dois passer par un listener.

    Si je schématise ton code, on doit avoir quelquechose comme ce qui suit.

    Code "principal"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Code pour afficher la combo
     
    // Attente du choix
    while (cluedo.choisi==false){};
     
    // Suite du traitement
    Code du Listener
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void actionPerformed(ActionEvent e) {
        cluedo.choisi = true;
    }

    Tu devrais le modifier comme suit:

    Code "principal"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    // Code pour afficher la combo
    Code du listener
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void actionPerformed(ActionEvent e) {
    // Suite du traitement
    }
    Tu n'as plus d'attente et tu ne remplis plus la console avec des retours à la lignes...

    Dernier détail:
    Si ton traitement est potentiellement long, tu dois modifier le code de ton listener pour exécuter le traitement dans un autre thread. Sinon, tu va voir ton IHM se figer (Bouton enfoncé qui ne remonte pas par exemple).

    Cela peut se faire de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void actionPerformed(ActionEvent e) {
       new Thread(new Runnable() {
          public void run() {
             // Suite du traitement
          }
       }).start();
    }

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo