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 :

Repaint(x,y,w,h) zone de clip et optimisation des performances


Sujet :

Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Par défaut Repaint(x,y,w,h) zone de clip et optimisation des performances
    Bonjour,

    J'ai de nombreuses images disposées sur une image de fond.
    Je souhaite modifier ces images lorsque l'utilisateur passe le curseur dessus (une à la fois évidemment), ça permet de faire comprendre que quelquechose peut se passe si l'on clique sur une image (exemple : les boutons "arrêter", "redémarrer" de XP).

    Chaque image est un objet et lorsque le curseur passe dessus, j'appelle une méthode propre à l'objet pour redéfinir le chemin de l'image.

    L'image change, le problème c'est que c'est très lent... et je souhaite que ça soit instantané...
    Ça redessine peut être toutes les images... en tout cas, moins il y a d'images, plus la modification de l'image au dessus de laquelle on place le curseur va vite...

    Du coup, j'ai essayé avec repaint(x,y,w,h) et j'arrive à récupérer ces 4 arguments dans paintComponent...

    => mais le problème reste le même... plus ya d'images, plus c'est lent...

    du coup,
    => j'aimerai savoir s'il est possible de récupérer ce qui devrait se trouver dans cette zone de clip ?
    avant de faire le repaint(x,y,w,h), je change l'image avec les bonnes coordonnées, donc même si elle n'est pas dessinée, elle devrait être placée à cet endroit...

    Je vous montre le code (tout est dans la même classe puisque les repaint() dans le MouseMoved de l'objet image ne fonctionnaient pas malgré les listener...)

    Fonction qui détecte la souris et qui change l'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
    public void MouseOverItem(MouseEvent event) //version simplifiée
    {
    for(int i = 0; i < vItem.size(); i++)
    {
      //test sur les images
      //si le curseur est sur l'image en question
      if(event.getX()<=getPositionX(vItem.elementAt(i).getName())+getLargeur(vItem.elementAt(i).getPath()) & event.getX()>=getPositionX(vItem.elementAt(i).getName()) & event.getY()<=getPositionY(vItem.elementAt(i).getName())+getHauteur(vItem.elementAt(i).getPath()) & event.getY()>=getPositionY(vItem.elementAt(i).getName()))
      {
        //je précise que je bouge, ça sert dans paintComponent
        isMoving=true;
     
    	//je teste la transparence
        if(alpha!=0)
        {
    	  //je change l'image
          vItem.elementAt(i).setNewImg(pathOVER,nameOVER);
          //vItem.elementAt(i).validate(); => avec ou sans ça change rien...
          repaint(vItem.elementAt(i).getX(),vItem.elementAt(i).getY(),vItem.elementAt(i).getLargeur(),vItem.elementAt(i).getHauteur());
        }
      }
    }
    }
    les fonctions pour repaindre (spcial thanks to Bouye)
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    protected void paintComponent(Graphics g) 
    {
      Graphics2D g2d = (Graphics2D) g.create();
      Graphics g2 = g.create();
     
      try 
      {
        if (isDragging) 
        {
          renderOffscreen(g2d,"dragging");
        }
        else if(isMoving)
        {
          renderOffscreen(g2d,"moving");
        }
        else 
        {
          renderDirectly(g2 );
        }
      }
      finally 
      {
        g2d.dispose();
        g2.dispose();
      }
    }
     
    protected void renderOffscreen(Graphics2D g, String mode) 
    {
      super.paintComponent(g);
     
      ...
      else if(mode.compareTo("moving")==0)
      {
        Shape clip = g.getClip();
     
        final int sx1 = clip.getBounds().x;
        final int sy1 = clip.getBounds().y;
        final int sx2 = clip.getBounds().x + clip.getBounds().width;
        final int sy2 = clip.getBounds().y + clip.getBounds().height;
     
    	//début du test pour trouver l'image sur laquelle on a cliquer
        for(int i=0; i<vItem.size();i++)
        {
          Pattern pattern_Item = Pattern.compile("^./images/Item/");
          Matcher matcher_Item = pattern_Item.matcher(vItem.elementAt(i).getPath());	
          if(matcher_Item.find()==true)
          {
            //sur toutes les images à l'écran, on trouver celle sur laquelle on a cliqué puisque c'est celle qui a correspond a la zone de Clip    
            if(sx2==getPositionX(vItem.elementAt(i).getName())+getLargeur(vItem.elementAt(i).getPath()) & sx1==getPositionX(vItem.elementAt(i).getName()) & sy2==getPositionY(vItem.elementAt(i).getName())+getHauteur(vItem.elementAt(i).getPath()) & sy1==getPositionY(vItem.elementAt(i).getName()))
            {
    		  //ouvre l'image qu'il faut (la nouvelle image) ; celle qui doit apparaitre lorsque l'on passe le curseur au dessus de l'ancienne image
              BufferedImage imageRepaint=null;
              try { imageRepaint = ImageIO.read(new File(vItem.elementAt(i).getPath())); } 
              catch (IOException e) { e.printStackTrace(); }
              imageRepaint=createCompatibleImg(imageRepaint); //créé une image compatible, mais ça ne change rien à la vitesse...
     
              //but : dessiner l'image et le fond pour donner l'impression que seul l'image à changer lors su passage de la souris
              g.setClip(clip);
              //g.setComposite(AlphaComposite.SrcIn);
              g.setColor(new Color(134,55,83));
              g.fill(clip);
              g.drawImage(imageRepaint, sx1, sy1, null);
            }
          }
        }
      }
    }
    Du coup, ça marche, mais pas assez vite...
    Ca vient peut être du "for" et des conditions du test pour récupérer l'image à dessiner... mais je n'ai pas vraiment le choix, parcequ'il y a différents types d'images, donc différents types d'images "survollées"...

    Merci pour votre aide...

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Tu dois précharger toutes tes images une fois pour toute et ne plus les lire sur disque ensuite.
    Commence par modifier ça
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Par défaut
    oui, c'est fait. Je les met même en image compatible...

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    Wohhhh, wohhhh, wohhhh, c'est quoi comme type de liste ?

    Parce que deja ton for dans la gestion de la souris cloche largement vu que tu n'arrete pas d'appeler getElementAt(i). C'est pas comme cela qu'on parcours une liste mister (surtout une longue liste). Deja meme avec une ArrayList c'est pas top mais imagine le trou de performance que ca doit etre avec une LinkedList.

    - Soit un parcours classique (et ce n'est pas forcement la meilleure des deux methodes, voir trou de performance avec LinkedList) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for(int i = 0; i < vItem.size(); i++) {
     // On appelle UNE SEULE FOIS vItem.elementAt(i)
     TrucChose chose = vItem.elementAt(i);
     [...]
    }
    - Soit par un interator implicite ou explicite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(Interator<TrucChose> it = vItem.iterator(); it.hasNext(); ) {
     TrucChose chose = it.next();
     [...]
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(TrucChose chose : vItem) {
     [...]
    }
    A corriger fissa dans la gestion de la souris mais aussi partout ou tu fais ce genre de choses.
    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

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    Ensuite tu peux te simplifier la vie en utilisant la methode intersect() de la classe Shape plutot que de faire les calculs de collision a la main.

    Fait gaffe ton test pour savoir sur quelle image on a clique est fausse... (la zone de clip peut etre completement differente). Tu devrais plutot garder l'indice de la bonne image ou une reference sur cette image quand tu le trouves dans la gestion de la souris.

    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
     
    private int activeImageIndex = -1
     
    // Me demande quelle IDE a genere ce nom de methode ?
    // M'enfin...
    public void MouseOverItem(MouseEvent event) //version simplifiée
    {
      // L'ancienne image n'est plus active elle a besoin d'etre redessinnee.
      if (activeImageIndex >= 0) {
        repaint(...); //boite de cette image.
      }
      activeImageIndex = -1;
      // chercher la nouvelle image...
      for ...
    }
    Ensuite, ton pattern ne semble jamais changer ; tu ne peux pas le compiler une bonne fois pour toute ?
    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

  6. #6
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Citation Envoyé par baltam Voir le message
    oui, c'est fait. Je les met même en image compatible...
    Justement non, ce n'est pas fait, C'est pour cela que je t'en parle. Dans la méthode "renderOffscreen", tu reconstruis l'image en la lisant sur disque via un ImageIO.
    De plus, pour le mode passé en paramètre de renderOffscreen, tu devrais utiliser un entier, ou mieux : une énumération si tu es en Java 1.5 ou supérieur. Ca évitera le long test de chaîne et empêchera de mettre n'importe quoi en paramètre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Par défaut
    Hi !
    merci pour vos réponses

    Merci dinobogan, effectivement, à chaque fois que je retourne l'hauteur d'une image (par exemple), je la lis du disque d'abord...

    Ça a l'air de bien marcher du coup.

    J'ai bien mis les iterator bouye, mais ça ne marche pas mieux. Toutefois, c'est mieux comme manière de lire une liste
    Autrement, qu'est ce que tu entends par "ton pattern ne semble jamais changer ; tu ne peux pas le compiler une bonne fois pour toute ?"

    Merci

  8. #8
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 897
    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 897
    Billets dans le blog
    54
    Par défaut
    Ton expression régulière est toujours la même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for(int i=0; i<vItem.size();i++)  {
       Pattern pattern_Item = Pattern.compile("^./images/Item/");
       [...]
    Après ca dépend ; tu nous a dis que c'était lent quand tu avais beaucoup d'images. Mais qu'est ce que "beaucoup d'images" chez toi ? 5 ? 200 ?
    La différence de vitesse dans le parcours de liste ne sera pas visible sur une petite liste.
    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

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Par défaut
    ah ok pardon.
    Pour le moment je suis dans une "phase de test", donc les patterns ne sont pas encore fixés.

    Sinon, pour le moment ma liste est de 40 environ, mais ça va vite monter à 200 ou 300.
    Le parcours de liste sera utile effectivement

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

Discussions similaires

  1. Réponses: 45
    Dernier message: 06/03/2007, 16h30
  2. Réponses: 1
    Dernier message: 18/02/2007, 11h07
  3. Réponses: 1
    Dernier message: 30/08/2006, 18h08
  4. Réponses: 1
    Dernier message: 21/01/2006, 09h54
  5. Réponses: 2
    Dernier message: 28/09/2005, 17h08

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