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

Agents de placement/Fenêtres Java Discussion :

Problèmes de dessin de ligne dans une JFrame .


Sujet :

Agents de placement/Fenêtres Java

  1. #1
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut Problèmes de dessin de ligne dans une JFrame .
    Bonjour,

    plusieurs soucis avec l'utilisation des APIs Java de dessin 2D :
    - Le premier avec java.awt.Graphics.drawline :
    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
    class Test
    {
            private static void f()
            {
                    javax.swing.JFrame jf = new javax.swing.JFrame()
                    {
                            public void paint(java.awt.Graphics g)
                            {
                                    g.setColor(java.awt.Color.blue);
                                    g.drawLine(1,1,499,499);
                            }
                    };
     
                    jf.setSize(500,500);
                    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
                    jf.setVisible(true);
            }
     
            public static void main(String[] args)
            {
                    javax.swing.SwingUtilities.invokeLater(
                            new Runnable()
                            {
                                    public void run()
                                    {
                                            f();
                                    }
                            }
                    );
            }
    }
    La ligne est affichée mais décalée sur la droite (voir la miniature attachée) .

    Donc :
    1) Pourquoi ce décalage ?

    - Le deuxième problème avec java.awt.Graphics2D.draw :
    C'est le même code qu'avant sauf pour la méthode "paint" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void paint(java.awt.Graphics2D g)
    {
                 g.setPaint(java.awt.Color.blue);
                 g.draw(new java.awt.geom.Line2D.Double(1,1,499,499));
    }
    Là la ligne ne s'affiche même plus .

    2) Pourquoi la ligne ne s'affiche pas ?

    3) Quel composant utiliser pour dessiner des droites, et plus généralement pour faire des graphiques en 2D ?

    Merci .
    Images attachées Images attachées  

  2. #2
    Membre averti Avatar de Amine_sas
    Profil pro
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    245
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 245
    Points : 307
    Points
    307
    Par défaut
    Salut,
    Essaye de dessiner sur un JPanel au lieu de le faire directement sur la fenêtre (JFrame). Voici un 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
     
     
    class MyPanel extends JPanel{
     
     
    public void piantComponent(Graphics g){
          super.paintComponent(g);
          Graphics2D g2D = ( Graphics2D ) g;
           // instructions de dessin
          ......
     
    }
     
    }
    Pour ajouter le panel à la fenetre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    JPanel panel = new MyPanel();
    frame.getContentPane().add(panel);

  3. #3
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Merci de ta réponse .

    Avec un JPanel l'origine se trouve bien en haut à gauche et toutes les lignes sont bien affichées .
    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
    class Test
    {
            private static void f()
            {
                    javax.swing.JFrame jf = new javax.swing.JFrame();
     
                    jf.setSize(500,500);
                    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
     
                    javax.swing.JPanel jp = new javax.swing.JPanel()
                    {
                            public void paintComponent(java.awt.Graphics g)
                            {
                                    super.paintComponent(g);
                                    java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
                                    g2.setPaint(java.awt.Color.blue);
                                    g2.draw(new java.awt.geom.Line2D.Double(0,0,499,499));
                                    g2.draw(new java.awt.geom.Line2D.Double(499,0,499,499));
                            }
                    };
     
                    jf.getContentPane().add(jp);
     
                    jf.setVisible(true);
            }
     
            public static void main(String[] args)
            {
                    javax.swing.SwingUtilities.invokeLater(
                            new Runnable()
                            {
                                    public void run()
                                    {
                                            f();
                                    }
                            }
                    );
            }
    }
    En revanche la fenêtre initiale est plus petite que le JPanel, ce qui est normal à cause de la barre de titre et des bordures .

    Est-il possible de faire en sorte que la taille de la JFrame s'adapte à celle du JPanel ?

  4. #4
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 108
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    Par défaut
    le pack redimensionne au dimension preféré des composants.

  5. #5
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui à priori ça devrait fonctionner mais avec ce 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
    class Test
    {
            private static void f()
            {
                    javax.swing.JFrame jf = new javax.swing.JFrame();
     
                    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
     
                    javax.swing.JPanel jp = new javax.swing.JPanel()
                    {
                            public void paintComponent(java.awt.Graphics g)
                            {
                                    super.paintComponent(g);
                                    System.out.println("paintComponent");
                                    java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
                                    g2.setPaint(java.awt.Color.blue);
                                    g2.draw(new java.awt.geom.Line2D.Double(0,0,499,499));
                                    g2.draw(new java.awt.geom.Line2D.Double(499,0,499,499));
                            }
                    };
     
                    jp.setSize(500, 500);
     
                    jf.getContentPane().add(jp);
     
                    jf.pack();
                    jf.setVisible(true);
            }
     
            public static void main(String[] args)
            {
                    javax.swing.SwingUtilities.invokeLater(
                            new Runnable()
                            {
                                    public void run()
                                    {
                                            f();
                                    }
                            }
                    );
            }
    }
    la JFrame se retrouve avec une taille de 0x0 .

    Sinon est-il possible de "dessiner" les droites une fois puis laisser le composant les mettre à jour seul, sans avoir besoin de surcharger la méthode "paintComponent" ?

    Merci .

  6. #6
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 852
    Points : 22 869
    Points
    22 869
    Billets dans le blog
    51
    Par défaut
    la JFrame se retrouve avec une taille de 0x0
    Normal tu dois donner une taille preferree (setPreferredSize()) ou minimale (setMinimumSize()) a ton panel.

    Sinon est-il possible de "dessiner" les droites une fois puis laisser le composant les mettre à jour seul, sans avoir besoin de surcharger la méthode "paintComponent" ?
    Non, ceci est la methode correcte pour faire un rendu en Swing (tout comme la surcharge de paint() est la methode correcte pour un rendu en AWT). Tu peux cependant faire si tu veux un rendu offscreen ; c'est a dire peindre tes lignes dans une BufferedImage qui sera elle-meme peinte a l'ecran. Mais dans ce cas tu devras quand meme surcharger paintComponent() pour dessiner cette meme image a l'ecran. Cette methode utilise plus de memoire (cf l'image) mais la composition de l'image a l'ecran est plus rapide que le dessin des lignes separees donc c'est une bonne solution quand tu as enornement d'informations vectorielles a l'ecran. Et dans ce cas effectivement, tu dessines tes lignes un nombre minimal de fois (il est cependant conseille de les redessiner quand ton panel change de taille).

    La meilleures methodes consiste a modifier ta classe pour accepter le rendu des lignes sur un Graphics quelconque en fonction d'un flag.

    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
    public class MyRenderPanel extends JComponent {
      public static final String RENDER_METHOD_PROPERTY = "RenderMethod";
     
      public enum RenderMethod {
        ACTIVE, OFFSCREEN
      }
     
      private RenderMethod renderMethod = RenderMethod.ACTIVE;
     
      private BufferedImage image = null;
     
      /** Getter.
      * @see #setRenderMethod
      */
      public RenderMethod getRenderMethod() {
        return renderMethod;
      }
     
      /** Setter.
      * @see #getRenderMethod
      */
      public void setRenderMethod(RenderMethod value) {
        if (value == null) {
          value = RenderMethod.ACTIVE
        }
        RenderMethod oldValue = renderMethod;
        renderMethod  = value;
        firePropertyChange(RENDER_METHOD_PROPERTY, oldValue, value);
        if (value == RenderMethod.ACTIVE) {
          image = null;
        }
        repaint();
      }
     
    [...]
     
     /** Dessin personnalise.
      * @param graphics Surface de dessin independante de la sortir.
      * @param width Largeur de la surface de dessin.
      * @param height Hauteur de la surface de dessin.
      */
     private void renderDrawing(Graphics2D graphics, double width, double height) {
      [...]
      }
     
      /** {@inheritDoc}
       */
      @Override protected void paintComponent(Graphics graphics) {
        // Peinture par defaut du composant.
        super.paintComponent(graphics);
        // Calcul de la taille de la surface de dessin independament du Border du composant.
        Dimension size = getSize();
        Insets insets = getInsets();
        int width = size.width - (insets.left + insets.right);
        int height = size.height - (insets.top + insets.bottom);
        //Rendu.
        RenderMethod renderMethod = getRenderMethod();
        switch (renderMethod) {
          // Rendu dans une image.
          case OFFSCREEN: {
            // L'image est reinitialisee si la taille du composant a change.
            if ((image == null) || (width != image.getWidth() || (height != image.getHeight())) {
              // Taille d'image non-valide.
              if ((width <= 0) || (height <= 0)) {
                return;  
              }
              image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
              Graphics2D g2d = image.createGraphics();
              try {
                renderDrawing(g2d, width, height);
              }
              finally {
                g2d.dispose();
              }
            }
            g.drawImage(image, 0, 0, null);
          }
          break;
          // Dessin direct a l'ecran.
          case ACTIVE:
          default: {
            Graphics2D g2d = (Graphics2D)graphics.create(insets.left, insets.top, width, height);
            try {
              renderDrawing(g2d, width, height);
            }
            finally {
              g2d.dispose();
            }
        }
      }
    }

  7. #7
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    En effet ce code fonctionne correctement :
    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
    class Test
    {
            private static void f()
            {
                    javax.swing.JFrame jf = new javax.swing.JFrame();
     
                    jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
     
                    javax.swing.JPanel jp = new javax.swing.JPanel()
                    {
                            public void paintComponent(java.awt.Graphics g)
                            {
                                    super.paintComponent(g);
                                    System.out.println("paintComponent");
                                    java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;
                                    g2.setPaint(java.awt.Color.blue);
                                    g2.draw(new java.awt.geom.Line2D.Double(0,0,499,499));
                                    g2.draw(new java.awt.geom.Line2D.Double(499,0,499,499));
                            }
                    };
     
                    jp.setPreferredSize(new java.awt.Dimension(500, 500));
     
                    jf.getContentPane().add(jp);
     
                    jf.pack();
                    jf.setVisible(true);
            }
     
            public static void main(String[] args)
            {
                    javax.swing.SwingUtilities.invokeLater(
                            new Runnable()
                            {
                                    public void run()
                                    {
                                            f();
                                    }
                            }
                    );
            }
    }
    Merci à tous de vos réponses.

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

Discussions similaires

  1. Problème d'ajout de ligne dans une JFrame
    Par nrgumn dans le forum Débuter
    Réponses: 2
    Dernier message: 04/01/2012, 06h29
  2. Réponses: 1
    Dernier message: 23/06/2010, 09h17
  3. Problème de taille de ligne dans une DatagridView
    Par AlixNoyon dans le forum Windows Forms
    Réponses: 3
    Dernier message: 14/12/2009, 23h38
  4. Problème d'insertion de lignes dans une table MySql
    Par developppez dans le forum Windows Forms
    Réponses: 14
    Dernier message: 02/01/2009, 17h58
  5. [VBA-E] Problème pour insérer des lignes dans une feuille Excel
    Par skystef dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 16/04/2007, 14h13

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