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 :

ArrayList de 500 objets : ça rame


Sujet :

2D Java

  1. #21
    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
    Pour moi c'est ton paintComponent() qui est trop compliqué... et tu utilises mal la zone de clip (tu devrais l'utiliser dans TOUS les cas et pas seulement lors du mouseOver/drag).

    Mais tout ceci reste très flou pour moi donc difficile de t'aider...

    Ton nombre d'Item est-il fixe ? Ou peut-il changer au cours du temps ?
    Tes Items peuvent-ils être modifiés (position,taille) au cours du temps ?
    Tes Items sont-ils opaque ?
    L'image onMouseOver est-elle de la même taille que l'image qu'elle remplace ?
    En quoi consiste graphiquement l'effet drag ?

    Enfin, à quoi ressemble ta classe Item ?

    a++

  2. #22
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Points : 13
    Points
    13
    Par défaut
    Oui, je suis d'accord, c'est trop compliqué.
    Je suis justement en train de la refaire.

    Je ne met QUE des repaint(x,y,w,h) dans le prgramme et je récupère la zone de clipping et dessine les images qui s'y trouvent.

    Ton nombre d'Item est-il fixe ?
    >> il y a autant d'Item que de ligne dans la base de données. On peur dire oui.

    Peut-il changer au cours du temps ?
    >> non...

    >> cependant, certains peuvent être mis "visibles" ou invisibles". Mais ils existent quand même, ils ne sont pas dessiné lorsqu'ils sont mis "invisibles".

    Tes Items peuvent-ils être modifiés (position,taille) au cours du temps ?
    >> oui, j'ai notamment une fonction Zoom pour cela

    Tes Items sont-ils opaque ?
    >> ce sont des PNG. tout l'image n'est pas opaque afin de lui donner une forme "non rectangulaire"
    L'image onMouseOver est-elle de la même taille que l'image qu'elle remplace ?
    >> oui, c'est exactement la même, il n'y a que la couleur qui change

    En quoi consiste graphiquement l'effet drag ?
    >> on appuie sur la souris, on reste appuyé et on déplace la souris
    >> la carte se déplace autant que l'on déplace la souris
    >> comme lorsqu'on déplace un fichier en Drag sous windows
    >> par contre, rien d'autre que la positions des images n'est changé... la transparence reste la même et la taille aussi.
    Enfin, à quoi ressemble ta classe Item ?
    >>J'ai deux constructeurs, un qui prends en compte les données reçues de la base de données, un autre qui ne le fait pas (pour l'image de fond par exemple, ou pour les icones de zoom, etc.).

    celui qui ne le fait pas :
    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
    public Item(BufferedImage bImage, String imgName, String name, BufferedImage bImageOver, String imgNameOver, String nameOver, int x, int y){
        	img = bImage;
        	ImagePath = imgName;
        	ItemName = name;
     
        	imgOver = bImageOver;
        	ImagePathOver = imgNameOver;
        	ItemNameOver = nameOver;
     
        	posX = x;
        	posY = y;
     
        	ItemSizeX = img.getWidth();
        	ItemSizeY = img.getHeight();
    }
    Dans l'autre constructeur, ya juste plus d'arguments...

    Et sinon, dans Item.java, ya des methodes set et get.
    A priori je n'ai plus besoin de mettre de fontion qui dessine l'Item puisque mon paintComponent de la classe principale le fait maintenant...

    Gspr que ça aide

  3. #23
    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
    Je pense que le mieux serait d'utiliser une image offscreen, justement pour éviter d'avoir trop d'élément à afficher à la fois.

    Dans ton offscreen tu dessines ton image normalement (comme tu le faisais dans ton code). Le seul problème viendra lorsque il faudra redimensionner un Item (on verra cela plus bas). Mais une fois que tu as créer ton offscreen, le code de ta méthode paintComponent() doit uniquement se contenter de le récopier dans la zone de clipping.

    Grosso-modo ta zone de dessin devrait commencer par un code comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	// On récupère la zone à redessiné :
    	Rectangle clip = g.getClipBounds();
    	if (clip==null) {
    		// Si elle n'est pas défini on dessine la page courante :
    		clip = getVisibleRect();
    	}
     
    	// On recopie l'image offscreen sur le graphics, 
    	// mais uniquement sur la zone de clipping :
    	g.drawImage(this.offscreen,
    		clip.x, clip.y, clip.x+clip.width, clip.y+clip.height,
    		clip.x, clip.y, clip.x+clip.width, clip.y+clip.height, null);
    En clair, tu redessines l'image offscreen sur ton composant, en te limitant à la zone de clipping (inutile de tout faire). De même lorsque tu affiches tout ton composant tu n'as plus 500 images à dessiné mais seulement une...



    Passons maintenant à l'effet "over". Pour moi le plus simple consisterait à utiliser un attribut contenant l'Item en "over", et de l'utiliser dans paintComponent(). Par exemple :
    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
    	if (overItem!=null) {
    		// La souris est sur un Item
    		// On doit redessiner la zone correspondante :
     
    		// On récupère la zone occupé par l'Item :
    		Rectangle bounds = overItem.getBounds();
     
    		// On redessine le background :
    		g.drawImage(this.background,
    				clip.x, clip.y, clip.x+clip.width, clip.y+clip.height,
    				clip.x, clip.y, clip.x+clip.width, clip.y+clip.height, null);
     
    		// Puis on parcours la liste des Items :
    		for (Item item : alItem) {
    			// Et on redessine uniquement les items dans cette zone :
    			if (bounds.intersects(item.getBounds())) {
    				item.draw(g);
    			}
    		}
    	}
    On redessine uniquement les Items qui se trouve dans la zone correspondant à l'état "over". Je considère ici que l'item peut se dessiner en "over" par lui-même via draw().



    Pour le drag ce n'est toujours pas très clair : tu déplaces toutes la carte ou uniquement un item ?


    a++

  4. #24
    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
    Oups j'ai oublié : le gros problème vient lors du changement de position/taille d'un item, car l'image offscreen n'est plus valide.

    Dans ce cas là, il faut :
    • Récupérer les bounds de l'item avant la modif.
    • Récupérer les bounds de l'item après la modif.
    • Redessiner sur l'image offscreen tous les items présent sur ces deux zone
    • Puis faire un repaint() sur ces deux zones (afin de réellement mettre à jour le composant.


    a++

  5. #25
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 31
    Points : 13
    Points
    13
    Par défaut
    merci pour ces infos

    Je suis pas sûr de comprendre ce qui concerne l'offscreen...
    En clair, tu redessines l'image offscreen sur ton composant, en te limitant à la zone de clipping (inutile de tout faire). De même lorsque tu affiches tout ton composant tu n'as plus 500 images à dessiné mais seulement une...
    Quelle est la raison pour laquelle on crée l'image offscreen si on ne fait que des repaint(x,y,w,h) avec la zone x,y,x+w,y+h correspondant à mon image ?

    Je n'ai pas pu essayer encore le "over" parceque je n'arrive pas à faire marcher le "offscreen"...

    Le drag consiste à déplacer la totalité de la carte.
    Mais ça va probablement prendre du temps à faire, puisque la carte contient plus de 500 images...
    Donc le mieux est probablement de toutes les déplacer et de ne redessiner que celles qui sont dans la zone de clipping correspondant à la taille de mon écran...

    Avant ta réponse, j'ai recommencé ma méthode 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
    super.paintComponent(g);
    Shape clip = g.getClip();
    final int clipX = clip.getBounds().x;
    final int clipY = clip.getBounds().y;
    final int clipXwidth = clip.getBounds().x + clip.getBounds().width;
    final int clipYheight = clip.getBounds().y + clip.getBounds().height;
     
    for (Iterator<Item> it = alItem.iterator(); it.hasNext(); ) 
    {
      Item iItem = it.next();
     
      if(...si un objet Item est dans la zone de clip...){
      if(iItem.getVisibility()) //s'il est visible on le dessine
      g.drawImage(iItem.getImgToDraw(), iItem.getX(), iItem.getY(), null);
    }
    C'est plus simple déjà... tous les repaint() sont repaint(x,y,w,h)
    Mais c'est toujours aussi lent...

    Il faudrait que j'utilise ton astuce offscreen... que j'avoue ne pas avoir compris si bien que ça, lorsque Bouye me l'a donnée...

  6. #26
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    - De même s'il y a 500 image et que toutes ne tiennent pas sur l'écran on ne va peut-être pas forcément créer une énoooooorme image avec les 500 autres mais uniquement une qui affiche ce qui est visible et après on utilise des bouton de navigation Next - Previous pour naviguer dans d'autres pages. Et charger les nouvelles images si besoin.

    - Même ainsi on peut s'arranger pour charger les images de manière aynchrone en créant d'abord des cadres vides à leur taille et ensuite en les chargeant en arrière-plan.

    Bref faire comme sur comme une boutique en ligne quoi ou la plupart des sites construits autour de requêtes de BD.

    Bref, il y a des tas et des tas d'optimisations possibles.
    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

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [Problèmes avec ArrayList] Supprimer des objets égaux à null
    Par smutmutant2003 dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 08/10/2009, 10h43
  2. [ArrayList] removeAll d'objets egaux
    Par Lady dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 24/09/2007, 10h32
  3. Serialisation/deserialisation d'un arrayList retourne des objets vides
    Par cdtkoenig dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 18/07/2007, 15h45
  4. Réponses: 1
    Dernier message: 18/01/2006, 18h39
  5. [ArrayList]transformer l'objet récupéré en double...
    Par snoop dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 16/07/2004, 16h16

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