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

Langage Java Discussion :

Problème de lag, comment détourner le problème ?


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut Problème de lag, comment détourner le problème ?
    Bonjour ou bonsoir,

    J'ai un soucis, expliqué ci-dessous.

    Ingrédients :
    • Une JFrame(jF) dans laquelle se trouve un JLabel(jL)
    • Un String(texte) pouvant varier et de taille(tailleTexte) pouvant également varier
    • Un Thread(defil), de priorité maximale, qui fait défiler le texte dans le jL à l'aide d'un compteur(compteur) qui est incrémenté "tous les 100 millisecondes"(je suis obligé d'avoir une périodicité d'environ 100 millisecondes)

    Code du Thread : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    			Thread defil = new Thread() {
    				public void run() {
    					compteur = 0;
    					tailleTexte = texte.length();
    					while (true) {
    						Thread.sleep(100);
    			        		tailleTexte = texte.length();
    			        		compteur = compteur % tailleTexte;
    						jL.setText(texte.substring(compteur, tailleTexte - 1) + texte.substring(0, compteur));
    			        		compteur = (compteur + 1) % tailleTexte;
    					}
    				}
    			 };

    Mon soucis est le suivant :
    J'ai un lag d'affichage.

    En dessous de 200 millisecondes, un lag se fait sentir lors de l'affichage.
    "Normal, c'est dépendant du processeur sur lequel est lancé le programme", vous allez me dire.

    MAIS j'aimerais tout de même avoir une solution.

    J'ai eu un début de solution, à savoir :
    La méthode setText pour un JLabel prend trop de temps. Donc il faut trouver un component dont le setText est plus rapide(au moins deux fois) que celui pour un JLabel, ou alors faire un gif animé du texte défilent et l'affiché.
    NB : Je n'aime pas la deuxième proposition, non pas par flemme, mais pour raison technique.

    Pouvez vous m'aider ?

    Merci


    Edit : Pour les curieux, je n'ai pas oublié de synchroniser le String texte et je n'ai pas oublié de catcher l'éventuel InterruptedException du sleep. A part ces deux "non ajouts" au code plus haut, tout est à l'identique.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 584
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 584
    Par défaut
    Hum. J'ai essayé de faire en sorte que le changement de texte soit le plus rapide possible (précalculer en mémoire toutes les images que la label doit faire en boucle, et les transférer directement au Raster,) et le même lag est toujours là. Un .gif animé ne ferait pas mieux.

    Pour respecter une telle vitesse, deux possibilités :
    - Changer l'affichage en fonction de ce qu'il devrait être au moment où on l'affiche. C'est comme ça qu'on fait de l'affichage vidéo en principe. Le rafraîchissement n'est pas plus rapide, mais les lags se voient peu.

    - Ne pas le faire en AWT ou Swing. Le faire en Java2D (ce qui inclut le premier point au-dessus.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Salut !

    J'en suis venu à peu près à la même conclusion, d'abord par rapport aux gif :
    Mise en mémoire des trames du gif et affichage périodique des trames. Mieux que l'affichage du texte dans un JLabel, mais toujours avec du lag.
    J'ai améliorer ça avec une petite modification, qui reprend ta remarque plus bas, plutôt que de faire digérer l'affichage des trames par le processeur en lui envoyant des instructions toutes les 100 millisecondes, je récupère l'heure toutes les 10 millisecondes et affiche les trames quand elles devraient apparaître. Le lag se fait largement moins sentir, mais est toujours présent.
    J'ai encore améliorer l'affaire.. Plutôt que d'afficher les trames les unes après les autres, j'ai assembler les trames bouts à bouts et je fais simplement glisser l'image avec la méthode cité plus haut.
    J'ai un résultat satisfaisant, mais .. j'ai l'impression de voir un lag.

    Puis par rapport à Java2D, j'ai jamais encore touché à ça, j'y toucherais plus tard, mais dans l'absolu je dois faire avec ce que j'ai pour l'instant.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Déjà, n'appelez aucune méthode de vos composants graphiques depuis un autre thread que l'EDT (voir la FAQ à ce sujet).
    Ensuite, en ce qui me concerne, je ne remarque aucun lag (hormis le fait que votre algorithme fait qu'une des combinaisons apparaît systématiquement deux fois et pourrait donner l'impression d'un arrêt sur image)

    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
    package test;
    import javax.swing.*;
     
     
    public class Test {
       static int compteur;
       public static void main(String[] argv){
          final String texte = "abcdefghijklmnop";
          JFrame frame = new JFrame();
          final JLabel test = new JLabel("test");
          frame.setSize(200,200);
          frame.getContentPane().add(test);
          frame.setVisible(true);
          Thread defil = new Thread() {
    	public void run() {
    		compteur = 0;
    			while (true) {
    				try{
    					Thread.sleep(10);
    		        		final int tailleTexte = texte.length();
    		        		compteur = compteur % tailleTexte;
    					SwingUtilities.invokeAndWait(new Runnable(){ 
    						public void run() {
    							test.setText(texte.substring(compteur, tailleTexte - 1) + texte.substring(0, compteur)); 
    						}});
    		        		compteur = (compteur + 1) % tailleTexte;
    				} catch (InterruptedException e){
    					return;
    				} catch (java.lang.reflect.InvocationTargetException e){
    					e.printStackTrace();
    				}
    			}
    	}
           };
           defil.start();
       }
    }
    edit: par contre il n'y a aucun raison de faire de la synchronisation sur votre string, et ça peut être la source de vos lags qui du code "lent" se synchronize aussi inutilement sur cette String.

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Bonsoir

    Je tiens à préciser deux petites choses que je n'ai pas précisé au premier post parce que je ne pensais pas qu'on allait regarder de ce côté là :
    • Je ne fais pas exactement un JLabel.setText.
      J'ai plusieurs classes : Boite(extend JFrame), Panneau(extend JPanel), Bouton(extend JButton), etc
      Dans mon thread defil, je fais ceci :
      ((Boite)fenetrePrincipale).setTexte(DefilLabel, "texte qui défile");
      Donc je ne pense pas avoir de soucis avec l'EDT, j'ai toujours eu cette habitude de programmation. Mais je vais aller vérifier quand même au cas où.
    • La synchronisation que j'effectue est nécessaire. Le texte à défiler peut varier, comme préciser sur mon premier post. Un autres Thread s'occupe de récupérer ce texte à défiler et mon Thread Defil doit vérifier cette variable commune afin de l'afficher. Je dois donc synchroniser l'envoi et la consultation de cette chaîne commune.


    Je n'ai pas bien saisi ce que vous entendez par :
    je ne remarque aucun lag (hormis le fait que votre algorithme fait qu'une des combinaisons apparaît systématiquement deux fois et pourrait donner l'impression d'un arrêt sur image)
    Aucune combinaison n’apparaît systématiquement deux fois :
    (pour une chaine de n(>1 caractères))
    compteur = 0
    texte.substring(0, n - 1) + texte.substring(0, 0)
    compteur = (0 + 1) % n = 1
    texte.substring(1, n - 1) + texte.substring(0, 1)
    ..
    compteur = ((n - 2) + 1) % n = n - 1
    texte.substring(n - 1, n - 1) + texte.substring(0, n - 1)
    compteur = ((n - 1) + 1) % n = 0
    texte.substring(0, n - 1) + texte.substring(0, 0)

    Le lag dont je vous parle intervient de façon aléatoire avec un sleep de 100 millisecondes.


    Edit : Je viens de tester votre code. A 100 millisecondes, je vois bien du lag.

    Edit 2 : A l'aide de isEventDispatchThread(), je suis toujours dans l'EDT.
    Avec ou sans synchronisation(String constant), j'ai du lag.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par zizoufoot Voir le message
    Dans mon thread defil, je fais ceci :
    ((Boite)fenetrePrincipale).setTexte(DefilLabel, "texte qui défile");
    Donc je ne pense pas avoir de soucis avec l'EDT, j'ai toujours eu cette habitude de programmation.
    Et cette méthode manipule les composant graphique, donc le problème EDT reste entier (voir la FAQ, toute opération graphique DOIT se faire dans le thread de l'EDT)
    La synchronisation que j'effectue est nécessaire. Le texte à défiler peut varier, comme préciser sur mon premier post.
    un String, c'est immutable, ça ne peux pas changer. Le champ où vous stockez la variable peux changer de valeur, mais pas l'objet String en lui même. Donc le synchronize est à faire sur le conteneur de la String dans ce cas. Aussi, si vous êtes dans le schéma un écrivain d'un coté, un lecteur de l'autre, il y a moyen de s'en sortir sans synchronize

    Je n'ai pas bien saisi ce que vous entendez par Aucune combinaison n’apparaît
    Bah j'ai retappé votre code (sans l'analyser) et la une des chaines apparaissait deux fois d'affilée J'ai pas regardé en détail
    Edit 2 : A l'aide de isEventDispatchThread(), je suis toujours dans l'EDT.
    Votre thread defil ne devrait pas être dans l'EDT :/

Discussions similaires

  1. [Conseils] Comment retrouver un problème
    Par Shoryu dans le forum Sondages et Débats
    Réponses: 67
    Dernier message: 03/11/2006, 13h26
  2. Comment gérer les problèmes de connexion sur un idFTP ?
    Par giloutho dans le forum Web & réseau
    Réponses: 2
    Dernier message: 05/12/2005, 18h42
  3. Réponses: 3
    Dernier message: 05/07/2005, 18h07
  4. Réponses: 16
    Dernier message: 24/06/2005, 12h49

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