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

AWT/Swing Java Discussion :

Plusieurs dessins sur même Panel + redimensionnement


Sujet :

AWT/Swing Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut Plusieurs dessins sur même Panel + redimensionnement
    Bonjour,
    J'ai le problème suivant que je n'ai pas réussi à résoudre, après plusieurs heures d'essais infructueux et quelques exemples étudiés.
    Je veux pouvoir dessiner :
    1) un rectangle dont les dimensions vont s'adapter à la fenêtre,
    2) un cercle qui doit exister dans la "même case" du conteneur parent (i.e. dans le getContentPane(... , BorderLayout.CENTER)) que le rectangle, éventuellement pouvoir se superposer avec.

    J'ai créé deux JPanel pan (contenant le rectangle) et pan2 (contenant le cercle), et je les mets dans un JLayeredPane pour gérer la transparence (setOpaque).

    J'arrive à avoir :
    a) soit seulement le rectangle redimensionnable, en utilisant un "this.getWidth()" pour définir sa longueur quand je le dessine dans le JPanel, mais alors je n'arrive pas à combiner avec le cercle dans le JLayeredPane. En fait, pour que ça marche, il faut que je mette pan directement dans le getContentPane de la fenêtre...

    b) soit le rectangle et le cercle, mais le rectangle est de taille fixe, car j'utilise un setBounds sur mes panels, et donc la taille est fixée.
    ...

    Merci pour votre aide.

    PS : Question complémentaire (je ne suis pas très avancé en Java) : dans le "this.getWidth()" que j'utilise dans le drawRect, à quoi (quel objet) fait référence exactement this ? Pourquoi est-ce que cette méthode ne marche pas quand j'utilise le "this.getWidth()" dans le setBounds ? (L'objet n'est visiblement plus le même...). J'ai vérifié que dans ce cas, this.getWidth() vaut 0 et donc on ne voit pas les objets...

    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
     
    import javax.swing.*;
    import java.awt.*;
     
    public class totojava extends JFrame {
     
    	private JLayeredPane lp ;
    	private JPanel pan ;
    	private JPanel pan2 ;
     
    	public totojava() {
    		// PREMIER PANEL : RECTANGLE 
    		pan = new JPanel() {
    			public void paintComponent(Graphics g){
    				g.setColor(Color.black);
    				g.drawRect(100, 100, this.getWidth()-150, 200) ;
    				// ICI, THIS = ????? 
    			}           
    		};
     
    		// SECOND PANEL : CERCLE 
    		pan2 = new JPanel() {
    			public void paintComponent(Graphics g){
    				g.setColor(Color.blue);
    				g.fillOval(200, 50, 100, 100);
    				g.drawLine(250, 100, 250, 50);
    			}           
    		};
     
     
    		// SANS CES DEUX LIGNES, RIEN NE S'AFFICHE !
    //		pan.setBounds(50, 50, 600, 400) ;
    //		pan2.setBounds(200, 50, 400, 200) ;
    		pan.setBackground(Color.YELLOW) ;
    		pan2.setBackground(Color.CYAN) ;
    		lp = new JLayeredPane() ;
     
    		lp.add(pan2, new Integer(2)) ;
    		lp.add(pan, new Integer(1)) ;
    		pan2.setOpaque(!pan.isOpaque()) ; // OPPOSE DE LA VALEUR PAR DEFAUT -> RENDRE LE FOND TRANSPARENT
    		getContentPane().add(lp, BorderLayout.CENTER) ;
     
    	}
     
    	public static void main(String[] args) {
    		JFrame f = new totojava(); 
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }

  2. #2
    Membre du Club Avatar de arafat877
    Inscrit en
    Septembre 2010
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 46
    Points : 46
    Points
    46
    Par défaut Solution
    Salut !
    Si tu veux gérer la transparence dans tes composants, alors je te propose cet
    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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
     
    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Composite;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
     
    /**
     *
     * @author Arafat Bouchafra
     * @Date   4 déc. 2010
     * @Time   09:52:54
     */
     
    public class TransparencyExample extends JPanel {
      private static int gap=10, width=60, offset=20,
                         deltaX=gap+width+offset;
      private Rectangle
        blueSquare = new Rectangle(gap+offset, gap+offset, width, width),
        redSquare = new Rectangle(gap, gap, width, width);
     
      private AlphaComposite makeComposite(float alpha) {
        int type = AlphaComposite.SRC_OVER;
        return(AlphaComposite.getInstance(type, alpha));
      }
     
      private void drawSquares(Graphics2D g2d, float alpha) {
        Composite originalComposite = g2d.getComposite();
        g2d.setPaint(Color.blue);
        g2d.fill(blueSquare);
        g2d.setComposite(makeComposite(alpha));
        g2d.setPaint(Color.red);
        g2d.fill(redSquare);
        g2d.setComposite(originalComposite);
      }
     
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
        for(int i=0; i<11; i++) {
          drawSquares(g2d, i*0.1F);
          g2d.translate(deltaX, 0);
        }
      }
     
      public static void main(String[] args) {
     
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Transparence");
                frame.setSize(11*deltaX + 2*gap, deltaX + 3*gap);
                frame.setContentPane(new TransparencyExample());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
      }
    }
    Bon courage

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par arafat877 Voir le message
    Salut !
    Si tu veux gérer la transparence dans tes composants, alors je te propose cet
    exemple :

    ...
    Je te remercie pour cet exemple intéressant, je ne connaissais pas du tout ce "AlphaComposite". Cependant, ça ne répond à aucune de mes deux questions, et ça n'est pas du tout ce que je recherche.
    Si j'ai bien compris l'exemple que j'ai trouvé, le "setOpaque" sert (entre autres, et c'est ce qui m'intéresse ici) à rendre le background d'un panel "transparent" (non opaque), afin que l'on puisse superposer deux tels objets (sans aucun effet de transparence).
    Dans mon cas, j'ai deux JPanel à faire cohabiter au même endroit. L'idée, c'est qu'ensuite je manipule l'une des deux formes par l'intermédiaire de son JPanel conteneur (car j'avais compris qu'on ne pouvait pas manipuler des "graphics" (rectangle, cercle, etc.) directement. Mais peut-être n'ai-je pas bien compris ?...)

  4. #4
    Expert confirmé
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Points : 4 539
    Points
    4 539
    Par défaut
    Salut,

    Citation Envoyé par totojava Voir le message
    this.getWidth()
    this fait référence au primer panneau.


    Citation Envoyé par totojava Voir le message
    L'idée, c'est qu'ensuite je manipule l'une des deux formes par l'intermédiaire de son JPanel conteneur (car j'avais compris qu'on ne pouvait pas manipuler des "graphics" (rectangle, cercle, etc.) directement. Mais peut-être n'ai-je pas bien compris ?...)
    tu peux manipuler tes formes graphiques sans passer par une intermédiaire : tu fais clique souris sur le shape à manipuler et tu détermine par la suite l'objet correspondant(qui contient les informations sur la forme 2D dessinée) en parcourant le vecteur qui contient déjà l'ensemble des formes dessinées sur ton panneau

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par slim_java Voir le message
    Salut,



    this fait référence au primer panneau.




    tu peux manipuler tes formes graphiques sans passer par une intermédiaire : tu fais clique souris sur le shape à manipuler et tu détermine par la suite l'objet correspondant(qui contient les informations sur la forme 2D dessinée) en parcourant le vecteur qui contient déjà l'ensemble des formes dessinées sur ton panneau
    Merci pour ces infos, ça va dans mon sens. Par contre, je ne vois pas qui est le premier panneau dont tu parles ? Je précise ma question : lorsque je fait "this.getWidth" dans pan, je suis dans une classe interne anonyme, non ? Normalement, le this est celui de l'objet courant ? Quel est cet objet ?
    Et lorsque je fais le "this.getWidth" dans le constructeur totojava, pourquoi j'obtiens 0, i.e. une valeur différente du "this.getWidth" de pan ?
    Je souhaite bien comprendre ce point qui me paraît fondamental...

    Sinon, quelle est la méthode pour "abonner" un objet graphique (ici mon drawRect) à un évènement ? J'imagine qu'il faut passer par pan.g, mais je ne vois pas la démarche (et je n'ai rien lu à ce sujet dans les livres que j'ai lus).

    EDIT : Je viens de trouver des infos sur la classe Shape et le Graphics2D. Je vais poursuivre ma lecture, mais je suis toujours preneur d'informations qui me feront aller plus vite !

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    tu peux manipuler tes formes graphiques sans passer par une intermédiaire : tu fais clique souris sur le shape à manipuler et tu détermine par la suite l'objet correspondant(qui contient les informations sur la forme 2D dessinée) en parcourant le vecteur qui contient déjà l'ensemble des formes dessinées sur ton panneau
    Notamment, quelles sont les méthodes à utiliser pour avoir le "vecteur qui contient déjà l'ensemble des formes dessinées", et à quel objet s'appliquent-elles ? J'ai du mal à voir...

  7. #7
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    En patientant un peu, je pense qu'une nouvelle réponse te suggérera de modifier ton BIOS pour régler tes problèmes...

    La réponse la plus simple reste toutefois d'ajouter la ligne suivante à ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lp = new JLayeredPane();
    lp.setLayout(new OverlayLayout(lp)); // Cette ligne de code là.
    Ce LayoutManager n'est pas forcément le plus connu, mais il est très utilisé avec les JLayeredPane. Avec lui, c'est un peu comme si chaque composant se retrouvait au CENTER d'un BorderLayout avec un redimensionnement automatique à la taille de la fenêtre. Et c'est justement ce redimensionnement qui permet à pan.getWidth() de retourner une valeur non nulle. Au passage :
    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
    public class Outter {
     
    	public void f() {
    		System.out.println("Outter.f()");
    	}
     
    	public void g() {
    		System.out.println("Outter.g()");
    	}
     
    	public class Inner {
     
    		public void f() {
    			System.out.println("Inner.f()");
    		}
     
    		public void run() {
    			f();
    			this.f(); // Redondant.
    			Outter.this.f();
    			g();
    			// Inner.this.g(); --> Erreur de compilation.
    			Outter.this.g(); // Redondant.
    		}
    	}
     
    	public static void main(String[] arguments) {
    		Outter outter = new Outter();
    		outter.f();
     
    		Inner inner = outter.new Inner();
    		inner.f();
    		// inner.g(); --> Erreur de compilation.
    		inner.run();
    	}
    }
     
    /*
    Sortie du programme :
     
    Outter.f()
    Inner.f()
    Inner.f()
    Inner.f()
    Outter.f()
    Outter.g()
    Outter.g()
    */
    J'utilise une classe interne plutôt qu'une classe interne anonyme, mais le fonctionnement est le même.

  8. #8
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Accessoirement, il est aussi plus simple de faire ça :
    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
    @SuppressWarnings("serial")
    public class TotoJava2 extends JFrame {
     
    	public TotoJava2() {
    		setLayout(new BorderLayout());
     
    		add(new JPanel() {
    			@Override
    			protected void paintComponent(Graphics g) {
    				g.setColor(Color.black);
    				g.drawRect(100, 100, this.getWidth() - 150, 200);
     
    				g.setColor(Color.blue);
    				g.fillOval(200, 50, 100, 100);
    				g.drawLine(250, 100, 250, 50);
    			}
    		});
    	}
     
    	public static void main(String[] args) {
    		JFrame f = new TotoJava2();
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par Chatanga Voir le message
    Accessoirement, il est aussi plus simple de faire ça :
    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
    @SuppressWarnings("serial")
    public class TotoJava2 extends JFrame {
     
    	public TotoJava2() {
    		setLayout(new BorderLayout());
     
    		add(new JPanel() {
    			@Override
    			protected void paintComponent(Graphics g) {
    				g.setColor(Color.black);
    				g.drawRect(100, 100, this.getWidth() - 150, 200);
     
    				g.setColor(Color.blue);
    				g.fillOval(200, 50, 100, 100);
    				g.drawLine(250, 100, 250, 50);
    			}
    		});
    	}
     
    	public static void main(String[] args) {
    		JFrame f = new TotoJava2();
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }
    Merci pour ton aide, je ne connaissais pas non plus ce layout . Dans les livres, on ne dit pas tout, et la doc officielle sur internet est dense !!

    Par contre, pour ton exemple ci-dessus, effectivement, c'est plus simple, mais mon but est de pouvoir manipuler les formes géométriques indépendamment l'une de l'autre. Comment je fais pour accéder au rectangle (par exemple sélection par souris) avec cette méthode ?

  10. #10
    Expert confirmé
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Points : 4 539
    Points
    4 539
    Par défaut
    Salut,

    Citation Envoyé par totojava Voir le message
    Comment je fais pour accéder au rectangle (par exemple sélection par souris) avec cette méthode ?

    comme je t'ai dis, tu dois ajouter chaque forme 2D que tu viens de dessiner dans un vecteur, par la suite , lorsque tu clique sur une forme en vue de la modifier, tu dois chercher cette forme dans ton vecteur.
    Pour le faire, tu dois obtenir les coordonnées du Point clique_souris et tester à quelle forme elle appartient; cela est possible si tu utilise les classes implémentant l'interface Shape admettant la méthode contains() qui détermine si un point(x,y) appartient à une forme.
    A l'étape ou tu as déterminé cette forme dans ton vecteur, tu fais la modification correspondante; par exemple modifier sa largeur et sa hauteur...
    Enfin, rafraichir le dessin en parcourant ce vecteur dans la méthode paintConponent() et ajouter chaque forme enregistrée dedans.

  11. #11
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Citation Envoyé par totojava Voir le message
    Par contre, pour ton exemple ci-dessus, effectivement, c'est plus simple, mais mon but est de pouvoir manipuler les formes géométriques indépendamment l'une de l'autre. Comment je fais pour accéder au rectangle (par exemple sélection par souris) avec cette méthode ?.
    Un Graphics sert simplement à dessiner des pixels. Une méthode telle que drawRect ne crée en aucun cas un Shape qui serait mémorisé quelque part et qu'il serait possible de récupérer après coup. Si tu veux modifier ton rendu, tu dois toi-même gérer cet aspect là. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
     
    import javax.swing.JFrame;
    import javax.swing.JPanel;
     
    @SuppressWarnings("serial")
    public class TotoJava3 extends JFrame {
     
    	private static class InnerPanel extends JPanel {
     
    		private Point selectionStart, selectionEnd;
     
    		private MouseAdapter mouseAdapter = new MouseAdapter() {
     
    			@Override
    			public void mousePressed(MouseEvent event) {
    				selectionStart = event.getPoint();
    			}
     
    			@Override
    			public void mouseReleased(MouseEvent event) {
    				selectionStart = null;
    			}
    		};
     
    		private MouseMotionAdapter mouseMotionAdapter = new MouseMotionAdapter() {
     
    			@Override
    			public void mouseDragged(MouseEvent event) {
    				selectionEnd = event.getPoint();
    				repaint(); // <=> InnerPanel.this.repaint();
    			}
    		};
     
    		public InnerPanel() {
    			addMouseListener(mouseAdapter);
    			addMouseMotionListener(mouseMotionAdapter);
    		}
     
    		@Override
    		protected void paintComponent(Graphics g) {
    			Graphics2D g2d = (Graphics2D) g;
    			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    					RenderingHints.VALUE_ANTIALIAS_ON);
     
    			if (selectionStart != null && selectionEnd != null) {
    				g.setColor(getBackground());
    				g.fillRect(0, 0, getWidth(), getHeight());
     
    				int x = Math.min(selectionStart.x, selectionEnd.x);
    				int y = Math.min(selectionStart.y, selectionEnd.y);
    				int width = Math.abs(selectionEnd.x - selectionStart.x);
    				int height = Math.abs(selectionEnd.y - selectionStart.y);
     
    				g.setColor(Color.blue);
    				g.drawRect(x, y, width, height);
    			}
    		}
    	}
     
    	public TotoJava3() {
    		add(new InnerPanel());
    	}
     
    	public static void main(String[] args) {
    		JFrame f = new TotoJava3();
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }

  12. #12
    Expert confirmé
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Points : 4 539
    Points
    4 539
    Par défaut
    Citation Envoyé par Chatanga Voir le message
    Un Graphics sert simplement à dessiner des pixels. Une méthode telle que drawRect ne crée en aucun cas un Shape qui serait mémorisé quelque part et qu'il serait possible de récupérer après coup.
    dans mon post j'ai parlé de classe implémentant l'interface Shape, une simple documentation méen à utiliser les classes comme Rectangle2D , Ellipse2D ... et la méthode de dessin draw et non drawRect...

    donc merci de BIEN lire les réponses des autres !!

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par slim_java Voir le message
    dans mon post j'ai parlé de classe implémentant l'interface Shape, une simple documentation méen à utiliser les classes comme Rectangle2D , Ellipse2D ... et la méthode de dessin draw et non drawRect...

    donc merci de BIEN lire les réponses des autres !!
    Oui, oui, je pense que Chatanga répondait à ma question, et ne reprenait pas ton message. C'est MOI qui ne sait pas grand chose .

    En fait, je vois qu'il y a un peu deux écoles, celle de slim_java avec les objets Graphics2D, et celle de Chatanga.

    Je vais étudier tout cela pour voir si ça répond à mon problème, et je reviens dans pas longtemps...

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Alors me revoilà, avec un début de solution à mon problème, inspiré par le code de Chatanga, et l'idée de slim_java de reconnaître l'objet graphics sur lequel on clique.

    Toutefois, ça ne répond pas encore à ma question car :
    1) je n'arrive pas à effacer le cercle en le redessinant avec la couleur de fond ;
    2) j'ai un problème de "portée" de variables ou d'objets : je suis obligé de créer un nouveau "Ellipse2D" cercle2, car lorsque je laissais cercle, ça ne faisait rien !
    Or, le cercle = new Ellipse2D a pour coordonnées des variables xC, yC, etc. définies dans ma classe et que je peux changer... ?

    Voici le code :
    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
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
    import java.awt.geom.*;
     
     
    public class totojava extends JFrame {
     
    	private static class barre extends JPanel {
    		private Point selectionStart, selectionEnd;
    		private MouseAdapter mouseAdapter = new MouseAdapter() {
    			@Override
    			public void mousePressed(MouseEvent event) {
    				selectionStart = event.getPoint();
    			}
    			@Override
    			public void mouseReleased(MouseEvent event) {
    				selectionStart = null;
    				System.out.println("Fin du déplacement") ;
    			}
    		};
    		private MouseMotionAdapter mouseMotionAdapter = new MouseMotionAdapter() {
    			@Override
    			public void mouseDragged(MouseEvent event) {
    				selectionEnd = event.getPoint();
    				repaint(); // <=> InnerPanel.this.repaint();
    			}
    		};
     
    		public barre() {
    			addMouseListener(mouseAdapter);
    			addMouseMotionListener(mouseMotionAdapter);
    		}
     
    		@Override
    		protected void paintComponent(Graphics g) {
    			Graphics2D g2d = (Graphics2D) g;
    			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    					RenderingHints.VALUE_ANTIALIAS_ON);
     
    			int xC = 200 ;
    			int yC = 50 ;
    			int largC = 100 ;
    			int hautC = 100 ;
     
    			// DEBUT 
    			Graphics2D g2D = (Graphics2D) g ;
    			Rectangle2D rect = new Rectangle2D.Double(100, 100, this.getWidth()-150, 200) ;
    			g2D.setColor(Color.black);
    			g2D.draw(rect) ;
    			Ellipse2D cercle = new Ellipse2D.Double(xC, yC, largC, hautC) ;
    			g2D.setColor(Color.blue);
    			g2D.draw(cercle) ;
     
    			if (selectionStart != null && selectionEnd != null) {
    				if (cercle.contains(selectionStart)) {
    					g2D.setColor(getBackground());
    					g2D.draw(cercle) ;
    					xC = selectionEnd.x ;
    					Ellipse2D cercle2 = new Ellipse2D.Double(xC, yC, largC, hautC) ;
    					g.setColor(Color.black);
    					g2D.draw(rect) ;
    					g.setColor(Color.blue);
    					g2D.draw(cercle2) ;
    				}
    			}
    		}
    	}
     
    	public totojava() {
    		add(new barre());
    	}	
     
    	public static void main(String[] args) {
    		JFrame f = new totojava(); 
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);		
    	}
    }

  15. #15
    Expert confirmé
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Points : 4 539
    Points
    4 539
    Par défaut
    Salut,

    Citation Envoyé par totojava Voir le message

    Toutefois, ça ne répond pas encore à ma question car :
    1) je n'arrive pas à effacer le cercle en le redessinant avec la couleur de fond ;

    tu dois ajouter cette instruction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    super.paintComponent(g);
    dans la méthode paintComponent en premier lieu.


    Citation Envoyé par totojava Voir le message
    2) j'ai un problème de "portée" de variables ou d'objets : je suis obligé de créer un nouveau "Ellipse2D" cercle2, car lorsque je laissais cercle, ça ne faisait rien !
    Or, le cercle = new Ellipse2D a pour coordonnées des variables xC, yC, etc. définies dans ma classe et que je peux changer... ?
    j'ai pas suivi tout le code (Désolé), mais dans la méthode paintComponent(), tu dois utiliser un seul objet cercle pour lequel tu dois modifier les coordonnées X ou Y ou les deux, dans la méthode Mousedragged pour qu'il change de position.

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par slim_java Voir le message
    Salut,
    j'ai pas suivi tout le code (Désolé), mais dans la méthode paintComponent(), tu dois utiliser un seul objet cercle pour lequel tu dois modifier les coordonnées X ou Y ou les deux, dans la méthode Mousedragged pour qu'il change de position.
    C'est bien ce que je fais j'ai l'impression : dans paintComponent, je définis le cercle par l'intermédiaire d'une coordonnée xC, puis quand il y a eu déplacement, je fais xC = selectionEnd.x ; où selectionEnd est le point. Mais ça ne marchait pas si je ne définissais pas un second cercle dans cette portion de code... ?
    Par contre, je ne sais pas ce que le Mousedragged vient faire là. D'ailleurs, je ne sais pas ce que c'est que ce MouseAdapter. J'ai à peu près compris ce qu'est MouseListener, mais pas MouseAdapter. Quelqu'un pourrait m'expliquer brièvement ? Et me dire pourquoi il faut que je modifie quelque chose dans le MouseDragged ?

    Merci.

  17. #17
    Expert confirmé
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Points : 4 539
    Points
    4 539
    Par défaut
    Citation Envoyé par totojava Voir le message
    Et me dire pourquoi il faut que je modifie quelque chose dans le MouseDragged ?
    le code dans MouseDragged s'exécute quand tu clique sur le bouton gauche de la souris et tu fais un glissement sans relâcher.
    j'ai pensé que tu veux déplacer le cercle en faisant un dragg

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Citation Envoyé par slim_java Voir le message
    le code dans MouseDragged s'exécute quand tu clique sur le bouton gauche de la souris et tu fais un glissement sans relâcher.
    j'ai pensé que tu veux déplacer le cercle en faisant un dragg
    Oui ! C'est ça que je veux, mais mes connaissances en java/swing un peu limitées font que je m'exprime mal...

    Je résume où j'en suis, n'hésitez pas à me reprendre, c'est comme ça que j'apprends (et j'ai appris beaucoup ces dernières heures avec tous ces échanges ) :
    - je veux effectivement pouvoir bouger un objet graphique, mais je ne savais pas que c'était comme faire du drag & drop.
    - pourquoi dans le code chatanga que j'ai réutilisé, il n'y a rien dans le MouseDragged ? Je m'en suis inspiré car ça marchait bien pour dessiner le rectangle, avec comme stratégie : regarder le point où l'on commence, et regarder le point où l'on relache la souris. Pourquoi ça ne marche pas dans mon cas ? C'est parce que j'utilise deux objets ellipse ?

    Et deux questions complémentaires :
    - le "MouseAdapter", pourquoi ça n'est pas un Listener ? Je n'ai toujours pas compris.
    - pourquoi faut-il utiliser le super de paintComponent ?

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Rebonjour,
    Alors c'est presque OK !
    Voici le code qui fait ce que je veux, élaboré grâce aux conseils de tous ceux qui m'ont aidé :

    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
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
    import java.awt.geom.*;
    import java.lang.Math ;
     
     
    public class Totojava4 extends JFrame {
     
    	private boolean inCercle = false ;
    	private boolean depl = false ;
    	private int xC = 200 ;
    	private int xInit = xC ; 
    	private int yC = 50 ;
    	private int largC = 100 ;
    	private int hautC = 100 ;
     
    	private class barre extends JPanel {
    		private Point selectionStart;
    		private MouseAdapter mouseAdapter = new MouseAdapter() {
     
    			@Override
    			public void mousePressed(MouseEvent event) {
    				selectionStart = event.getPoint();
    				xInit = xC ;
    				System.out.println("Pressé et x = " + selectionStart.getX()) ;
    			}
     
    			@Override
    			public void mouseReleased(MouseEvent event) {
    				selectionStart = null;
    				inCercle = false ;
    				depl = false ;
    				System.out.println("Fin du déplacement") ;
    			}
    		};
     
    		private MouseMotionAdapter mouseMotionAdapter = new MouseMotionAdapter() {
    			@Override
    			public void mouseDragged(MouseEvent event) {
    				if (inCercle) {
    					xC = Math.max(0, (int) (xInit + (event.getX() - selectionStart.getX()))) ;
    					// xC = Math.min(???????.getWidth(), xC) ;  
    				}
    				repaint();
    			}
    		};
     
    		public barre() {
    			addMouseListener(mouseAdapter);
    			addMouseMotionListener(mouseMotionAdapter);
    		}
     
    		@Override
    		protected void paintComponent(Graphics g) {
    			super.paintComponent(g);
    			Graphics2D g2d = (Graphics2D) g;
    			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    					RenderingHints.VALUE_ANTIALIAS_ON);
     
    			Graphics2D g2D = (Graphics2D) g ;
    			Rectangle2D rect = new Rectangle2D.Double(100, 100, this.getWidth()-150, 200) ;
    			g2D.setColor(Color.black);
    			g2D.draw(rect) ;
    			Ellipse2D cercle = new Ellipse2D.Double(xC, yC, largC, hautC) ;
    			g2D.setColor(Color.blue);
    			g2D.draw(cercle) ;
     
    			if (selectionStart != null && !depl) { 
    				inCercle = cercle.contains(selectionStart) ;
    				depl = true ;
    			}
    		}
    	}
     
    	public Totojava4() {
    		add(new barre());
    	}	
     
    	public static void main(String[] args) {
    		JFrame f = new Totojava4(); 
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);		
    	}
    }
    Ca fait ce que je veux, mais j'ai encore un problème à régler, et finalement j'en reviens à mon premier post puisqu'il me manque le getWidth de la fenêtre principale !
    En effet, si je fais un mouvement de souris en dehors de la fenêtre, j'ai mon cercle qui suit, et donc disparaît et je le perds !!
    Je voudrais donc limiter le xC en max (après l'avoir limité en min par 0 par l'instruction précédente), mais il faut que j'ai accès à la taille de la fenêtre. Quelle méthode employer ? C'est ici que ça se passe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    xC = Math.max(0, (int) (xInit + (event.getX() - selectionStart.getX()))) ;
    // xC = Math.min(???????.getWidth(), xC) ;
    (Je me permets de préciser : quelque chose de simple et qui ne nécessite pas de changer le Bios, pour reprendre la philosophie d'un intervenant ...)

    Et n'hésitez pas à faire des commentaires sur le code, ça m'aide à progresser. Merci .

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 74
    Points : 40
    Points
    40
    Par défaut
    Bon, c'est encore moi ! (J'ai l'impression de monologuer depuis quelques temps )
    J'ai résolu mon dernier problème, mais j'ai toujours des questions en suspens...

    En effet, comme je l'ai indiqué, le this.getWidth() placé dans la méthode paintComponent renvoie exactement la largeur de la fenêtre TotoJava4 (qui étend JFrame). Par contre, le même this.getWidth() placé n'importe où ailleurs dans mes essais renvoie 0. Ca, je ne comprends pas pourquoi, ça reste mystérieux.
    Alors pour pouvoir utiliser la valeur de la largeur de la fenêtre, j'ai créé une variable private largeur en début de classe, et je change sa valeur dans le paintComponent...
    Tout marche !
    Je vais marquer RESOLU pour la discussion, mais je vais ouvrir une nouvelle discussion au sujet du this, après avoir fait quelques tests et relus quelques chapitres sur le sujet car je crois que je ne maîtrise pas tout .

    Merci !

    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
     
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseMotionAdapter;
    import java.awt.geom.*;
    import java.lang.Math ;
     
     
    public class Totojava4 extends JFrame {
     
    	private boolean inCercle = false ;
    	private boolean depl = false ;
    	private int xC = 200 ;
    	private int xInit = xC ; 
    	private int yC = 50 ;
    	private int largC = 100 ;
    	private int hautC = 100 ;
    	private int largeur ; 
     
    	private class barre extends JPanel {
    		private Point selectionStart;
     
    		private MouseAdapter mouseAdapter = new MouseAdapter() {
     
    			@Override
    			public void mousePressed(MouseEvent event) {
    				selectionStart = event.getPoint();
    				xInit = xC ;
    			}
     
    			@Override
    			public void mouseReleased(MouseEvent event) {
    				selectionStart = null;
    				inCercle = false ;
    				depl = false ;
    				System.out.println("Fin du déplacement") ;
    			}
    		};
     
    		private MouseMotionAdapter mouseMotionAdapter = new MouseMotionAdapter() {
    			@Override
    			public void mouseDragged(MouseEvent event) {
    				if (inCercle) {
    					xC = Math.max(0, (int) (xInit + (event.getX() - selectionStart.getX()))) ;
    					if (xC > largeur-largC) 
    						xC = largeur-largC ;  
    				}
    				repaint();
    			}
    		};
     
    		public barre() {
    			largeur =  this.getWidth() ;
    			addMouseListener(mouseAdapter);
    			addMouseMotionListener(mouseMotionAdapter);
    		}
     
    		@Override
    		protected void paintComponent(Graphics g) {
    //			System.out.println("Dans paint, this.getWidth() = " + this.getWidth()) ;
    			super.paintComponent(g);
    			Graphics2D g2d = (Graphics2D) g;
    			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    					RenderingHints.VALUE_ANTIALIAS_ON);
     
    			Graphics2D g2D = (Graphics2D) g ;
    			largeur = this.getWidth() ; // ICI !!!!!!!!!!!!!!!!
    			Rectangle2D rect = new Rectangle2D.Double(100, 100, largeur-200, 200) ;
    			g2D.setColor(Color.black);
    			g2D.draw(rect) ;
    			Ellipse2D cercle = new Ellipse2D.Double(xC, yC, largC, hautC) ;
    			g2D.setColor(Color.blue);
    			g2D.draw(cercle) ;
     
    			if (selectionStart != null && !depl) { 
    				inCercle = cercle.contains(selectionStart) ;
    				depl = true ;
    			}
    		}
    	}
     
    	public Totojava4() {
    		add(new barre());
    	}	
     
    	public static void main(String[] args) {
    		JFrame f = new Totojava4(); 
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setSize(800, 400);
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);		
    	}
    }

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

Discussions similaires

  1. [1.x] Plusieurs sites sur même hébergement
    Par nims dans le forum Symfony
    Réponses: 7
    Dernier message: 18/03/2009, 23h22
  2. dessiner sur un panel ou sur un picturebox
    Par olibara dans le forum C#
    Réponses: 12
    Dernier message: 13/06/2008, 23h24
  3. Plusieurs oracle sur même machine
    Par kheduch dans le forum Import/Export
    Réponses: 41
    Dernier message: 25/04/2008, 14h29
  4. Startup plusieurs database sur même serveur
    Par dumser1 dans le forum Administration
    Réponses: 5
    Dernier message: 06/09/2007, 09h40
  5. [JFrame] réafficher plusieurs fois un même panel à l'écran
    Par Monkeyget dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 01/04/2005, 14h29

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