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

SWT/JFace Java Discussion :

Création Zone de Dessin 2D


Sujet :

SWT/JFace Java

  1. #1
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut Création Zone de Dessin 2D
    Bonjour,

    Je souhaite créer une zone de dessin dans une interface graphique. Quelque chose de simple qui permet de créer des lignes, des points et de placer des images sur ou au-dessus des lignes, mais chaque élément doit être sélectionnable (ce qui est la seule difficulté).

    J'ai déjà créé un Canevas et tester quelques petits trucs (tracer une ligne notamment), maintenant j'aimerais savoir si vous aviez une bibliothèque à me recommander pour faire ce que j'ai décrit juste au-dessus, sachant qu'encore une fois l'élément important c'est que je veux que mes éléments soient sélectionnables. Malgré le fait que l'on soit sur le forum AWT/SWING je ne suis pas fermé aux propositions SWT/JFACE (en fait j'hésite à poster le même post sur le forum réserver à SWT/JFACE, mais je ne sais pas trop si cela sera bien utile).

    Merci d'avance pour vos conseils
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Tu as de la chance, c'est une question qui a été posée récemment je pense. Regarde un peu ceci.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    Effectivement je n'avais pas vu ce post je te remercie. J'ai tout de même deux questions : avec les Shape je peux rendre cliquable un point, une ligne, mais je ne l'ai pas vu pour une image, est-ce possible de le faire aussi pour une image ? Deuxième question y a-t-il une équivalence en SWT (si oui je préférerais l'utiliser, si non ce n'est pas grave ^^)
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  4. #4
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Pour rappel, une image est un rectangle.

    Une shape peut être un rectangle.

    Donc la réponse est oui.

    En SWT tu peux certainement dessiner des lignes, des points, des rectangle, comme en swing j'imagine. Pour ce qui concerne la sélection, cela ne devrait pas changer énormément. Mais je ne fais pas de SWT donc a prendre avec des pincettes.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par wax78 Voir le message
    En SWT tu peux certainement dessiner des lignes, des points, des rectangle, comme en swing j'imagine. Pour ce qui concerne la sélection, cela ne devrait pas changer énormément. Mais je ne fais pas de SWT donc a prendre avec des pincettes.
    C'est tout à fait similaire (simplement le Canvas SWT et également un container, donc permet d'ajouter des composants aussi, mais ça ne servirait à rien ici). Il n'y a pas de raison de passer à SWT pour ça (plus lourd, car il faut une distrib par par platform (il y a une partie native dans SWT)).

    Pour les bibliothèques il y en a SWING (Piccolo2D par exemple) et en SWT/Draw2D (GEF), mais elles sont toutes les deux overkill pour dessiner juste des lignes, des points et des images. Elles ont justes l'avantage de gérer directement la sélection, entre autres.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    Si je préfère SWT, c'est parce que je développe avec Eclipse RCP et windowsbuilder. Je n'ai donc jusqu'ici utiliser que des objets SWT et je souhaitais garder une certaine homogénéité.

    Du coup je pense que je vais me tourner vers Draw2d, car la gestion de la sélection est vraiment importante pour moi.

    En tout cas je vous remercie tous les deux pour vos conseils
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  7. #7
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    Si je préfère SWT, c'est parce que je développe avec Eclipse RCP et windowsbuilder. Je n'ai donc jusqu'ici utiliser que des objets SWT et je souhaitais garder une certaine homogénéité.

    Du coup je pense que je vais me tourner vers Draw2d, car la gestion de la sélection est vraiment importante pour moi.

    En tout cas je vous remercie tous les deux pour vos conseils
    Oui, dans ce cas, il vaut mieux intégrer du Canvas SWT. Je ne pense pas qu'il soit indispensable de passer sur Draw2D : tu te fais une petit interface avec une méthode draw(GC gc) et mouseMatch(int x, int y) et trois implémentation concrète, une la ligne, une pour le point, et une l'image) : SWT natif suffira. Ton implémentation de Canvas aura une liste de d'instances de cette interface, et il y a juste à la parcourir dans le PaintListener et le MouseAdapter/MouseMoveListener.

    Accessoirement on peut intégrer du AWT dans du SWT (ce que je fais perso avec Piccolo2D justement), mais juste pour des lignes et des images, autant le faire directement en SWT.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  8. #8
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    D'accord, d'accord je vois, mais je viens de penser, il faudrait aussi que j'ai une fonction de zoom et de dezoom et j'aimerais créer un repère orthonormé pour simplifier mes calculs sur la distance entre deux points, mais aussi pouvoir, après avoir sélectionner une ligne, la redimensionner à la volé. C'est toujours possible avec du SWT natif et draw(GC gc) ou là ça devient plus compliqué ? (Je préfère poser toutes mes questions maintenant et d'être sur de partir sur le bon truc plutôt que me retrouver bloqué au milieu de mon travail ^^').
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  9. #9
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Il y'a surement un équivalent de swing (AffineTransform) qui te permettra de faire les translation et un scale (zoom) en swt avant de dessiner tout ton "modèle". (peut être ça)
    Et en réutilisant (si nécessaire) la transformation sur les shapes au moment de la détection de sélection ca devrait passer normalement.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    D'accord, d'accord je vois, mais je viens de penser, il faudrait aussi que j'ai une fonction de zoom et de dezoom et j'aimerais créer un repère orthonormé pour simplifier mes calculs sur la distance entre deux points. C'est toujours possible avec du SWT natif et draw(GC gc) ou là ça devient plus compliqué ? (Je préfère poser toutes mes questions maintenant et d'être sur de partir sur le bon truc plutôt que me retrouver bloqué au milieu de mon travail ^^').
    Alors :

    • zoom/dezoom, donc soit transformées affines (qui permet de faire les changements d'echelle, mais aussi les rotations) soit se taper un facteur d'échelle à appliquer à chaque point. C'est pareil en SWT et en DRAW2D : ça utilise l'objet Transform dont l'implémentation simplifiée rend un peu fastidieux son usage (disons que tu vas manipuler de la matrice), mais si ça reste sur le changement d'echelle, ça va, ce n'est pas trop compliqué non plus). Ce qui est casse-pied, c'est que un Transform est une resource, donc il faut bien penser à le disposer quand il faut.
      Gérer le scale à la main (avec 2 variables) n'est pas très compliqué pour dessiner, ou pour faire la transformée inverse pour gérer la souris (et oui, parce qu'il faut gérer la souris à l'échelle également, pour sélectionner des lignes ou des images).
      Par contre, quand on fait du changement d'echelle, on a vite besoin des translations aussi : ce n'est pas non plus très compliqué, mais ça fait encore un truc à gérer à la main.
    • Le repère orthonormé : je ne vois pas en quoi ça a un rapport avec le calcul de distance... sinon, c'est juste quelques lignes à dessiner. Éventuellement, tu peux t'appuyer sur java.awt.geom pour le calcul de distance et passer de SWT à AWT et inversement pour faire ça.


    Donc ça fait quelques trucs à gérer encore toi-même, à la main avec 2 variables ou un Transform pour le zoom/translation, et un dessin de repère à faire : pas de quoi justifier le passage à une bibliothèque, mais continue à rajouter des trucs, et ça pourrait devenir avantageux : au moins, tu ne te poses aucune question sur le zoom, en dessin, comme en interactivité, tu peux ajouter tous les objets que tu veux : çà simplifie pas mal de choses.

    Sinon pour gérer la Transform, je dois pouvoir te refiler ma classe utilitaire qui permet de manipuler un org.eclipse.swt.graphics.Transform comme une java.awt.geom.AffineTransform (plus exactement une PAffineTransform), donc plus simplement
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    Le repère orthonormé ce n'est pas pour qu'il soit apparent, mais pour gérer la notions de distances et d'échelle malgré le zoom/dezoom. Je m'explique avec un exemple on imagine que les points c'est des villes et les traits la distance entre celle-ci (on affiche la distance sur le trait), je veux que malgré le zoom/dezoom quand on trace un trait la distance affiché sur un autre trait soit proportionnel au premier. Mais aussi si je zoom sur un point, lorsque je dezoom, je ne veux pas que tout ce qui était passé "hors cadre" lors du zoom disparaissent.

    Vous voyez ce que je veux dire ?
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  12. #12
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    Vous voyez ce que je veux dire ?
    Oui. Mais pas besoin de dessiner un repère orthonormé pour gérer ça : c'est juste une aide visuelle pour l'utilisateur. Ensuite, de toute manière les coordonnées des points en Java (AWT comme SWT, c'est toujours dans un repère orthogonal, mais avec l'axe des abscisses inversé, la tête en bas).

    Le zoom par transformée affiche n'agit que sur l'affichage, pas sur les données (on pourrait, mais c'est plus compliqué, lent, et inutile) : donc tout ce qui n'est pas visible à une échelle donnée le devient si on zoom en arrière forcément. Il ne faut pas voir le contexte graphique (AWT comme SWT), on une feuille de dessin, ou on ajoute des dessins, on en supprime avec une gomme, et que le zoom fonctionnait comme s'il prenait une photo en jetant à la poubelle le dessin précédent. On dessine toujours tout, et dès qu'on veut changer quelque chose (ajouter une ligne, changer l’échelle...), de base, on redessine tout (on peut par la suite optimiser que pour ne dessiner qu'une partie mais c'est plus plus complexe).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  13. #13
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    Hmmm, d'accord effectivement c'est plus simple comme ça, du coup je serais bien intéressé par ta classe utilitaire qui permet de manipuler Transform

    J'ai une question qui me vient là : pour le changement d'échelle, comment on gère les points qui sortent de l'écran avec un zoom ? Car j'aurai quand même besoin d'eux pour tracer les lignes. Et sais-tu aussi où se trouve le point d'origine du canvas de base ?

    Dernière question lors de la sélection, pour montrer à l'utilisateur que tel ou tel objet a été sélectionné (avec des petits carrés rouges entre l'objet sélectionné par exemple), c'est à moi d'y gérer à la main ou il y a une fonction qui le gère ?
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  14. #14
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    Hmmm, d'accord effectivement c'est plus simple comme ça, du coup je serais bien intéressé par ta classe utilitaire qui permet de manipuler Transform
    Je n'ai pas le temps de virer toutes les dépendances (j'ai paré au plus vite) : la classe qui t'intéresse c'est PAffineTransform. C'est une Transform SWT, donc il faudra penser à la disposer. Mais elle a les méthode d'une AffineTransform AWT, donc est plus facile à manipuler (pas besoin de manipuler les matrices). Les méthodes utilitaires de AffineTransform sont par contre dans TransformUtils (comme getScaleInstance() par exemple).
    Il y a tout ce qu'il faut pour passer d'une AffineTransform vers une Transform ou PAffineTransform ou vice versa.

    Citation Envoyé par maelstrom Voir le message
    J'ai une question qui me vient là : pour le changement d'échelle, comment on gère les points qui sortent de l'écran avec un zoom ? Car j'aurai quand même besoin d'eux pour tracer les lignes. Et sais-tu aussi où se trouve le point d'origine du canvas de base ?
    Tu n'as pas à te préoccuper de ça : imagine que tu dessines sur une feuille de taille infinie (pas vraiment, parce qu'on est limité par le type des coordonnées (int ou double selon les méthodes que tu emploies). Simplement la fenêtre est chargée d'afficher que ce qui correspond à sa taille à elle. Comme sur l'image suivante (ou la fenêtre est le rectangle cyan, la ligne en noire est dessinée avec des coordonnées en dehors de l'écran, et on ne voit à l'écran que la partie en orange)


    Nom : clip.png
