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

Composants Java Discussion :

Problème: JDesktopPane + Skin importé


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2008
    Messages : 34
    Par défaut Problème: JDesktopPane + Skin importé
    Bonjour,

    J'ai une application java avec un personnage que je déplace dans un JPanel dans une JFrame. Tout se passe bien, 0% de l'UC utilisée

    1er Problème:
    Lorsque j'importe un thème en utilisant en même temps un JDesktopPane (implémenté d'un JPanel et de 2 JInternalFrame translucides), ça utilise vers les 20% de mon UC soit environ 2.0GHz (je dispose d'un Q6600). Ce n'est pas le cas si j'enlève le thème ou si j'enlève le JDesktopPane en gardant le JPanel.

    2e Problème:
    De plus, je suis obligé d'utiliser la méthode setDragMode(JDesktopPane.OUTLINE_DRAG_MODE) sinon, lorsque mon personnage se déplace et que je bouge au même moment une JInternalFrame, sa vitesse se multiplie et il s'arrête plus loin que l'endroit où je clique.
    Il s'arrête sans problème au point voulu en temps normal.

    Ce déplacement est conçu de la façon suivante:
    Lorsque je clique avec la souris, je détermine de combien en x et en y mon personnage, centré sur l'écran, doit se déplacer a chaque boucle du thread.
    On a donc une vitesse de déplacement régie par le sleep du thread: cause du problème?
    Ce thread a un sleep de 40 ms.
    Ce calcul s'accompagne de 2 booléennes pour déterminer si le personnage va en haut ou en bas, à gauche ou à droite. Ainsi, lorsqu'il arrive au point où j'ai cliqué (MousePressed ou MouseDragged en fait), il s'arrête.

    3eme problème:
    Sous vista, lorsque j'ai le thème vista (par défaut), si je place ma JFrame de sorte qu'elle ait des pixels derrière le boutons "démarrer" qui est rond et qui dépasse de la barre, mon jeu se met à prendre dans les 15% de l'UC et le jeu rame. Dès que je monte la JFrame en dehors de ce bouton, l'UC se remet à 0%.

    Merci de vos réponses et de votre temps passé à lire mon problème.

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 913
    Billets dans le blog
    54
    Par défaut
    Sans code ou demo difficile de repondre plus en precisement.

    1) Generalement le JDesktopPane a toujours ete un trou au niveau performance (d'ou les flags pour changer l'affichage quand on deplace une JInternalFrame).

    2) Etrange, il semble que malgre le fait que tu utilises une Thread separee une partie de ton mouvement soit encore base sur des evenements de repeinture. Verifie bien ton code.

    3) Quelques astuces d'optimisation :

    - Il te faut optimiser ton rendu en tenant compte de la zone de clip du Graphics passe en paramettre de paint() ou paintComponent() et ce pour eviter de peindre des trucs inutiles.

    - En contrepartie quand tu demandes un reaffichage il te faut appeler la variante de repaint() qui prend en compte une zone definie. Par exemple dans ton cas tu dois, a chaque pas de la Thread appeler repaint() une fois sur la position actuelle du perso et une fois sur la position suivante. Quand tu es dans l'EDT tu peux faire deux appels separes a repaint() et le repaint manager fera l'union des deux zones au moment du reaffichage (puisque dans l'EDT, il n'y a pas de reaffichage au moment ou tu appelles repaint() sauf si tu appelles repaintImmediatly() - ce que generalement il ne faut pas faire). Or bien sur ceci n'est pas garanti dans une Thread autre, donc : stocke la position du perso (toute la zone couverte), deplace-le, fait l'union de l'ancienne et de la nouvelle zone puis appelle repaint().

    - Utilise des BufferedImage compatibles avec l'affichage que tu creeras grace a la classe GraphicsConfiguration. Cela permet d'obtenir un bon degree d'acceleration video.

    - As-tu essayer de tester ton projet sur la derniere version en date de la beta de Java 1.6.10_update10 ? Le support de l'acceleration 2D est sense etre meilleur dans les dernieres versions (evidement comme c'est une beta, des bugs peuvent survenir cependant).
    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

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2008
    Messages : 34
    Par défaut
    Avant tout merci pour ta réponse.

    Citation Envoyé par bouye Voir le message
    1) Generalement le JDesktopPane a toujours ete un trou au niveau performance (d'ou les flags pour changer l'affichage quand on deplace une JInternalFrame).
    Oui mais sans thème ajouté, l'UC n'est utilisé qu'a 3% (avec JInternalFrame translucide) et avec thème 15%.
    Voici le code pour l'implantation du thème, ( librairie ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Skin theSkinToUse = SkinLookAndFeel.loadThemePack("themepack.zip");
    SkinLookAndFeel.setSkin(theSkinToUse);
    UIManager.setLookAndFeel(new SkinLookAndFeel());
    Y a-t-il un autre composant pouvant intégrer des JInternalFrame?

    Citation Envoyé par bouye Voir le message
    2) Etrange, il semble que malgre le fait que tu utilises une Thread separee une partie de ton mouvement soit encore base sur des evenements de repeinture. Verifie bien ton code.
    Effectivement une partie des calculs étaient effectué dans paintComponent Merci .

    Citation Envoyé par bouye Voir le message
    3) Quelques astuces d'optimisation :

    - Il te faut optimiser ton rendu en tenant compte de la zone de clip du Graphics passe en paramettre de paint() ou paintComponent() et ce pour eviter de peindre des trucs inutiles.


    - En contrepartie quand tu demandes un reaffichage il te faut appeler la variante de repaint() qui prend en compte une zone definie. Par exemple dans ton cas tu dois, a chaque pas de la Thread appeler repaint() une fois sur la position actuelle du perso et une fois sur la position suivante. Quand tu es dans l'EDT tu peux faire deux appels separes a repaint() et le repaint manager fera l'union des deux zones au moment du reaffichage (puisque dans l'EDT, il n'y a pas de reaffichage au moment ou tu appelles repaint() sauf si tu appelles repaintImmediatly() - ce que generalement il ne faut pas faire). Or bien sur ceci n'est pas garanti dans une Thread autre, donc : stocke la position du perso (toute la zone couverte), deplace-le, fait l'union de l'ancienne et de la nouvelle zone puis appelle repaint().
    J'ai essayé d'appliquer ce que tu as dis voici le code obtenu ( je n'ai pas bien saisie la fin ) :
    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
    protected void paintComponent (Graphics g)
       {
    	     super.paintComponent(g) ;
    	    g.clipRect(0, 0, dimEcran.width, dimEcran.height);
    	      g.drawImage(imageFond,(int)xPerso, (int)yPerso, null);
    	      g.drawImage(imageInnaccessible,(int)xPerso, (int)yPerso, null);
    	      
    	      g.drawImage(Personnage.getImage(), (dimEcran.width/2)-Personnage.getIconWidth()/2, ((dimEcran.height-28)/2)-Personnage.getIconHeight()+20, null);
    	     
    	      g.drawImage(imageDerniereCouche,(int)xPerso, (int)yPerso, null);
    	      g.dispose();
    
       }
    //Dans la thread :
    regardeSiZoneAccessible();  /* Regarde les couleurs de l'image  'imageInnaccessible' par rapport à la position du personnage
    et si il y a de la couleur alors le déplacement est stoppé */
    
    repaint(0,0,dimEcran.width,dimEcran.height);
    xPerso += dx;
    yPerso += dy;
    Néanmoins il n'y a pas de diminution de l'UC utilisé ( mais surement de la carte graphique ) .

    Citation Envoyé par bouye Voir le message
    - Utilise des BufferedImage compatibles avec l'affichage que tu creeras grace a la classe GraphicsConfiguration. Cela permet d'obtenir un bon degree d'acceleration video.
    Je vais aller faire des recherches sur cette classe.
    Citation Envoyé par bouye Voir le message
    - As-tu essayer de tester ton projet sur la derniere version en date de la beta de Java 1.6.10_update10 ? Le support de l'acceleration 2D est sense etre meilleur dans les dernieres versions (evidement comme c'est une beta, des bugs peuvent survenir cependant).
    Je vais l'essayer.

    J'ai remarqué qu'en n'ajoutant pas les JInternalFrame au JDesktop ( donc un JDesktop supportant seulement un JPanel ) l'UC était diminué.
    Rendre les JInternalFrame translucide pourrait-il en être la cause?

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 913
    Billets dans le blog
    54
    Par défaut
    Non, quand tu es dans paintComponent(), le Graphics a deja un clip qui lui a ete fourni par le RepaintManager en fonction, entre autre des appels que tu as effectue a repaint().
    Tu dois donc recuperer cette forme (via getClip()) et verifier si ce que tu dois peindre est bien dans la zone a reafficher (si c'est dedans ou si ca l'intersecte). Si c'est le cas, tu redessines, sinon tu ne redessines pas.

    Et c'est la tout l'interret de ne demander un repaint() que sur une portion specifique de l'ecran : ne redessiner que ce qui se trouve a cet endoit.

    Ainsi plutot que d'appeler repaint(0,0,dimEcran.width,dimEcran.height); ce qui semble correspondre a tout ton ecran, concentre-toi uniquement sur la zone qui a besoin d'etre redessinnee.
    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
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2008
    Messages : 34
    Par défaut
    Citation Envoyé par bouye Voir le message
    Tu dois donc recuperer cette forme (via getClip()) et verifier si ce que tu dois peindre est bien dans la zone a reafficher (si c'est dedans ou si ca l'intersecte). Si c'est le cas, tu redessines, sinon tu ne redessines pas.
    Je suis désolé mais je ne vois vraiment pas comment faire

    Récupérer le clip du Graphics de la méthode paintComponent(), ok
    Mais vérifier si ce que je dois peindre est bien dans la zone à reafficher je vois pas.

    En simplifier, j'utilise un Thread qui fait un
    et une méthode paint(Graphics) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public void paint (Graphics g1)
       {
    		  Graphics2D g =(Graphics2D) g1;
    	 	  super.paintComponent(g) ;
     
    	      if((int)xPerso!=0 | (int)yPerso!=0) g.translate((int)xPerso,(int) yPerso);
     
    	      g.drawImage(fond,0, 0, this);
    	      g.translate(-(int)xPerso,-(int) yPerso);
     
    	      g.drawImage(myImagePerso[currentMyImagePerso].getImage(), (dimEcran.width/2)-myImagePerso[0].getIconWidth()/2, ((dimEcran.height-28)/2)-myImagePerso[0].getIconHeight()+20, null);
     
    	      g.drawImage(couche3,(int)xPerso, (int)yPerso, this); 	 
       }
    Tu parle aussi d'utiliser des bufferedImages grâce à la classe GraphicsConfiguration, cette méthode suffit-elle?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public BufferedImage toBufferedImage(Image image) 
    	{
          image = new ImageIcon(image).getImage();
          BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),image.getHeight(null),BufferedImage.TYPE_BYTE_BINARY ); 
          Graphics g = bufferedImage.createGraphics();
          g.drawImage(image,0,0,null);
          g.dispose();
          return bufferedImage;  
    	}
    Voilà, merci pour ta patience.

  6. #6
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 913
    Billets dans le blog
    54
    Par défaut
    1) getClip() retourne une Shape, or tu connais et la position de ton perso et sa boite englobante (x, y, x+width, y+height) donc tu peux tres bien appeller les methode contains() et intersects() de l'interface Shape. CQFD.

    Cela peut sembler donner lieu a des calculs plus complexes mais en fait tu gagnes enormement plus en optimisation ainsi qu'en dessinant tout le temps tout alors que durant certains repaint, si tu as fait les bons appels, seule une toute partie de l'affichage est a changer/redessiner.

    2) non car une BufferedImage cree ainsi peut ne pas etre dans le format interne de la carte video. Donc au moment de la composition sur l'ecran, cette image sera convertie en un format compatible ce qui ralentira l'affichage (conversion qui sera effectuee a chaque reaffichage). Tu peux gagner enormement en performances en utilisant des BufferedImage compatibles des le depart, celles crees par GraphicsConfiguration.createCompatibleImage(...).
    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. [XHTML] Problème de skin au passage XHTML1.1
    Par PerfectSlayer dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 13/02/2007, 12h22
  2. Problème de syntaxe importation Excel
    Par evans dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 13/04/2006, 19h02
  3. Problème avec l'import DTS SQL Serveur 2005
    Par dlan dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 07/03/2006, 12h47
  4. Problème sur export import fromuser touser
    Par tomsawyer dans le forum Oracle
    Réponses: 3
    Dernier message: 19/12/2005, 12h15
  5. Problème champ après import d'excel vers access
    Par David M dans le forum Access
    Réponses: 6
    Dernier message: 16/10/2005, 12h53

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