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

Graphisme Java Discussion :

Besoin d'aide sur le JGlassPane


Sujet :

Graphisme Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut Besoin d'aide sur le JGlassPane
    Bonjour tout le monde!

    J'ai un petit souci de performance au niveau du rendu visuel de mon appli.
    Je m'explique : j'ai dans mon appli des JInternalFrame contenant, entre-autre, des images qui parfois doivent être associées, c'est-à-dire que l'on doit voir le curseur sur les 2 images. Pour cela, je récupère la position du curseur système sur la JInternalFrame active et je crée une "image de curseur" sur la JInternalFrame associée. (Déjà, si vous avez une meilleure solution, je suis preneur).

    Le problème, c'est que quand je déplace le curseur, je déplace aussi "l'image de curseur". Or comme c'est juste un dessin, je suis obligé de redessiner tout le contenu de ma JInternalFrame associée pour ne pas avoir la trace de mon "image de curseur"...
    Vous me suivez toujours?

    Or ce système, peut s'avérer très lent sur des images fortement zoomées.

    Je pensais donc utiliser le glasspane de ma JInternalFrame pour y faire afficher l'image de curseur et ne redessiner QUE l'image du curseur lors du déplacement du curseur système, et non pas tout le contenu de ma JInternalFrame...
    Je voulais donc avoir un peu d'aide là-dessus.

    En effet, les composants appartenant à ma JInternalFrame, possèdent différents mouseListener qui gèrent entre-autre l'apparence du curseur système, et qui ne doivent donc pas être bloqués par le glasspane. Le glasspane doit donc juste capter le mouseMoved de la JInternalFrame active et redessiner l'image de curseur sur la JInternalFrame associée.

    J'ai essayé de l'implémenter, mais seul le glasspane de la fenêtre inactive reçoit les évènements souris, ce qui est fort troublant


    Donc déjà, pensez-vous qu'il soit possible de ne pas avoir la trace de mon image de curseur en utilisant un glasspane?
    Si oui, un petit coup de pouce sur l'utilisation de ce composant serait la bienvenue. (j'ai déjà été voir ici, mais ça ne m'a pas beaucoup aidé)

    Merci d'avance!

  2. #2
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bonjour,

    Je ne connais pas trop les JGlassPane, mais un repaint(int x, int y, int w, int h) ne suffit-il pas pour améliorer tes performances ?
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  3. #3
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Le problème, c'est que justement cette méthode prend en argument des int...
    Or on s'est rendu compte que si on prend les coordonnées et dimensions du rectangle obtenu par getVisibleRect() de la classe JComponent, et qu'on les caste en int, ben ça foirait...

    Cette approximation est source d'erreur dans notre appli, donc on ne peut pas utiliser cette méthode. Mais on y avait pensé...

  4. #4
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bon, juste au cas ou vous utilisiez un JScrollPane, il y a JScrollPane.getViewport().getViewRect(), mais je suppose que vous y avez pensé.
    Je suppose que vous avez aussi essayé d'arrondir les x y en dessous et les w h au dessus.


    Au niveau du GlassPane, en quoi le tuto n'a pas aidé ? Le GlassPaneDemo n'a pas l'air mal. La méthode redispatchMouseEvent permet de filtrer les évènements souris, ça correspond à ce que tu veux faire, non ?
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  5. #5
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    C'est justement le fait d'arrondir qui pose problème pour nous, parce que ça entraîne un décalage.

    Le tuto sur le glasspane est bien, ça a l'air chouette, mais le problème c'est que chez moi, il ne capte les évènements souris que si je me ballade sur la JInternalFrame INactive... Et moi, c'est tout le contraire que je veux.
    Je veux qu'il capte les évènements souris sur la JInternalFrame active afin de les redispatcher comme dans le tuto...

  6. #6
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bon, ben, j'avais bien compris. Et je comprends pas.

    Ou peut etre : le GlassPane doit etre visible (setVisible(true/false)) pour attraper les évènements. Tu as vérifié ?

    En tout cas, la j'en sais pas plus que toi.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  7. #7
    Membre éclairé Avatar de soad
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    520
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2004
    Messages : 520
    Par défaut
    Citation Envoyé par seiryujay
    Le problème, c'est que justement cette méthode prend en argument des int...
    Or on s'est rendu compte que si on prend les coordonnées et dimensions du rectangle obtenu par getVisibleRect() de la classe JComponent, et qu'on les caste en int, ben ça foirait...

    Cette approximation est source d'erreur dans notre appli, donc on ne peut pas utiliser cette méthode. Mais on y avait pensé...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Rectangle r = tonComponent.getVisibleRect();
     
    int x = r.x;
    int y = r.y;
    int width = r.width;
    int height = r.height;
    api de la classe Rectangle : http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Rectangle.html

    tu peux récupèrer des int avec la class Rectangle !

  8. #8
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par xavlours
    Bon, ben, j'avais bien compris. Et je comprends pas.

    Ou peut etre : le GlassPane doit etre visible (setVisible(true/false)) pour attraper les évènements. Tu as vérifié ?

    En tout cas, la j'en sais pas plus que toi.
    Il doit être visible pour récupérer les évènements, et il l'est...
    C'est ça que je ne comprends pas.
    Je vais me faire un petit projet test à côté pour essayer de mieux comprendre son fonctionnement...

  9. #9
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par saod
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Rectangle r = tonComponent.getVisibleRect();
     
    int x = r.x;
    int y = r.y;
    int width = r.width;
    int height = r.height;
    api de la classe Rectangle : http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Rectangle.html

    tu peux récupèrer des int avec la class Rectangle !
    Je peux récupérer des int à partir de la classe Rectangle, effectivement, mais je ne VEUX pas! Le fait d'arrondir pose un problème pour moi...

  10. #10
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Si l'arrondi pose probleme recupere le rectangle, ajoute -1 a x et y et +2 a width et height, cela compensera les erreurs d'arrondis. Ensuite, tu peux surement mieux gerer tes decimaux. Si l'arrondi cree des decalages, tu devrais pouvoir regler ca autre part (apres tout on dessine un pixel ou pas, pas une fraction de pixel). N'oublie pas, si tu utilises repaint(x, y, w, h) il faut aussi honorer le clip rectangle dans ton code de dessin.

    J'utilise souvent repaint(x, y, w, h) dans le meme genre de cas et je n'ai jamais eu de probleme pour obtenir l'effet desire

  11. #11
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par Gfx
    Si l'arrondi pose probleme recupere le rectangle, ajoute -1 a x et y et +2 a width et height, cela compensera les erreurs d'arrondis. Ensuite, tu peux surement mieux gerer tes decimaux. Si l'arrondi cree des decalages, tu devrais pouvoir regler ca autre part (apres tout on dessine un pixel ou pas, pas une fraction de pixel). N'oublie pas, si tu utilises repaint(x, y, w, h) il faut aussi honorer le clip rectangle dans ton code de dessin.

    J'utilise souvent repaint(x, y, w, h) dans le meme genre de cas et je n'ai jamais eu de probleme pour obtenir l'effet desire
    En fait, j'ai fait un amalgamme... Le problème ne vient pas exactement du repaint(x,y,w,h). Le truc, c'est que j'ai redéfini la méthode paintComponent() du composant à repeindre, et dans cette méthode, il faut (entre-autre) que je rafraîchisse une image qui peut être zoomée et être donc plus grande que le "visibleRect".
    Donc pour essayer de rafraîchir juste la partie de l'image concernée, j'utilise un drawImage() auquel je passe en paramètre monImage.getSubImage(int,int,int,int) et l'AffineTransform appliquée à l'image.
    Et c'est ce getSubImage() qui pose problème, parce qu'il prend en paramètre des entiers, donc des arrondis des x,y,w et h rééls. Et si on applique l'AffineTransform à cette image "approximée", y'a un décalage de créé et ça pose problème...

    J'espère que j'ai pas été trop confus.

    Sinon, en passant : quelle méthode est appelée lors d'un repaint(x,y,w,h)?
    C'est pantComponent(Graphics) ou autre chose?

  12. #12
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Un repaint(x, y, w, h) appelle paintComponent() mais change le clip rectangle du Graphics passe en parametre (voir getClipRect()). C'est ce rectangle qui donne la zone dans laquelle dessiner et il faut la respecter pour ameliorer les performances. Dans le cas de ton drawImage(), mauvaise nouvelle... ton getSubImage() sera BEAUCOUP plus lent que le drawImage() tout court. Tu peux aussi tout simplement appeler la methode drawImage() qui permet de specifier la zone de l'image a dessiner :

    drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)

  13. #13
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Ok, merci pour les infos!

    Par contre, l'utilisation de drawImage(Image,int,...) est un peu génante pour moi. En effet j'applique une AffineTransform à mon image afin de pouvoir zoomer dessus.
    Or la méthode drawImage() que tu me conseilles ne prend pas en compte l'AffineTransform. Donc souci

    A moins qu'il soit possible de créer une image équivalente à l'image de base à laquelle on aurait appliqué l'AffineTransform...

  14. #14
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Non pas souci. C'est dans la documentation de Graphics2D :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void 	setTransform(AffineTransform Tx)
    Le mieux reste d'utiliser la methode scale(double, double) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    AffineTransform t = g2.getTransform();
    g2.scale(zoomLevel, zoomLevel);
    // dessiner avec drawImage()
    g2.setTransform(t);
    Et comme je l'ai dit tu peux aussi simplement appeler drawImage() comme si tu dessinais l'image entiere.

    Bref, lis la documentation et evite (d'esssayer) d'optimiser avant de l'avoir fait

  15. #15
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par Gfx
    Bref, lis la documentation et evite (d'esssayer) d'optimiser avant de l'avoir fait
    Crois-moi, je n'essaierai pas d'optimiser, si ce n'était pas nécessaire... Au départ, je redessinais tout, mais lorsqu'on dessinait des formes sur l'image et qu'on appliquer un fort facteur de zoom, les perfo étaient sévèrement amoindries. C'est pour ça qu'on essaie d'optimiser et de redessiner juste la partie utile.
    Ceci parce qu'il faut dessiner une image du curseur sur les JInternalFrame "associées" à la JInternalFrame active...

    Citation Envoyé par Gfx
    Non pas souci. C'est dans la documentation de Graphics2D :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void 	setTransform(AffineTransform Tx)
    Le mieux reste d'utiliser la methode scale(double, double) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    AffineTransform t = g2.getTransform();
    g2.scale(zoomLevel, zoomLevel);
    // dessiner avec drawImage()
    g2.setTransform(t);
    Et comme je l'ai dit tu peux aussi simplement appeler drawImage() comme si tu dessinais l'image entiere.
    Je teste ça, et je te donne des nouvelles...

  16. #16
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Existe-t'il un moyen pour ne dessiner que la partie visible à l'écran d'une Shape?

  17. #17
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Je n'ai pas dit que c'etait pas bien d'optimiser, j'ai dit qu'il ne faut pas le faire prematurement et sans lire la doc.

    Pour ta Shape, tu peux utiliser une Area pour faire l'intersection du clip rectangle et de ta Shape. Mais fais quelques tests pour voir si tu gagnes vraiment en vitesse (la creation de l'intersection peut etre couteuse).

  18. #18
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    Citation Envoyé par Gfx
    Je n'ai pas dit que c'etait pas bien d'optimiser, j'ai dit qu'il ne faut pas le faire prematurement et sans lire la doc.
    J'avais bien compris, mais crois-moi, je ne me serai pas lancé là-dedans si ce n'était pas nécessaire : j'ai bien plus confiance en la maîtrise des développeurs de Sun que dans mes capacités d'optimisation

    Citation Envoyé par Gfx
    Pour ta Shape, tu peux utiliser une Area pour faire l'intersection du clip rectangle et de ta Shape. Mais fais quelques tests pour voir si tu gagnes vraiment en vitesse (la creation de l'intersection peut etre couteuse).
    Déjà testé... Ca améliore assez fortement les performances, mais malheureusement cette méthode retourne une area, donc une forme fermée. Ce qui veut dire que ça dessine la partie de la Shape que je veux dessiner, plus le contour de ma zone d'affichage reliant les extrémités de la Shape.
    Ca peut être résolu en traçant un cadre tout autour de ma zone d'affichage, mais je pensais qu'il y avait une méthode plus "propre" dirons-nous...

  19. #19
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    J'ai bien compris que tu avais besoin d'optimiser, je dis que quand on le fait il faut lire la doc attentivement :p Notamment pour eviter l'utilisation de getSubImage() par exemple.

    Si ton probleme vient de l'utilisation d'une Stroke, tu peux simplement prendre faire une Area qui fait l'intersection de la Shape et du clip rectangle augmente de la taille de la Stroke. Le resultat sera trop grand mais pas assez pour diminuer les performances et la Stroke devrait etre dessinee en dehors du clip rectangle et n'apparaitra donc pas a l'ecran.

  20. #20
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    C'est ce qu'on se disait aussi.
    Bon ben je crois qu'on va partir sur cette solution... Même si j'aurai bien aimé que le glasspane ou un autre composant permette de redessiner juste la couche souhhaitée ou qu'il existe un mécanisme permettant de ne redessiner que la partie visible d'une Shape...

    Juste au cas où, j'ai cru comprendre qu'il était possible de "clipper" une Shape... cf l'API SMCanvas, partie "Utiliser le clipping"...
    Je ne sais pas si c'est faisable rapidement à partir des classes de base de java ou non.

    Une idée à ce sujet?

Discussions similaires

  1. besoin d'aide sur trigger
    Par devalender dans le forum SQL
    Réponses: 2
    Dernier message: 18/07/2004, 22h28
  2. [D7] Besoin d'aide sur un PChar
    Par bobby-b dans le forum Langage
    Réponses: 6
    Dernier message: 30/06/2004, 16h42
  3. Filemaker ... besoin d'aide sur les Plugin
    Par joange dans le forum Autres SGBD
    Réponses: 3
    Dernier message: 22/04/2004, 10h16
  4. [intermedia] besoin d'aide sur script PL/SQL
    Par SteelBox dans le forum PL/SQL
    Réponses: 8
    Dernier message: 05/01/2004, 19h59
  5. [CR] besoin d'aide sur les formules
    Par GuillaumeDSA dans le forum Formules
    Réponses: 4
    Dernier message: 10/07/2003, 12h19

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