Affichages : 654
Taille : 375 octets

    Attention à une chose par contre : c'est à toi de dire au Canvas quel est sa taille (il ne peut savoir ce que tu dessines dans le Graphics), avec setPreferredSize(). Donc chaque fois que tu vas ajouter des lignes, des images, ou des points, il faudra recalculer le périmètre englobant maximum pour redéterminer les bounds.

    Sinon, le point d'origine (0,0) est en haut à gauche. Tu as intérêt à translater ce point pour qu'il soit au centre du viewport (ou canvas sinon scroillable)


    Citation Envoyé par maelstrom Voir le message
    Dernière question lors de la sélection, pour montrer à l'utilisateur que tel ou tel objet a été sélectionné (avec des petits carrés rouges entre l'objet sélectionné par exemple), c'est à moi d'y gérer à la main ou il y a une fonction qui le gère ?
    Oui, c'est à toi de le gérer. A mon avis tu devrais te faire une petite abstraction chargé de gérer un objet dessinable de base, qui intègre cette notion, puis d'avoir trois implémentations concrètes, une pour la ligne, une pour le point et une pour l'image.
    Fichiers attachés Fichiers attachés
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  15. #15
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    je n'ai pas tout compris sur le premier point. Concrètement, quelle est la classe qui m'intéresse exactement ?

    Ensuite, selon toi il serait préférable de déplacer l'origine du repaire (0,0) au centre du canvas ? Qu'il soit au centre ou en haut à gauche ça ne change rien non ? Tant que l'on s'adapte à la situation de départ et que l'on s'y tient.

    Pour finir si j'ai bien compris pour le troisième point, je fais une abstract class avec un constructeur qui prend un Object et une méthode isSelected(). Et cette méthode je la redéfinis dans trois implements : une pour la ligne, une pour le point et une pour l'image. C'est bien cela ?
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  16. #16
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    je n'ai pas tout compris sur le premier point. Concrètement, quelle est la classe qui m'intéresse exactement ?
    Pour obtenir une transformée sans facteur de zoom (initialisation) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PAffineTransform transform = new PAffineTransform(display); // créé une transformée identitée
    Le passage du display, c'est la contrainte SWT (le display tu l'obtient sur ton Canvas, par getDisplay()) : donc tu peux faire :


    Comme je l'ai dit, il s'agit d'un Transform SWT, mais qu'on peut utiliser comme un AffineTransform (qui a les mêmes méthodes, donc voir la doc de AffineTransform). Sauf que j'ai dit que les méthodes statiques, je les avais mises dans TransformUtils) :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class MyCanvas extends Canvas {
     
         private final PAffineTransform transform;
     
         public MyCanvas(Composite composite, int style) {
             super(composite, style);
             transform = new PAffineTransform(getDisplay()); // 
         }
     
     
    }
    Ensuite pour manipuler le transform :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    transform.setToScale(2, 2); // passe à un zoom x 2
     
    	transform.setToScale(0.5, 0.5); // passe à un zoom / 2
     
    	transform.scale(2, 2); // multiplie par 2 le zoom actuel
     
    	transform.scale(0.3333, 0.3333); // divise par 3 le zoom actuel
    Attention, à faire impérativement sur le thread SWT sinon risque de plantage.

    Donc tu peux par exemple, t'écrire une méthode dans MyCanvas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void changeZoom(double factor) {
        	 checkWidget(); // on s'assure de pas appeler la méthode en dehors du thread SWT par inadvertance
             transform.setToScale(factor, factor);
             redraw(); // on redessine pour prendre en compte le changement d'échelle
    }
    Pour préndre en compte la transformée lors du dessin, il faut l'affecter au GC dans le PaintListener :

    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
    public MyCanvas(Composite composite, int style) {
             super(composite, style);
             transform = (PAffineTransform) TransformUtils.getIdentity(getDisplay()); // 
             addPaintListener(new PaintListener() {
     
            	 // on va utiliser cette variable pour mémoriser le transform avant de le changr
            	 // sinon on va foutre la zone dans tout l'affichage
            	// ici on a pas besoin de manipulation, donc on prend direct une Transform 
            	 private final Transform savetransform = new Transform(getDisplay()); 
     
            	 {
            		 addDisposeListener(new DisposeListener() {
     
    					@Override
    					public void widgetDisposed(DisposeEvent e) {
    						savetransform.dispose();
    					}
     
    				});
            	 }
     
    			@Override
    			public void paintControl(PaintEvent e) {
    				e.gc.getTransform(savetransform); // on sauve
    				e.gc.setTransform(transform); // on affecte le zoom
    				// ici on dessine
    				e.gc.setTransform(savetransform); // on restaure
    			}
    		});
             // permet de disposer la transformée lorsque le canvas est disposé : plus besoin d'y penser
            addDisposeListener(new DisposeListener() {
     
    			@Override
    			public void widgetDisposed(DisposeEvent e) {
    				transform.dispose();
    			}
    		});
         }

    Citation Envoyé par maelstrom Voir le message
    Ensuite, selon toi il serait préférable de déplacer l'origine du repaire (0,0) au centre du canvas ? Qu'il soit au centre ou en haut à gauche ça ne change rien non ? Tant que l'on s'adapte à la situation de départ et que l'on s'y tient.
    Avec l'origine 0,0 en haut à gauche, quand tu vas zoomer, tu vas agrandir vers la droite et vers le bas, ce qui n'est pas très naturel. En général, il est plus naturel de zoomé centré. Donc tu devras faire une translation sur ton zoom pour que ça zoom centré. C'est de ça que je parlais.

    Citation Envoyé par maelstrom Voir le message
    Pour finir si j'ai bien compris pour le troisième point, je fais une abstract class avec un constructeur qui prend un Object et une méthode isSelected(). Et cette méthode je la redéfinis dans trois implements : une pour la ligne, une pour le point et une pour l'image. C'est bien cela ?
    Oui, et non.
    L'objet en paramètre, ça va dépendre : pour un point, c'est 2 int, pour un segment, c'est 2 points par exemples (je parle de point SWT, ou draw2d), et pour un image, c'est une image SWT par exemple. PAs le même type, pas le même nombre, donc pas dans l'abstraction.
    isSelected, c'est pareil : pour le point et l'image, ça marche. Pour le segment, si tu veux déplacer chaque point séparément, il faudra autre chose.
    Disons que tu peux faire boolean isSelected() si tu veux pouvoir récupérer cette info, mais je verrais plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public abstract void draw(GC gc); // pour dessiner le le truc
     
    public boolean select(int x, int y); // pour sélectionner à la souris
    dans le cas du point et de l'image, ça sélectionne tout. dans le cas d'un segment, selon l'endroit où on clique (une extrémité ou l'autre, ou même un point au milieu, ça sélectionne, ou pas, l'une des extrémité, ou autre chose, peu importe). C'est là que isSelected() veut dire juste y'a quelque chose de sélectionné dans ce composant, pour savoir lequel il faut aller plus proche dans le détail (travailler avec la classe concrète).
    Il faut juste penser à appliquer la transformée inverse de transform (voir la méthode de PAffineTransform, Point inverseTransform(Point p1, Point p2), ou celle avec PrecisionPoint, ou encore, PAffineTransform.transform(double[],int,double[],int,int)) sur le x,y de la souris avant d'appeler select(x,y) : ainsi, tous tes tests d'intersections, de distances, etc... se fera à l'échelle 1, par rapport au repère d'origine.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  17. #17
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    Alors j'ai un petit problème et une question :

    Le problème :
    Citation Envoyé par joel.drigo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class MyCanvas extends Canvas {
     
         private final PAffineTransform transform;
     
         public MyCanvas(Composite composite, int style) {
            super(composite, style);
            transform = (PAffineTransform) TransformUtils.getIdentity(getDisplay()); // 
         }
     
     
    }
    Lorsque j'instancie dans mon éditeur la class MyCanvas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyCanvas canvas = new MyCanvas(tabFolder, SWT.NONE);
    J'au une erreur qui me dit que TransformUtils ne peut pas être caster en PAffineTransform : java.lang.ClassCastException: org.eclipse.swt.graphics.Transform cannot be cast to net.zephyr.graphicInterface.transform.PAffineTransform

    Après pour ma question :
    Citation Envoyé par joel.drigo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    @Override
    			public void paintControl(PaintEvent e) {
    				e.gc.getTransform(savetransform); // on sauve
    				e.gc.setTransform(transform); // on affecte le zoom
    				// ici on dessine
    				e.gc.setTransform(savetransform); // on restaure
    			}
    J'ai une variable qui m'indique ce que je dessine (un point, une ligne ou une image) selon quel bouton est sélectionné donc c'est là où tu as mis //ici on dessine, que je gère tout ça ? avec un switch puis des Listenner SWT.MouseDown, SWT.MouseUp ?
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  18. #18
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par maelstrom Voir le message
    Alors j'ai un petit problème et une question :

    Le problème :

    Lorsque j'instancie dans mon éditeur la class MyCanvas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyCanvas canvas = new MyCanvas(tabFolder, SWT.NONE);
    J'au une erreur qui me dit que TransformUtils ne peut pas être caster en PAffineTransform : java.lang.ClassCastException: org.eclipse.swt.graphics.Transform cannot be cast to net.zephyr.graphicInterface.transform.PAffineTransform
    Oui, c'est de ma faute : c'est le seul cas que je n'ai pas traité, et j'ai oublié de modifié mon exemple dans mon message.

    Au lieu de transform = (PAffineTransform) TransformUtils.getIdentity(getDisplay()); //Fait transform = new PAffineTransform(getDisplay())
    Citation Envoyé par maelstrom Voir le message
    Après pour ma question :

    J'ai une variable qui m'indique ce que je dessine (un point, une ligne ou une image) selon quel bouton est sélectionné donc c'est là où tu as mis //ici on dessine, que je gère tout ça ? avec un switch puis des Listenner SWT.MouseDown, SWT.MouseUp ?
    Non. A cet endroit on fait juste le dessin de ce qu'il y a dessiner. Il ne faut pas que tu vois un contexte graphique comme une feuille de papier sur laquelle on dessine des trucs et que ça reste dessiné dans qu'on passe pas un coup de gomme. Une image serait plus comme une feuille de papier.

    En fait, à tout moment, le fond d'un composant peut être redessiner : il ne faut pas chercher à tenir compte de quand et comment, mais toujours considérer que ça peut se faire à tout moment. Tout ce qu'on a faire, c'est que à chaque fois que ça se fait, programmer le code qui fait ce qu'on dessiner dans le fond du composant.

    Lorsque ce qu'on veut dessiner est statique et fixe, c'est facile : il suffit de mettre tous les ordres de dessins à l'endroit ou j'ai mis mon commentaire //ici on dessine. Mais lorsque c'est variable, comme dans ton cas, on va plutôt stocker dans une liste les éléments à dessiner (une variable de la classe) et à l'endroit du commentaire les dessiner.
    C'est là qu'un choix s'impose :

    • soit on détermine comment dessiner dans la méthode de dessin
      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
      public void paintControl(PaintEvent e) {
      	e.gc.getTransform(savetransform); // on sauve
      	e.gc.setTransform(transform); // on affecte le zoom
       
      	// ici on dessine
       
              // on parcourt une liste de ce qu'il y a dessiner
              for( ... ) {
       
                    type = typeDeCeQuilYaADessiner
       
                    switch( type ) {
                         case c'est une ligne
                             on dessine une ligne
                             break
                         case c'est un point
                             on dessine un point
                             break;
                         case c'est une image
                             on dessine une image
                             break;
                    } 
       
              }
       
      	e.gc.setTransform(savetransform); // on restaure
      }
    • mieux et plus souple : on représente nos objets à dessiner par une Interface (par exemple IDrawable), ou une abstraction, et on implémente 3 classes :
      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
      public class MyCanvas extends Canvas {
      	 private final PAffineTransform transform;
       
      	 private List<IDrawable> drawables = new ArrayList<IDrawable>();
       
           public MyCanvas(Composite composite, int style) {
               super(composite, style);
               transform = new PAffineTransform(getDisplay()); // 
               addPaintListener(new PaintListener() {
       
              	 // on va utiliser cette variable pour mémoriser le transform avant de le changr
              	 // sinon on va foutre la zone dans tout l'affichage
              	// ici on a pas besoin de manipulation, donc on prend direct une Transform 
              	 private final Transform savetransform = new Transform(getDisplay()); 
       
              	 {
              		 addDisposeListener(new DisposeListener() {
       
      					@Override
      					public void widgetDisposed(DisposeEvent e) {
      						savetransform.dispose();
      					}
       
      				});
              	 }
       
      			@Override
      			public void paintControl(PaintEvent e) {
      				e.gc.getTransform(savetransform); // on sauve
      				e.gc.setTransform(transform); // on affecte le zoom
      				for(IDrawable drawable : drawables) {
      					drawable.draw(e.gc);
      				}
      				e.gc.setTransform(savetransform); // on restaure
      			}
      		});
               // permet de disposer la transformée lorsque le canvas est disposé : plus besoin d'y penser
              addDisposeListener(new DisposeListener() {
       
      			@Override
      			public void widgetDisposed(DisposeEvent e) {
      				transform.dispose();
      			}
      		});
           }
       
           public void changeZoom(double factor) {
          	 checkWidget(); // on s'assure de pas appeler la méthode en dehors du thread SWT par inadvertance
               transform.setToScale(factor, factor);
               redraw(); // on redessine pour prendre en compte le changement d'échelle
          }
       
           public void add(IDrawable drawable) {
          	 checkWidget();
          	 drawables.add(drawable);
          	 redraw();
           }
       
      }
      Avec :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      public interface IDrawable {
       
      	void draw(GC gc);
       
      }
      Il suffit ensuite que tu fasses trois classes, dont voici par exemple la version pour la ligne :

      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
      public class LineDrawable implements IDrawable {
       
      	private int x1;
      	private int y2;
      	private int x2;
      	private int y1;
       
      	public LineDrawable(int x1, int y1, int x2, int y2) {
      		this.x1=x1;
      		this.y1=y1;
      		this.x2=x2;
      		this.y2=y2;
      	}
       
      	public void draw(GC gc) { 
      		gc.drawLine(x1, y1, x2, y2);
      	}
       
      }
      Pour la saisie, il faut passer par un MouseListener et probableemnt un MouseMoveListener : si tu veux pouvoir faire du dessin interactif, il te faudra ajouter des fonctionnalité à IDrawable pour gérer l'interactivité et le dessin intermédiaire (afficher par exemple ce qu'on est entrain de dessiner différemment). Tu peux d'ailleurs ajouter à IDrawable des méthodes qui seront appelés dans le MouseListener ou MouseMoveListener pour gérer comment les évènements modifie l'objet dessiné.

      Par exemple, vite fait (enfin ça ma permit de voir qu'il y avait un bug dans les classes que je t'ai donné (voir à la fin)) :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      public interface IDrawable {
       
      	void draw(GC gc, boolean drawing); // ici j'ajoute un argument booléen pour dire que je dessine un élément en cours de création (mais on peut faire autrement)
       
      }
      La classe ligne :
      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
       
      public class LineDrawable implements IDrawable {
       
      	private int x1;
      	private int y2;
      	private int x2;
      	private int y1;
       
      	public LineDrawable() {
      	}
       
      	public LineDrawable(int x1, int y1, int x2, int y2) {
      		setPoint1(x1, y1);
      		setPoint2(x2, y2);
      	}
       
      	public void setPoint1(int x1, int y1) {
      		this.x1=x1;
      		this.y1=y1;
      	}
      	public void setPoint2(int x2, int y2) {
      		this.x2=x2;
      		this.y2=y2;
      	} 
       
      	public int getX1() {
      		return x1;
      	}
       
      	public int getX2() {
      		return x2;
      	}
       
      	public int getY1() {
      		return y1;
      	}
       
      	public int getY2() {
      		return y2;
      	}
       
      	@Override
      	public void draw(GC gc, boolean drawing) {
      		gc.drawLine(x1, y1, x2, y2);
      		if ( drawing ) { // si vrai signifie que c'est en cours de dessin
      			gc.drawString("["+x2+","+y2+"]", x2+5, y2-15);	// par exemple, j'affiche les coordonnées - on peut tout imaginer !!!
      		}
      	}
       
      }
      Le canvas :
      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
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
       
      public class MyCanvas extends Canvas {
       
      	public enum Draw {
      		POINT,
      		LINE,
      		IMAGE;
      	}
       
      	 private final PAffineTransform transform;
       
      	 private List<IDrawable> drawables = new ArrayList<IDrawable>();
      		private IDrawable currentDrawable; 
      		private Draw currentDraw = Draw.LINE;
       
           public MyCanvas(Composite composite, int style) {
               super(composite, style);
               transform = new PAffineTransform(getDisplay()); // 
               addPaintListener(new PaintListener() {
       
              	 // on va utiliser cette variable pour mémoriser le transform avant de le changr
              	 // sinon on va foutre la zone dans tout l'affichage
              	// ici on a pas besoin de manipulation, donc on prend direct une Transform 
              	 private final Transform savetransform = new Transform(getDisplay());
       
              	 {
              		 addDisposeListener(new DisposeListener() {
       
      					@Override
      					public void widgetDisposed(DisposeEvent e) {
      						savetransform.dispose();
      					}
       
      				});
              	 }
       
      			@Override
      			public void paintControl(PaintEvent e) {
      				e.gc.getTransform(savetransform); // on sauve
      				e.gc.setTransform(transform); // on affecte le zoom
      				for(IDrawable drawable : drawables) {
      					drawable.draw(e.gc, false);
      				}
      				if ( currentDrawable!=null ) {
      					currentDrawable.draw(e.gc, true);
      				}
      				e.gc.setTransform(savetransform); // on restaure
      			}
      		});
               // permet de disposer la transformée lorsque le canvas est disposé : plus besoin d'y penser
              addDisposeListener(new DisposeListener() {
       
      			@Override
      			public void widgetDisposed(DisposeEvent e) {
      				transform.dispose();
      			}
      		}); 
              MouseAdapter mouseAdapter = new MouseAdapter();
              addMouseListener(mouseAdapter);
              addMouseMoveListener(mouseAdapter);
              // changeZoom(2); // on peut forcer le zoom pour les tests
           }
       
           public void changeZoom(double factor) {
          	 checkWidget(); // on s'assure de pas appeler la méthode en dehors du thread SWT par inadvertance
               transform.setToScale(factor, factor);
               redraw(); // on redessine pour prendre en compte le changement d'échelle
          }
       
           public void add(IDrawable drawable) {
          	 checkWidget();
          	 drawables.add(drawable);
          	 redraw();
           }
       
           private class MouseAdapter implements MouseListener, MouseMoveListener {
       
      		@Override
      		public void mouseDoubleClick(MouseEvent e) {
      			// TODO Auto-generated method stub
       
      		}
       
      		@Override
      		public void mouseDown(MouseEvent e) { 
      			switch( currentDraw ) {
      			case LINE:
      				{
      					LineDrawable lineDrawable = new LineDrawable();
      					Point point = inverseTransform(e.x, e.y);
      					lineDrawable.setPoint1(point.x, point.y);
      					lineDrawable.setPoint2(point.x, point.y);
      					currentDrawable = lineDrawable;
      				}
      				break;
      			case POINT:
      				// à faire
      				break;
      			case IMAGE:
      				// à faire
      				break;
      			}
      		}
       
      		private Point inverseTransform(int x, int y) {
      			Point p1 = new Point(x,y);
      			try {
      				return transform.inverseTransform(p1, null);
      			} catch (NoninvertibleTransformException e) {
      				// normalement y'a pas de problème d'inversion
      				e.printStackTrace();
      				return p1;
      			}
      		}
       
      		@Override
      		public void mouseUp(MouseEvent e) {
      			if ( currentDrawable !=null ) {
      				drawables.add(currentDrawable);
      			}
      			currentDrawable=null;
      			redraw();
      		}
       
      		@Override
      		public void mouseMove(MouseEvent e) {
      			System.out.println("mousemo");
      			if ( currentDrawable instanceof LineDrawable ) {
      				LineDrawable lineDrawable = (LineDrawable) currentDrawable;
      				Point point = inverseTransform(e.x, e.y);
      				lineDrawable.setPoint2(point.x, point.y);
      			} 
      			redraw();
      		}  
       
           }
       
      }


    Pour le bug, il est dans PAffineTransform, dans la méthode setElements (ligne 832 à priori) - il faut ajouter la ligne updateState():

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private void setElements(double m00, double m10, double m01, double m11,
    			double m02, double m12) {
    		super.setElements((float) m00, (float) m10, (float) m01, (float) m11,
    				(float) m02, (float) m12);
    		updateState();
    	}
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  19. #19
    Membre régulier Avatar de maelstrom
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2014
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2014
    Messages : 108
    Points : 120
    Points
    120
    Par défaut
    J'ai encore un petit problème et du coup quelque chose que je ne comprend pas :

    Cela vient de la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private Point inverseTransform(int x, int y)
    		{
    			Point p1 = new Point(x,y);
    			try
    			{
    				return transform.inverseTransform(p1, null);
    			}
    			catch (NoninvertibleTransformException e)
    			{
    				// normalement y'a pas de problème d'inversion
    				e.printStackTrace();
    				return p1;
    			}
    		}
    tout d'abord j'ai une erreur sur la ligne : return transform.inverseTransform(p1, null);. Car la méthode inverseTransform est déclaré comme ceci dans PAffineTransform : inverseTransform(Rectangle2D, Rectangle2D) et donc elle n'existe pas avec un Point pour objet. (inverseTransform(Point, null) n'existe pas).

    Et du coup par la même occasion je ne vois pas à quoi sert cette méthode pourquoi vouloir inverser ?
    Madness ? THIS IS JAVA !!!
    SPARTAN ! What is your programming language ? JAVA ! JAVA ! JAVA !
    Code well, code readable, code in Allman style !

    N'oubliez pas de cliquer sur si ce commentaire vous a été utile et aussi sur si cela a... résolu ton problème !

  20. #20
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Il faut importer org.eclipse.draw2d.geometry.Point (tu as dû importer org.eclipse.swt.graphics.Point, ou java.awt.Point) : c'est le seul moyen d'avoir des points qui peuvent avoir soit une précision de int, soit une précision de double.


    L'inversion sert à passer des coordonnées SWT qui sont affectés par la transformée (zoom) vers les coordonnées standard (non affectées par le zoom).
    Si j'affiche un point de coordonnées x, y en x'=T(x),y'=T(y) (transformées donc par la transformée affine), si je clique sur un point de coordonnées x1', y1', ces coordonnées correspondent à un point de coordonnées x1'=T(x1),y1'=T(y1), soit x1 = invT(x1'), y1=invT(y1').

    Essaye de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private Point inverseTransform(int x, int y) {
    			Point p1 = new Point(x,y);
    			/*try {
    				return transform.inverseTransform(p1, null);
    			} catch (NoninvertibleTransformException e) {
    				// normalement y'a pas de problème d'inversion
    				e.printStackTrace();
    				return p1;
    			}*/
                            return p1;
    		}
    Et décommente // changeZoom(2); // on peut forcer le zoom pour les tests : tu verras que quand tu cliques sur un point pour tracer une ligne, le point affiché est complètement décalé par rapport à l'endroit où tu cliques...

    Je te donne la classe de test :
    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 class DemoTransform {
     
    	public static void main(String[] args) {
     
     
    		Display display = new Display ();
    		Shell shell = new Shell (display);
     
    		shell.setLayout(new FillLayout());
    		new MyCanvas(shell, SWT.DOUBLE_BUFFERED);
     
    		shell.setSize(300, 300);
    		shell.open ();
    		while (!shell.isDisposed ()) {
    			if (!display.readAndDispatch ()) display.sleep ();
    		}
    		display.dispose ();
     
     
    	}
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. création zone de texte
    Par yousron dans le forum Access
    Réponses: 1
    Dernier message: 05/02/2007, 10h47
  2. Problème d'affichage dans une zone de "dessin"
    Par jason69 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 28/08/2006, 16h12
  3. Réponses: 1
    Dernier message: 06/06/2006, 17h52
  4. [débutant] Une zone de dessin et des boutons
    Par mavina dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 17/02/2006, 12h51
  5. [MFC] zone de dessin
    Par meli0207 dans le forum MFC
    Réponses: 3
    Dernier message: 04/07/2005, 16h12

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