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 :

[Performance]Graphics/Graphics2D


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 86
    Par défaut [Performance]Graphics/Graphics2D
    Bonjour,

    j'ai une petite application qui fonctionne bien, mais le rendu graphique laisse assez à désirer (quand je zoom, quand je scroll, etc).

    j'ai une JFrame, dans laquelle je met un JScrollPane, dans lequel je met un JComponent (j'y ajoute une image de fond et je dessine des choses dedans). Donc j'utilise un Graphics dans la méthode paintComponent du JComponents.

    J'ai vu dans la FAQ Java de ce site la méthode pour améliorer le rendu graphique avec un Graphics2D. J'ai donc essayé de l'appliquer en remplaçant le Graphics par un Graphics2D (après tout, c'est des classes mère et fille, donc un Graphics2D et aussi un Graphics il me semble). Mais là, le rendu est trop optimisé : plus rien ne s'affiche ds le JComponent...

    J'ai alors essayé de donner plus de mémoire avec -Xmx et -Xms, mais la seule influence est que j'arrive à plus zoomer (mais le rendu est toujours saccadé).

    Comment faire pour que le rendu soit plus fluide (là lorsque je déplace la barre de défilement ça met bien 3 secondes avant de le prendre en compte)? J'ai l'impression que c'est la Scrollpane qui ralentit, vu que les barres de défilement aussi sont lentes à réagir, et l'image dans le JComponent ne scintille pas (je me suis essayée au double buffering).

    Si quelqu'un a une suggestion, voir même une solution (alleluia!)...

    Merci d'avance
    [ Modéré par vedaer ]
    -> Ajout du tag dans le titre
    [ Merci de respecter les Règles du Forum ]

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    lorsque je déplace la barre de défilement ça met bien 3 secondes avant de le prendre en compte
    As-tu un traitement relativement très long dans ton affichage qui justifierait les 3 secondes ? (ce qui est assez énorme). Sinon, je dirai qu'il s'agit simplement d'un problème d'affichage. Fais-tu un invalidate() après chaque modification pour demander un rafraichissement du dessin ? Sinon, tu peux toujours faire un repaint() pour forcer le dessin.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 86
    Par défaut
    ben en fait, je fais du geocoding... donc sur le dessin, j'ai une carte en fond (genre la moitié d'une région), et dessus je dessine toutes les rues..... (je les récupères à partir d'une shapefile grâce aux librairies libres de Geotools). Mais la récupération des données des routes est vraiment rapide, et ne se fait qu'au début.

    Ensuite j'initialise des Hashtable avec ces données et à chaque fois je redessine le tout (parce que ça peut être modifié...).

    quand je zoome, je change uniquement un ratio, et ensuite je repaint, mais les scrollbars ont du retard sur le réaffichage de l'image.

    Lorsque je scroll, je ne redessine rien (tout est déjà chargé), et pourtant ça met un petit temps à le prendre en compte...

    Est-ce qu'il y a une fonction pour raffraichir la scrollbar ?

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Effectivement, ça ne justifie pas les 3 secondes. Je te conseille d'afficher du texte sur la console au début et à la fin de ton tracé pour te rendre compte si ton tracé dure réellement 3 secondes.

    Pour rafraîchir ta scrollBar, il faut en fait faire un invalidate() sur ton JScrollPane.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 86
    Par défaut
    bon, j'ai mis des println partout, et en fait la méthode que j'utilise pour ne pas toujours redessiner tt n'est pas utilisée... donc je redessine tt à chaque fois.

    J'avais essayé de reprendre le contenu de mon JComponent pour le redessiner comme une image, mais ça marche pas (snif...)

    Quelqu'un aurait-il un exemple d'utilisation sous le coude? je continue d'essayer de bien le placer, mais avec un exemple je serais sûre d'avoir la bonne méthode (plutôt que du bidouillage...)

    Merci

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 95
    Par défaut
    Je n'ai pas d'exemple, mais je peux te donner une méthodologie pour faire ça. Le principe est d'utiliser un buffer où tu vas faire tous tes dessins qui visiblement sont long. Ensuite, lors de l'affichage, il suffit de dessiner le buffer.

    Tiens, je te donne un premier jet en vitesse (à compléter) :

    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
    public MyJComponent extends JComponent {
     
      private BufferedImage buffer;
     
      public MyJComponent () {
        buffer = null;
      }
     
      protected void paintComponent(Graphics graphics) {
        if (buffer == null) {
          buffer = new BufferedImage(...);
          faireMonDessin( buffer.getGraphics() );
        }
        d.drawImage( buffer );
      }
     
      public void faireMonDessin(Graphics graphics) {
        ... à faire
      }
     
    }
    Faudra également penser à vérifier les tailles, cad que si la taille du composant change, il faudra refaire le buffer.

    Ensuite, quand tout ça fonctionnera, pour améliorer l'affichage, tu peux également utiliser un buffer directement en mémoire de la carte graphique. Regarde la FAQ à propos du DoubleBuffering en mémoire vidéo et adaptes ça à ton problème.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    86
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2005
    Messages : 86
    Par défaut
    En effet, j'utilisais une bufferedimage dans la fonction repaint pour essayer de faire pareil, mais ça laissait à désirer.
    Enfin merci bcp, ta méthode marche très bien en effet!

    voilà ma fonction paintComponent :

    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
    public void paintComponent(Graphics g) {
     
    			double ratioCourant = ratio;
     
    			setSize((int)(largeur*ratioCourant),  
                                        (int)(hauteur*ratioCourant));
    			// Affichage de l'arriere plan (... ou non)
    			try{
    				if (arrierePlan && background != null) {
    					g.drawImage(background, 0, 0, getWidth(), 
                                                   getHeight(), this);
    				} else {
    					g.setColor(Color.white);
    					g.fillRect(0, 0, getWidth(), getHeight());
    				}
    			} catch (Throwable t) {
    				t.printStackTrace();
    			}
    			if (tampon == null ||
    					(! (tampon.getWidth(this) == this.getWidth()
    							&& tampon.getHeight(this) ==  
                                                                 this.getHeight()))
    							     || (!redraw)) {
    				tampon = new BufferedImage(this.getWidth(), 
                                  this.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
    				affRes.rendre(ratioCourant, tampon.getGraphics() );
    			}
    			redraw = true;
    			g.drawImage(tampon, 0, 0, this);
    			if (itemSelect){
    				StringTokenizer s = new 
                                        StringTokenizer(list.getSelectedItem(), "\t");
     
    				affRes.selectRequete(g,((String) 
                                           s.nextElement()).trim(), ratioCourant);
    			}
     
    			sp.invalidate();
     
    		}
    Donc, petite exlication : mon appli affiche une carte png en fond (ou un autre format, on n'est pas racistes), et dessus dessine les routes récupérées dans la shapefile. après, je fais du geocoding (trouver les coordonnées d'une adresse), et j'affiche les résultats sur tout ça. Je peux aussi déterminer le "centre" d'une ville (en fait le centre de gravité de toutes ses rues), et là je le dessine sous les requetes des adresses.

    J'ai une liste à côté du JComponent dans laquelle je place les noms des adresses, et lorsque je clique sur un nom, la requete correspondante change de couleur (la dernière partie du painComponent).

    Maintenant, rentrons ds le détail : affRes, c'est l'afficheur de mon réseau de routes et de requêtes (celui qui dessine). ratio, c'est pour gérer la taille du component (pour le zoom). le booléen redraw me sert à vérifier si j'ai rajouté une requete (à ce moment là j'ai aussi besoin de tout redessiner).

    Je ne sais pas si le invalidate de la fin est nécessaire. Enfin, ça marche bien, et quand je scroll c'est fluide.

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

Discussions similaires

  1. Réponses: 28
    Dernier message: 09/09/2010, 17h27
  2. Réponses: 4
    Dernier message: 16/08/2007, 23h43
  3. [Graphics] Implémentation de la classe Graphics2D
    Par anykeyh dans le forum AWT/Swing
    Réponses: 3
    Dernier message: 25/06/2007, 18h46

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