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 :

Probleme pour dessiner


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 60
    Par défaut Probleme pour dessiner
    Salut,

    Je me suis mis a Swing depuis hier . J'essai de faire un tableau blanc et j'ai un probleme curieux : Lorsque je dessine un point par exemple, ou une ligne, le tracé apparait une quinzaine de pixels au dessus du curseur de la souris ! Je n'arrive pas trouver d'ou cela vient ..

    Et tant que j'y suis j'ai des doutes quant à la conception. Bon je me suis documenté sur les listeners que j'apprend également à utiliser et voila mon souci :

    J'ai d'une part des boutons 'crayon', 'rectangle' etc qui sont JToggleButton et d'autre part un MouseListener et MouseMotionListener sur un JPanel, sur lequel on pourra dessiner. J'ai commencé a coder de la maniere suivante : Dans le cas ou je veux dessiner une ligne, dans la fonction mouseDragged je teste si le bouton "Ligne" est enfoncé, si c'est le cas j'appelle la fonction drawLine(). Ca marche mais j'imagine que c'est pas tres optimal.

    Pouvez-vous me conseiller une méthode ? Je laisse mon code, ca sera plus simple à comprendre (ou pas )

    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
    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
    package whiteboard;
     
    import  javax.swing.*;
    import  java.awt.*;
    import  java.awt.event.*;
     
    public class whiteboard extends JFrame {
        private JToggleButton buttonPen, buttonLine, buttonRectangle, buttonCircle, buttonText;  //les boutons
        protected ButtonGroup group;
        protected int lastX=0, lastY=0;
     
        /** Constructeur de test */
        public whiteboard() {
            //titre de la fenetre
            super("SIP Whiteboard");
            this.setSize(new Dimension(640,480));
            this.setResizable(false);
     
            // Container
            Container content = getContentPane();
            content.setBackground(Color.lightGray);
     
            // Panels
            JPanel controlArea = new JPanel(new GridLayout(8,2,0,8));
            JPanel drawArea = new JPanel();
     
            controlArea.setPreferredSize(new Dimension(100,200));
            drawArea.setBackground(Color.WHITE);
            drawArea.setPreferredSize(new Dimension(540,0));
     
            drawArea.addMouseListener(new PositionRecorder());
            drawArea.addMouseMotionListener(new Drawer());
     
            content.add(controlArea,BorderLayout.EAST);
            content.add(drawArea,BorderLayout.WEST);
     
            // Boutons
            buttonPen = new JToggleButton("Stylo",true);       
            buttonLine = new JToggleButton("Ligne");        
            buttonRectangle = new JToggleButton("Rectangle");    
            buttonCircle = new JToggleButton("Cercle");
            buttonText = new JToggleButton("Texte");
     
     
            buttonPen.addActionListener(new TraitementbuttonPen());
            buttonLine.addActionListener(new TraitementbuttonLine());
            buttonRectangle.addActionListener(new TraitementbuttonLine());
            buttonCircle.addActionListener(new TraitementbuttonLine());
            buttonText.addActionListener(new TraitementbuttonLine());
     
            // Groupes les boutons
            group = new ButtonGroup();
            group.add(buttonPen);
            group.add(buttonLine);
            group.add(buttonRectangle);
            group.add(buttonCircle);
            group.add(buttonText);
     
            // Les ajouter au JPanel
            controlArea.add(buttonPen);
            controlArea.add(buttonLine);
            controlArea.add(buttonRectangle);
            controlArea.add(buttonCircle);
            controlArea.add(buttonText);
     
            //
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
            //pack(); //permet de mettre une bonne dimension a la fenetre
            setVisible(true);
        }
     
        public static void main(String args[]) {
            new whiteboard();
        }
     
     
        public class TraitementbuttonPen implements ActionListener {
            public void actionPerformed(ActionEvent e){
                System.out.println("Ici !");            
            }
        }
     
         public class TraitementbuttonLine implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                System.out.println("2eme !");
            }
        }
     
        private class PositionRecorder extends MouseAdapter {
            public void mouseEntered(MouseEvent event) {
                requestFocus(); 
                record(event.getX(), event.getY());
                System.out.println(event.getX() + " " + event.getY());
            }
     
            public void mousePressed(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
                record(x, y);
            }
     
            public void mouseClicked(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
     
                if (buttonPen.isSelected() == true){
                    Graphics g = getGraphics();
                    g.drawLine(x, y, x, y);
                } 
                System.out.println(event.getX() + " " + event.getY());
            }
        }
     
         protected void record(int x, int y) {
                lastX = x;
                lastY = y;
         }
     
        private class Drawer extends MouseMotionAdapter {
            public void mouseDragged(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
                //System.out.println(x + " " + y);
                if (buttonPen.isSelected() == true){
                    Graphics g = getGraphics();
                    g.drawLine(lastX, lastY, x, y);
                    record(x, y);
                } 
            }
        }
    }
    edit : oublié le code

  2. #2
    Membre confirmé Avatar de kayzra
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Par défaut

  3. #3
    Membre expérimenté Avatar de jibbi
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 165
    Par défaut
    Bonjour,


    voici ton erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private class Drawer extends MouseMotionAdapter {
            public void mouseDragged(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
                //System.out.println(x + " " + y);
                if (buttonPen.isSelected() == true){
                    Graphics g = getGraphics();
                    g.drawLine(lastX, lastY, x, y);
                    record(x, y);
                } 
            }
        }
    tu utilise le graphics du JFrame alors que
    Cet evenement est ajouté à drawArea:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    drawArea.addMouseMotionListener(new Drawer());
    Ca donne décalage car le graphics du Frame comprend la bordure où est placé le titre de la fenêtre.

    Faut utiliser le graphics de la source de l'evenement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private class Drawer extends MouseMotionAdapter {
            public void mouseDragged(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
                //System.out.println(x + " " + y);
                if (buttonPen.isSelected() == true){
                    Graphics g = ((Component)event.getSource()).getGraphics();
                    g.drawLine(lastX, lastY, x, y);
                    record(x, y);
                } 
            }
        }
    Citation Envoyé par DrTank
    Ca marche mais j'imagine que c'est pas tres optimal.
    Ton code est bien, clair surtout
    On peut améliorer quelque points.

    Les points sont dessinés directement sur le graphics du composant, rien ne les garde en mémoire. Si le frame perd le focus, tout disparait
    trois solutions possible pour corriger ce problème:
    1- Dessiner dans le graphique d'une image que l'on cré en buffer.
    2- Dessiner dans un object GeneralPath // une Classe a connaître absolument :o)
    3- Combinaison de 1 et 2


    La solution 1 est plus facile et plus rapide à coder, mais la 3 permet beaucoup plus de possiblité.

    Pour créer un graphics à partir d'une image, solution 1
    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
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
     
     
    import  javax.swing.*;
    import  java.awt.*;
    import  java.awt.event.*;
    import  java.awt.image.BufferedImage;
     
    public class whiteboard extends JFrame {
        private JToggleButton buttonPen, buttonLine, buttonRectangle, buttonCircle, buttonText;  //les boutons
        private JButton buttonEffacer, buttonColor;
        protected ButtonGroup group;
        protected int lastX=0, lastY=0;
        protected DrawingPane drawArea;
     
        /** Constructeur de test */
        public whiteboard() {
            //titre de la fenetre
            super("SIP Whiteboard");
            this.setSize(new Dimension(640,480));
            this.setResizable(false);
     
            // Container
            Container content = getContentPane();
            content.setBackground(Color.lightGray);
     
            // Panels
            JPanel controlArea = new JPanel(new GridLayout(8,2,0,8));
            drawArea = new DrawingPane(540, 550);
     
            controlArea.setPreferredSize(new Dimension(100,200));
            drawArea.setBackground(Color.WHITE);
            drawArea.setPreferredSize(new Dimension(540,0));
     
            drawArea.addMouseListener(new PositionRecorder());
            drawArea.addMouseMotionListener(new Drawer());
     
            content.add(controlArea,BorderLayout.EAST);
            content.add(drawArea,BorderLayout.WEST);
     
     
            // Boutons
            buttonPen = new JToggleButton("Stylo",true);       
            buttonLine = new JToggleButton("Ligne");        
            buttonRectangle = new JToggleButton("Rectangle");    
            buttonCircle = new JToggleButton("Cercle");
            buttonText = new JToggleButton("Texte");
            buttonEffacer = new JButton("Effacer");
            buttonColor = new JButton("Couleur");        
     
     		// listener
            buttonPen.addActionListener(new TraitementbuttonPen());
            buttonLine.addActionListener(new TraitementbuttonLine());
            buttonRectangle.addActionListener(new TraitementbuttonLine());
            buttonCircle.addActionListener(new TraitementbuttonLine());
            buttonText.addActionListener(new TraitementbuttonLine());
            buttonEffacer.addActionListener(new ActionListener(){
            	public void actionPerformed(ActionEvent e){
            		drawArea.clear();
            		drawArea.repaint();        		
            	}
            });
     
            buttonColor.addActionListener(new ActionListener(){
            	public void actionPerformed(ActionEvent e){
            		Color newColor = JColorChooser.showDialog(
                         null,
                         "Choisir la couleur du trait",
                         drawArea.getBackground());                     
                    if (newColor != null) {                
                    	drawArea.setColor(newColor);     
                    	buttonColor.setBackground(newColor);
                    }
            	}
           	});
     
     
     
            // Groupes les boutons
            group = new ButtonGroup();
            group.add(buttonPen);
            group.add(buttonLine);
            group.add(buttonRectangle);
            group.add(buttonCircle);
            group.add(buttonText);
     
            // Les ajouter au JPanel
            controlArea.add(buttonPen);
            controlArea.add(buttonLine);
            controlArea.add(buttonRectangle);
            controlArea.add(buttonCircle);
            controlArea.add(buttonText);
            controlArea.add(buttonEffacer);
            controlArea.add(buttonColor);
     
            //
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
            //pack(); //permet de mettre une bonne dimension a la fenetre
            setVisible(true);
        }
     
     
    		class DrawingPane extends JPanel{
    			protected BufferedImage image;
    			protected Color back = Color.white;
    			public Graphics2D g2;
     
    			public DrawingPane(int w, int h){
    				image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    				g2 = image.createGraphics();
    				clear();
    				setColor(Color.black);				
    				addMouseMotionListener(new MouseMotionAdapter(){
    					public void mouseDragged(MouseEvent me){						
    						repaint();						
    					}
    				});
    				addMouseListener(new MouseAdapter(){
    					public void mousePressed(MouseEvent me){						
    						repaint();						
    					}
     
    				});
    			}			
     
     
     
    			protected void paintComponent(Graphics g){ 	// override
    					super.paintComponent(g);
    			     g.drawImage(image, 0, 0, this);			// affiche l'image dessiné
    			}			
     
    			public void setBackground(Color cl){ // override
    				back = cl;
    				super.setBackground(cl);				
    			}			
     
    			public void clear(){
    				 Color temp = g2.getColor(); 
    				 g2.setColor(back);
    			     g2.fill(new Rectangle(0, 0, image.getWidth(), image.getHeight()));
    			     g2.setColor(temp);
    			}
     
    			public void setColor(Color cl){
    			    g2.setColor(cl);
    			}
    		}
     
     
     
     
     
        public static void main(String args[]) {
            new whiteboard();
        }
     
     
        public class TraitementbuttonPen implements ActionListener {
            public void actionPerformed(ActionEvent e){
                System.out.println("Ici !");            
            }
        }
     
         public class TraitementbuttonLine implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                System.out.println("2eme !");
            }
        }
     
        private class PositionRecorder extends MouseAdapter {
            public void mouseEntered(MouseEvent event) {
                requestFocus(); 
                record(event.getX(), event.getY());
                System.out.println(event.getX() + " " + event.getY());
            }
     
            public void mousePressed(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
                record(x, y);
            }
     
            public void mouseClicked(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();
     
                if (buttonPen.isSelected() == true){                
                    drawArea.g2.drawLine(x, y, x, y);
                } 
                System.out.println(event.getX() + " " + event.getY());
            }
        }
     
         protected void record(int x, int y) {
                lastX = x;
                lastY = y;
         }
     
     
     
        private class Drawer extends MouseMotionAdapter {
            public void mouseDragged(MouseEvent event) {
                int x = event.getX();
                int y = event.getY();            
                if (buttonPen.isSelected() == true){
                	System.out.println(x + " " + y);
                    drawArea.g2.drawLine(lastX, lastY, x, y);
                    record(x, y);
                } 
            }
        }
    }

  4. #4
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    J'ai une seule chose à dire: les manipulations sur les graphics de composants doivent être réalisé dans la méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected void paintComponent(Graphics g)

    En effet si tu fais celà en dehors, tes modifs pourront s'effacer sans que tu le comprenne à n'importe quel moment (normalement au prochain appel à la méthode repaint() du composant sur lequel tu dessine) sans que tu puisse y faire quoi que ce soit.

    Dans ton cas le mieux est d'avoir une collection(une ArrayList par exemple) qui stocke les diverses formes à afficher et de parcourrir cette collection dans le paintComponent et de dessiner chaque élément.

    Ensuite tes listener te servent juste à ajouter des formes à la collection et à demander le repaint du composant....

    Tu auras déjà quelquechose de plus viable..

    Sinon l'autre solution serait de dessiner sur une image et de recharger cette image dans le panel à chaque modification. Mais ça rique d'être bien foireux à mettre en place...

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 60
    Par défaut
    Bon alors je me suis inspiré de vos méthodes, j'ai donc créé le GeneralPath pour les lignes a main levé, créé une ArrayList pour stocker tous les objets et surchargé la méthode paintComponent pour parcourir et afficher les objets de l'ArrayList.

    Bon, le probleme etant que tout est effacé lorsqu'une fenetre se trouve devant, comment dire d'appeler la méthode paintComponent lorsqu'une fenetre passe devant ?

    J'ai impémenté l'interface WindowFocusListener et surchargé les 2 méthodes windowGainedFocus et windowLostFocus

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        public void windowGainedFocus(WindowEvent e){
            paintComponent(drawArea.getGraphics());
        }
     
        public void windowLostFocus(WindowEvent e){
            paintComponent(drawArea.getGraphics());
        }
    drawArea etant le JPanel dans lequel on dessine. Est ce que ca vous semble cohérent ? Parceque ca ne marche pas.

  6. #6
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Il ne faut pas appeler paintComponent directement mais la méthode repaint();

  7. #7
    Membre confirmé
    Inscrit en
    Janvier 2004
    Messages
    60
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 60
    Par défaut
    Citation Envoyé par sinok
    Il ne faut pas appeler paintComponent directement mais la méthode repaint();
    Ca ne marche pas.

    Peut etre ma méthode paintComponent qui pose probleme ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    protected void paintComponent(Graphics g){
     
             Graphics2D g2 = (Graphics2D) g;
     
             int i;
             for (i=0;i<tab.size();i++){
                 System.out.println(tab.get(i));
                 Object a = tab.get(i);
                 g2.draw((Shape)a);
             }
         }

  8. #8
    Membre expérimenté Avatar de jibbi
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 165
    Par défaut
    Citation Envoyé par DrTank
    Ca ne marche pas.

    Peut etre ma méthode paintComponent qui pose probleme ?
    En effet, il faut appeler la méthode de la classe mère avant tout:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    protected void paintComponent(Graphics g){
             super.paintComponent(g); 
            Graphics2D g2 = (Graphics2D) g;
    
             int i;
             for (i=0;i<tab.size();i++){
                 System.out.println(tab.get(i));
                 Object a = tab.get(i);
                 g2.draw((Shape)a);
             }
         }

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

Discussions similaires

  1. petit probleme pour dessiner un tableau
    Par fleurrouge dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 28/12/2012, 11h22
  2. [débutant]probleme pour dessiner des shapes
    Par pingoui dans le forum 2D
    Réponses: 8
    Dernier message: 27/08/2007, 20h44
  3. probleme pour dessiner
    Par jayjay.f dans le forum AWT/Swing
    Réponses: 12
    Dernier message: 21/03/2007, 22h08
  4. probleme pour dessiner dans un JPanel
    Par L4BiN dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 02/08/2006, 15h01
  5. [debutant] Probleme pour dessiner un simple cube
    Par scorpiwolf dans le forum DirectX
    Réponses: 6
    Dernier message: 02/07/2003, 20h29

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