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

Interfaces Graphiques en Java Discussion :

Problèmes fenetre de chat


Sujet :

Interfaces Graphiques en Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 96
    Points : 39
    Points
    39
    Par défaut Problèmes fenetre de chat
    Bonjour

    Je dois actuellement créer un client de messagerie instantannée pour mon tfe, et j'ai un petit problème au niveau graphisme du client. Je m'explique :

    - Lorsqu'une personne envoie le message vers son interlocuteur, le message envoyé doit s'afficher chez l'autre personne (bien évidement me diriez vous). Là où ça coince c'est que le message est bien envoyé vers la personne, mais il ne s'affiche pas dans la fenetre.

    Je vous montre mon code pour l'envoie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public void actionPerformed(ActionEvent e) {
    		Object source = e.getSource();
    		if(source == button1){
    			if(messageField.getText() != null){
    				try{
    					String message = jabberModel.getUser()+" : "+messageField.getText()+ "\n";
    					jabberModel.sendMessage(jabberid+"@"+jabberModel.getServerName(), null, "thread_chat", "chat", null, message);
    					discussionField.append(message);
    					messageField.setText(null);
    				}
    				catch(Exception ex){
    					ex.printStackTrace();
    				}
    			}
    		}
    		else if (source == button2){
     
    		}
    	}
    La méthode de reception des messages là voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    String message = null;
    			do{
    				Packet packet = jabberModel.getTestThread().waitFor("message",null);
    				message = packet.getChildValue("body");
    			}
    			while(message == null);
    Le problème c'est que lorsque j'appelle ce bout de code, j'entre dans une boucle indéfinie (la boucle se trouve dans le waitFor) qui attend la réception d'un message. Et il restera dans cette boucle jusqu'à ce qu'il reçoive ce message donc je ne peux rien faire d'autre en attendant.

    La meilleure solution pour moi est que lorsqu'un utilisateur appuie sur le bouton envoyé, ça doit automatiquement appelé la méthode de reception de message chez le client et inversément, mais je ne sais pas comment faire pour implémenter ceci dans ma fenetre.

    Quelqu'un aurait une idée ?

    Merci beaucoup

    Dasson

    P.S. : J'utilise le protocole Jabber pour la messagerie instantanée.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 96
    Points : 39
    Points
    39
    Par défaut
    Bon je viens de trouver un moyen de faire naviguer les messages d'une fenetre à l'autre mais il reste toujours un petit problème.

    Tout d'abord le code

    ici l'envoie d'un message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public void actionPerformed(ActionEvent e) {
    		Object source = e.getSource();
    		if(source == button1){
    			String message = messageField.getText();
    			if(message != null){
    				try{
    					jabberModel.sendMessage(jabberid+"@"+jabberModel.getServerName(), null, "thread_chat", "chat", null, message);
    					discussionField.append(jabberModel.getUser()+" : "+message+"\n");
    					messageField.setText(null);
    					refresh=true;//variable static
    				}
    				catch(Exception ex){
    					ex.printStackTrace();
    				}
    			}
    		}
    		else if (source == button2){
     
    		}
    	}
    et ici la reception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public void windowActivated(WindowEvent e) {
    		/* Cette méthode est invoquée lorsque la fenêtre devient la fenêtre active sur le bureau */
     
    		if(refresh){//test si on a appuyé sur l'envoie d'un message
    			String message = null;
    			do{
    				Packet packet = jabberModel.getTestThread().waitFor("message",null);
    				message = packet.getChildValue("body");
    			}
    			while(message == null);
    			discussionField.append(jabberid+" : "+message+"\n");
    			refresh = false;//variable static
    		}
    	}
    Voilà, les echanges se font correctement. Mais le problème qui survient c'est qu'une personne ne peut pas envoyer 2 messages successif, mais doit attendre une réponse de son interlocuteur pour pouvoir lui envoyer un 2e message, ce qui est naturellement pas très logique pour faire de l'instant messaging.

    Une petite aide ne serait pas de refus.

    Dasson

  3. #3
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    C'est normal tu bloques l'EDT !!!
    Pour info l'EDT est le thread unique qui gère l'interface graphique et ses événements. Comme tu effectues des traitements "lourds" dedans tu l'empêches de mettre à jour l'affichage ce qui provoque des blocages.

    Par "traitement lourd" j'entends toutes les tâches qui ne dépendent pas de l'UI et qui peuvent éventuellement le bloquer. Même si on est d'accord que l'envoi d'une trame réseau est "rapide" pour un humain, c'est "long" dans le processus...

    Tu trouveras plusieurs discussions sur le sujet dans les forums, ou en consultant cet article : http://gfx.developpez.com/tutoriel/j...ing-threading/


    La solution étant donc d'utiliser des threads pour ces traitements, de préférence en utilisant la classe SwingWorker qui facilite cela :

    Tutoriel : http://rom.developpez.com//java-swingworker/

    Ton actionlistener ressemblerait alors grosso-modo à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    	public void actionPerformed(ActionEvent e) {
    		// On est dans l'EDT
     
    		Object source = e.getSource();
    		if(source == button1){
    			// On récupère le message et on vide le champ :
    			final String message = messageField.getText();
    			messageField.setText(null);
    			if(message != null){
    				new SwingWorker<String, Object>() {
     
    					/**
                                             * La méthode doInBackground() est appellée dans un thread
                                             * afin d'effectuer un traitement en fond de tache sans
                                             * bloquer l'interface graphique.
                                             */
    					@Override
    					protected String doInBackground() throws Exception {
    						// On est dans un thread à part :
    						// On envoi le message
    						try {
    							jabberModel.sendMessage(jabberid+"@"+jabberModel.getServerName(), null, "thread_chat", "chat", null, message);
    							return jabberModel.getUser()+" : "+message+"\n";
    						} catch (Exception e) {
    							return "Le message n'a pas pu être envoyé";
    						}
    					}
     
    					/**
                                             * La méthode done() est appellée dans l'EDT une fois que
                                             * la méthode doInBackground() s'est terminé. On peut alors utiliser
                                             * get() pour récupérer la valeur retourné par doInBackground().
                                             */
    					@Override
    					protected void done() {
    						discussionField.append(get()); // get renvoi le retour de doInBackground()
    					}
    				}.execute(); // Attention : ne pas oublier de lancer le SwingWorker ;)
    			}
    		}
    	}


    Pareil pour la réception des messages : tu attends un message seulement lorsque la fenêtre est activé !

    La réception des messages ne dépend pas d'un listener sur ton interface graphique : tu dois utiliser un thread en tâche de fond qui bouclera à l'infini pour attendre les messages, et qui les enverra à l'interface graphique quand ils arriveront (et non pas quant la fenêtre devient active).

    Par exemple quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    		new SwingWorker<Object, String>() {
    			@Override
    			protected Object doInBackground() throws Exception {
    				try {
    					// Tant que le thread n'est pas interrompu
    					while (Thread.currentThread().isInterrupted()==false) {
    						// On attend un message (ce code correspond bien à ca ?)
    						Packet packet = jabberModel.getTestThread().waitFor("message",null);
    						String message = packet.getChildValue("body");
     
    						// Et on le passe à l'EDT : 
    						publish(jabberid+" : "+message+"\n");
    					}
    				} catch (Exception e) {
    					// Traitement des erreurs
    					e.printStackTrace();
    				}
    				return null;
    			}
     
    			/**
                             * Cette méthode est appellée dans l'EDT lorsque la méthode
                             * publish() est appellée depuis le thread. Elle permet donc
                             * de mettre à jour l'affichage :
                             */
    			@Override
    			protected void process(List<String> chunks) {
    				for (String message : chunks) {
    					discussionField.append(message);
    				}
    			}
    		}.execute();

    Bon courage...

    a++

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 96
    Points : 39
    Points
    39
    Par défaut
    Merci pour ta réponse, je crois que ça va grandement m'aider.

    Je te tiens au courant demain de l'évolution du code, car c'est le code se trouve sur le pc du boulot.

    Je vais donc pour l'instant faire une bonne lecture.

    Dasson

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 96
    Points : 39
    Points
    39
    Par défaut
    Un grand merci. Grâce à toi tout marche correctement, et je vais alors modifier un peu mon code pour optimiser les threads grâce aux différents tuto que tu as posté.

    Dasson

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Swing] Problème Fenetre modale
    Par Nimothenicefish dans le forum Débuter
    Réponses: 4
    Dernier message: 30/05/2008, 19h22
  2. [VBA-E] problème fenetre
    Par Pantera dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 31/05/2007, 16h15
  3. problème fenetre JTree
    Par youp_db dans le forum Composants
    Réponses: 2
    Dernier message: 14/11/2006, 18h39
  4. Problème fenetre de chargement
    Par krolineeee dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 24/08/2006, 10h11
  5. [Problème] Fenetre d'aide avec texte formatté
    Par joker.benj dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 14/05/2006, 19h10

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