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

2D Java Discussion :

Problème de performance


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 14
    Par défaut Problème de performance
    Bonjour a tous, j'ai un petit soucis:

    j'ai un programme qui superpose une quarantaine d'images png, via imageIO et je veux rajouter a ma JFrame des boutons. Seulement, lorsque je met un bouton, dont j'ai redefinit les icones, et que je met ContentAreaFilled(false),
    les performances sont très mauvaise, le système met 5 secondes a se rendre compte que je suis sur le bouton et à passer à l'autre image enfoncée.

    Ceci est valable pour tous les composants, dès que je definie l'opacité à false, le systeme ralentit.

    voici le code (simplifié) de mon programme :

    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
    public Interface() {
     
            setSize(1024,800);
     
            setContentPane(new AffichageImagesPanel());
     
            Bouton b = new Bouton(500,500,"1");
     
            add(b.labelBouton);  
            add(b.boutonPays);
     
            addKeyListener(new java.awt.event.KeyAdapter() {
                public void keyPressed(java.awt.event.KeyEvent evt) {
                    formKeyPressed(evt);
                }
            });   
     
        }
    Voici ma classe Bouton :

    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
    public class Bouton{
     
        final String urlImage = "build/classes/risk/png/";
     
        ImageIcon normal,dessus;
     
        JLabel labelBouton;
        JButton boutonPays;
     
        int x,y;
     
        String nbArmee;
     
        /** Creates a new instance of Bouton */
        public Bouton(int _x,int _y,String _nbArmee) {
     
            x=_x;
            y=_y;
            nbArmee=_nbArmee;
     
            dessus = new ImageIcon(urlImage + "dessus.jpg");
            normal = new ImageIcon(urlImage + "normal.jpg");
     
            labelBouton = new JLabel(nbArmee);
            labelBouton.setBounds(x+18,y+5,40,40);
     
            boutonPays = new JButton(normal);
            boutonPays.setRolloverIcon(dessus);
            boutonPays.setBounds(x,y,40,40);
            boutonPays.setRolloverEnabled(true);
            boutonPays.setFocusPainted(false);
            boutonPays.setBorderPainted(false);
            boutonPays.setContentAreaFilled(false);
        }
     
    }
    et enfin voici ma classe contenant et affichant les images :

    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
     
     public void paintComponent(Graphics g){
     
                System.out.println("je suis dans paint");
                g.drawImage(fond,0,0,fond.getWidth(),fond.getHeight(),null);
     
                int i;
     
                for (i=0 ; tabloNomsPays[i]!=null ; i++){
                    g.drawImage(tabloPng[i],0,0,tabloPng[i].getWidth(),tabloPng[i].getHeight(),null);
                }
     
        }
     
        /**
         * Creates a new instance of AffichageImagesPanel
         */
        public AffichageImagesPanel() {
     
            tabloPng = new BufferedImage[45];
            int i;
     
            this.setDoubleBuffered(true);
     
            try{
    		fond = ImageIO.read(new File(urlImage + "fond.jpg"));
    	}catch(Exception e){System.out.println(e);}
     
            for (i=0;tabloNomsPays[i]!=null;i++){
     
                try{
    		tabloPng[i] = ImageIO.read(new File(urlImage + tabloNomsPays[i] + random() + ".png"));
                }catch(Exception e){
                    System.out.println(e);
                    System.out.println(tabloNomsPays[i]);
                    }  
     
            } 
        }
    je ne sais pas si utiliser le double buffer ameliorerait les performances, mais en tout cas je ne comp)rend pas pourkoi ceci ne fonctionne pas.

    Merci de votre aide,

    Shoki

  2. #2
    Membre confirmé
    Homme Profil pro
    Ingénieur Informatique
    Inscrit en
    Décembre 2005
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur Informatique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 146
    Par défaut
    vous pouvez essayer avec la classe Toolkit pour charger les images.
    Pour ImageIO je ne l'ai jamais utilisé donc je ne connais pas son mode opératoire si je puis dire. Mais pour le chargement avec Toolkit, les image se chargeront de façon asynchrone. Ainsi ton application ne sera pas gelé si ça prend du temps de charger les images.
    Maintenant aprés si le rendu nécessite l'image, vous pouvez toujours essayer d'utilise un MediaTracker pour synchroniser le chargement de l'image...

    C'est assez rapide à tester, par contre il est vrai que le ToolKit ne renvois pas directement un BufferedImage par contre.

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Il va probablement falloir faire un peu de repartition de taches voir carrement du multithreading pour ameliorer un peu les perfs et faire egalement patienter l'utilisateur (barre de progressement javax.swing.ProgressMonitor+ curseur sablier). Si tu ne necessites pas d'avoir les images tout de suite/maintenant, le chargement asynchrone de Toolkit peut aider egalement. Note : ImageIO est synchrone.

    En restant monothreade : penser a utiliser SwingUtilities.invokeLater() pour deferer le chargement des image a un moment d'inactivite de l'EDT de maniere a ne pas bloquer la propagation d'evenements en cours. Attention via cette methode il est possible/probable que l'etat du moniteur ne soit pas mis a jour correctement puisque toute l'action se deroule dans l'EDT et donc bloque Swing (pas de repeinte entre autre) tant que le chargement n'est pas fini.

    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
     
    final ProgressMonitor monitor = new ProgressMonitor(this, "Loading...", "Start, 0, imageNumber);
    monitor.setMillisToPopup(0);
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    SwingUtilities.invokeLater(new Runnable() { 
      public void run() {
        doLoadImages(monitor);
      }
    });
     
    /** Loads images asynchronously.
    */
    private void doLoadImages(ProgressMonitor monitor) {
      try {
        ...
      }
      catch (Throwable t) {
        ...
      }
      finally {
        monitor.close();
        setCursor(Cursort.getPredefinedCursor(Cursor.DEFAULT_CURSOR));     
      }
    }
    En multithreade : attention aux interractions avec l'EDT.

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    final ProgressMonitor monitor = new ProgressMonitor(this, "Loading...", "Start, 0, imageNumber);
    monitor.setMillisToPopup(0);
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    Thread t = new Thread(new Runnable() { 
      public void run() {
        doLoadImages     
      }
    });
    t.setPriority(Thread.NORM_PRIORITY);
    t.start();
     
    /** Loads images asynchronously.
    */
    private void doLoadImages(final ProgressMonitor monitor) {
      try {
         ...
      }
      catch (Throwable t) {
        ...
        final BufferedImage[] images = ...
        ...
        SwingUtilities.invokeLater(new Runnable() { 
           public void run() {
             doSetImagesOnPanels(images)
           }
      }
      finally {
        SwingUtilities.invokeLater(new Runnable() { 
           public void run() {
             monitor.close();
             doRestoreCursor()
           }
        });
      }
    )
     
    /** Restore cursor.
     * <br>This method should be called in EDT.
     */
    private void doRestoreCursor() {
      setCursor(Cursort.getPredefinedCursor(Cursor.DEFAULT_CURSOR));     
    }
     
    /** Sets images on panels.
     * <br>This method should be called in EDT.
     * @param images The image array.
     */
    private void doSetImagesOnPanels(BufferedImage[] images) {
      ...
    }
    Tu peux aussi regarder du cote de la classe SwingWorker (dont une version sera incluse dans Java 6) qui permet une meilleur planifications des taches entre l'EDT et une autre thread.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur Informatique
    Inscrit en
    Décembre 2005
    Messages
    146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur Informatique

    Informations forums :
    Inscription : Décembre 2005
    Messages : 146
    Par défaut
    Et bien merci aussi également pour moi, même si la réponse ne me concernait pas, j'ai appris quelque chose que j'ignorais et qui somme tout est assez important a avoir à l'esprit lorsque l'on gérer graphisme et interface graphique...

    J'avais fait un post il y a quelques temps, et il est possible que ce soit finalement du à une erreur d'appréciation sur le comportement des thread gérant évenement et affichage swing en plus des miens propres :s

    Vu que vous avez mis le doigt sur quelque chose, j'aimerais savoir si vous connaissez un endroit sur le net ou je pourrais avoir plus de renseignement sur l'EDT...ce genre de renseignement pourrait m'aider pour la suite
    Merci d'avance

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Voir la Java de Devellopez et aussi probalement les bouquins sur Swing, le didacticiel de Sun, les posts de Gfx sur ce forum a propos de l'EDT et de Swing et probablement son blog perso (ainsi que les liens presents sur sa page sur les blogs de autres devellopeur de Swing sur Java.Net).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. Problème de performance avec LEFT OUTER JOIN
    Par jgfa9 dans le forum Requêtes
    Réponses: 6
    Dernier message: 17/07/2005, 13h17
  2. [jeu]problème de performance d'un algo
    Par le Daoud dans le forum Algorithmes et structures de données
    Réponses: 12
    Dernier message: 30/05/2005, 16h07
  3. [C#] Probléme de performance avec IsDbNull
    Par jab dans le forum Windows Forms
    Réponses: 8
    Dernier message: 04/04/2005, 11h39
  4. [oracle 9i][Workbench]Problème de performance
    Par nuke_y dans le forum Oracle
    Réponses: 6
    Dernier message: 03/02/2005, 17h38
  5. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18

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