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

2D Java Discussion :

Dessin de forme géométrique, problèmes d'incompréhension avec repaint() etc


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Par défaut Dessin de forme géométrique, problèmes d'incompréhension avec repaint() etc
    Salut à tous,

    Je fois développer un paintbrush like en Java pour un projet. A la base je connaissais un peu le java mais pas du tout les interfaces graphiques avec SWING/AWT etc. J'apprends donc sur le tas. Je travaille avec NetBeans 6.5 et je bloque sur le dessin de forme avec le drag'n drop de la souris.

    En fait mon programme est bateau à souhait puisqu'il doit permettre de dessiner des tracés à main levée, des rectangles, cercles, etc...

    En ce qui concerne le dessin à main levée je pense avoir réussi quoique il y encore des défauts dans ma manière de programmer que je n'arrive pas à éviter. Je vais expliquer au fur à mesure pourquoi je dis ca.

    Bon alors 1er, comme premier pas mon programme est capable de faire un dessin à main levée et des rectangles basiques (bordure noire, fond blanc).

    Pour cela j'utilise les événements liés à la souris (souris pressée, relâchée, draguée...). Mon problème est que, lorsque je veux dessiner un rectangle, celui ci s'affiche au fur et à mesure sur la zone de dessin (vous savez, tant que le bouton de la souris n'est pas relâché, on pré visualise le rectangle qui va être dessiné). Or avec le code fourni, il s'affiche bien lors des mouvements de souris en drag mais disparaît aussitôt que la souris devient immobile même si on garde le bouton enfoncé. C'est très frustrant. Je vous laisse jeter un coup d'œil à mon code pour ceux qui ont la patiente de m'aider.

    Je sais aussi que je m'y prends mal pour dessiner car je n'effectue pas tous les dessin dans paintComponent alors que c'est dit partout. Le fait inexpliqué pour moi est que le dessin est très lent si je procède de cette manière alors j'ai essayé de contourné la difficulté. J'ai aussi trouvé des exemples de paintBrush en Java mais ils ne m'aident plus à ce stade.

    Merci d'avance pour votre aide.

    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
     
    import java.awt.*;
    import java.util.Vector;
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    /*
     * Dessin.java
     *
     * Created on 5 janv. 2009, 11:04:53
     */
     
    /**
     *
     * @author x
     */
    public class Dessin extends javax.swing.JPanel {
     
        Vector figuresList;
        int figure;
        Point start;
     
     
        /** Creates new form Dessin */
        public Dessin() {
            initComponents();
            figuresList = new Vector();
            start = new Point();
     
        }
     
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            draw(g);
     
        }
     
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {
     
            setBackground(new java.awt.Color(255, 255, 255));
            addMouseListener(new java.awt.event.MouseAdapter() {
                public void mousePressed(java.awt.event.MouseEvent evt) {
                    formMousePressed(evt);
                }
                public void mouseReleased(java.awt.event.MouseEvent evt) {
                    formMouseReleased(evt);
                }
            });
            addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
                public void mouseDragged(java.awt.event.MouseEvent evt) {
                    formMouseDragged(evt);
                }
            });
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
            this.setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 400, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 300, Short.MAX_VALUE)
            );
        }// </editor-fold>
     
     
     
        private void formMouseDragged(java.awt.event.MouseEvent evt) {                                  
            // TODO add your handling code here:
     
            //dessin à main levée
            if (figure == 1){
                Trace t = (Trace)figuresList.lastElement();
                t.add(evt.getX(), evt.getY());
                t.draw(this.getGraphics());
            }
     
            //Rectangle à dessiner
            else if (figure == 2){
                repaint();
                draw(this.getGraphics());
                Rect r = new Rect(Color.BLACK,start.x, start.y,
                                 evt.getX(), evt.getY());
                r.draw(this.getGraphics());
                this.getGraphics().dispose();
            }
     
        }                                 
     
        private void formMousePressed(java.awt.event.MouseEvent evt) {                                  
            // TODO add your handling code here:
            if (figure == 1){
               figuresList.add(new Trace(Color.BLACK));
           }
     
           else if(figure == 2){
               start.x = evt.getX();
               start.y = evt.getY();
           }
     
        }                                 
     
        private void formMouseReleased(java.awt.event.MouseEvent evt) {
            // TODO add your handling code here:
            if(figure == 2){
                figuresList.add(new Rect(Color.BLACK,
                                start.x, start.y, evt.getX(), evt.getY() ));
                repaint();
            }
        }
     
        public void draw(Graphics g){
            Figure f;
    		for(int i = 0 ; i < figuresList.size() ; i++) {
                f = (Figure)figuresList.elementAt(i);
    			f.draw(g);
            }
        }
     
        // Variables declaration - do not modify
        // End of variables declaration
     
    }
     
    abstract class Figure {
    	abstract void draw(Graphics g);
    }
    /**
     *
     * @author x
     */
    class Trace extends Figure {
     
     
        Color c;
    	Vector pointsArray;
     
    	Trace(Color c) {
    		this.c = c;
    		pointsArray = new Vector();
    	}
     
    	void add(int x, int y) {
    		pointsArray.addElement(new Point(x , y));
    	}
     
     
    	Point elementAt(int n) {
    		if (pointsArray.capacity() < n) return null;
    		return (Point) pointsArray.elementAt(n);
    	}
     
    	int nbPoints() {
    		return pointsArray.size();
    	}
     
    	void draw(Graphics g) {
    		int n = nbPoints();
    		if(n <= 1) return;
     
    		g.setColor(c);
    		int x_last = elementAt(0).x;
    		int y_last = elementAt(0).y;
     
    		int x,y;
     
    		for(int i = 1 ; i < n ; i++) {
    			x = elementAt(i).x;
    			y = elementAt(i).y;
    			g.drawLine(x_last, y_last, x, y);
    			x_last = x;
    			y_last = y;
    		}
    	}
     
     
    }
     
     
    class Rect extends Figure{
     
        Color c;
    	Point p1, p2;
     
    	Rect(Color c, int x1, int y1, int x2, int y2) {
    		this.c = c;
    		p1 = new Point(x1, y1);
    		p2 = new Point(x2, y2);
    	}
     
     
        void draw(Graphics g) {
            int x, y, width, height;
            g.setColor(c);
            x = Math.min(p1.x, p2.x);
    		y = Math.min(p1.y, p2.y);
    		width = Math.abs(p1.x - p2.x);
    		height = Math.abs(p1.y - p2.y);
            g.drawRect(x, y, width, height);
        }
    }

  2. #2
    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
    Bonjour,

    Tout opération de dessin effectuée dans un composant Swing doit se réaliser à l'intérieur de la méthode paintComponent. La méthode getGraphics qure tu utilises à l'heure actuelle ne doit pas être utilisée à ces fins.

    Donc grosso modo, il faut que tu prépares ta collection de figure dans tes listeners, puis que tu appelles la méthode repaint. La méthode répaint appellera par la suite la méthode paintComponent (c'est le comportement standard de Swing, pas besoin de surcharger la méthode repaint). Dans la méthode paintComponent et compmences par dessiner toutes les formes contenues dans ta collection, puis tu dessines suivant le cas, la forme que l'utilisateur est en train de composer. A noter qu'il faut bien redessiner toutes les formes à chaque appel de paintComponent.

  3. #3
    Membre habitué
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Par défaut
    Bonjour,

    Tout opération de dessin effectuée dans un composant Swing doit se réaliser à l'intérieur de la méthode paintComponent. La méthode getGraphics qure tu utilises à l'heure actuelle ne doit pas être utilisée à ces fins.

    Donc grosso modo, il faut que tu prépares ta collection de figure dans tes listeners, puis que tu appelles la méthode repaint. La méthode répaint appellera par la suite la méthode paintComponent (c'est le comportement standard de Swing, pas besoin de surcharger la méthode repaint). Dans la méthode paintComponent et compmences par dessiner toutes les formes contenues dans ta collection, puis tu dessines suivant le cas, la forme que l'utilisateur est en train de composer. A noter qu'il faut bien redessiner toutes les formes à chaque appel de paintComponent.

    Merci d'avoir répondu. Malheureusement j'ai déjà procédé de cette manière : toutes mes figures à dessiner étaient enregistrées dans un object Vector. Le dessin s'effectuait alors exclusivement dans paintComponent. Cela fonctionnait mais demeurait très lent à l'affichage et prenait bcp de ressources : le processeur à 100% pour un logiciel de dessin basique c'est pas recommandable...donc voilà même si tout le monde recommande de dessiner uniquement dans paintComponent, je n'ai pas trouvé d'autres solutions que d'utiliser directement le Graphics du panel ailleurs. J'ai finalement abouti à mes fins en utilisant la propriété setXORmode avec la couleur de fond de mon panel.

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 904
    Billets dans le blog
    54
    Par défaut
    Ta maniere de dessiner n'est pas correcte et ce n'est pas parce que cela fonctionne sur ta machine que cela fonctionnera forcement ailleurs.

    Si ton rendu etait trop lent initialement c'est probablement car tu devais dessiner bien trop de choses sans tenir compte de la zone de clip positionnee sur le Graphics passe en parametre de paintComponent() et/ou de l'ordonancement de tes formes. De meme il faut appeler la version de repaint() qui prend en parametre les coordonnees de la zone a repeindre plutot que le repaint() global.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    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
    L'autre solution étant de dessiner sur une image et de n'avoir que lk'image à dessiner sur ton composant dans le paintComponent.

    Toutefois, ton histoire de 100% proc est très louche afficher des formes basiques comme celles que tu dessines ne doit pas mettre le proc sur les genous normalement

  6. #6
    Membre habitué
    Inscrit en
    Décembre 2008
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 10
    Par défaut
    Ta maniere de dessiner n'est pas correcte et ce n'est pas parce que cela fonctionne sur ta machine que cela fonctionnera forcement ailleurs.

    Si ton rendu etait trop lent initialement c'est probablement car tu devais dessiner bien trop de choses sans tenir compte de la zone de clip positionnee sur le Graphics passe en parametre de paintComponent() et/ou de l'ordonancement de tes formes. De meme il faut appeler la version de repaint() qui prend en parametre les coordonnees de la zone a repeindre plutot que le repaint() global.
    Eh bien je sais tout ca, et c'est justement ce qui me frustre car qq chose m'échappe. Pour ce qui est de la zone de clip, je ne vois pas en quoi c'a m'est utile car à chaque fois que je vais appeler repaint(). Tout mon dessin va être effacé et donc du coup il faut veiller à tout redessiner. Sachant que c'est une application paint, l'utilisateur peut potentiellement dessiner partout dans la zone de dessin et donc restreindre la zone de clip n'a pas de sens?

    L'autre solution étant de dessiner sur une image et de n'avoir que lk'image à dessiner sur ton composant dans le paintComponent.

    Toutefois, ton histoire de 100% proc est très louche afficher des formes basiques comme celles que tu dessines ne doit pas mettre le proc sur les genous normalement
    Ben c'est bien ce qui me chagrine mais je ne trouve pas comment eviter ce problème, je sais que j'utilise mal l'api de dessin mais je dois rendre le projet bientot et croyez moi j'ai déjà cherché en vain de n'utiliser que la surcharge de paintComponent pour mon dessin mais c trop lent...et je ne sais pas pk.

Discussions similaires

  1. problème d'incompréhension avec les jointures
    Par healou dans le forum Requêtes
    Réponses: 15
    Dernier message: 08/06/2011, 11h32
  2. Réponses: 2
    Dernier message: 14/02/2009, 14h07
  3. Dessiner des formes géométriques 2D et 3D
    Par whitespirit dans le forum C++Builder
    Réponses: 14
    Dernier message: 21/01/2008, 09h09
  4. [Forms]sérieux problème avec forms
    Par med_anis_dk dans le forum Forms
    Réponses: 6
    Dernier message: 21/05/2006, 00h14
  5. Réponses: 7
    Dernier message: 19/10/2004, 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