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 :

Insérer une image dans un Graphics déjà exisant ?


Sujet :

AWT/Swing Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2015
    Messages : 24
    Points : 19
    Points
    19
    Par défaut Insérer une image dans un Graphics déjà exisant ?
    Bonsoir,


    J'ai un problème pour insérer des images dans un Graphics de JPanel.

    En fait j'ai fait une classe Frame extends JFrame, qui crée une fenêtre basique avec un JPanel :
    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
     
     
    public class Frame extends JFrame {
     
    private Panel pan = new Panel ();
    private Image background = new IconImage( "image2.png" ).getImage(); // l'image de fond de la fenêtre
     
    public Frame () {
     
    // Création fenêtre :
    this.setSize( .......
    .......
     
    // Panel :
    this.setContentPane( pan );
    this.setVisible(true):
    pan.setBackGround( image2 ); // méthode de la classe Panel
     
    }
     
    }
    Puis je crée une classe Panel extends JPanel de cette façon :

    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
     
     
    public class Panel extends JPanel {
     
    @Override
    public void paintComponent( Graphics g ) {
    g.drawImage( new IconImage( "image1.png" ).getImage() , 0 , 0 , this.getWigth() , this.getHeight() , null )
    }
     
    // Pour changer le background
    public void set backGround( Image image ) {
    Graphics g = this.getGraphics() ; // On récupère le Graphics
    g.drawImage( image , 0 , 0 , this.getWigth() , this.getHeight() , null ) );
    }
     
    }
    Voilà c'est gros ce que j'ai mis ( j'ai recopié le code de mémoire il y a surement des petites erreurs ).

    Mon objectif est de créer un Jpanel avec une image de fond image1, puis d'y insérer image2 dans le même Graphics.
    Seulement, bien que le code compile et s’exécute, l'image2 n'est jamais affiché dans ma fenêtre.

    Voilà je suis un peu perdu, je ne sais pas comment faire pour que l'image2 soit insérer dans le Graphics. J'ai essayé de faire des paint(), repaint(), paintAll(), validate(), revalidate() un peu partout mais sans succès.

    Quelqu'un a une solution ?

    Par contre je ne peux pas recréer une autre fenêtre, car mon objectif est d'y insérer des sprites dans la fenêtre par la suite.

    Et si vous trouvez que mon code est sale ou bizarre, n'hésitez pas à le me faire remarquer
    Je ne maîtrise encore pas du tout les interfaces graphiques en swing et awt, donc je suis ouvert à toutes les suggestions permettant de m'améliorer.

    Voilà merci d'avance

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

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    On ne procède pas comme ça avec l'instance de Graphics :

    • Elle est volatile : elle n'est utilisée qu'à un moment précis du processus Swing. Toute intervention en dehors du processus Swing ne peut que fonctionner aléatoirement ou ne pas fonctionner.
    • Elle est recyclée : elle est utilisée par Swing pour rendre l'affichage de plusieurs composants. Au mieux, tu risques de dessiner dans le mauvais composant.


    Deuxièmement, on évite de faire du code long dans les méthodes exécutées dans le thread graphique (Event Dispatch Thread), pour éviter de bloquer trop longtemps l'UI (affichage comme interaction). Charger des images depuis le disque est une opération relativement longue. En particulier, on évite de le faire plusieurs fois (la méthode paintComponent va être appelée à chaque fois que Swing estime que cela est nécessaire, donc potentiellement plusieurs fois).

    voilà comment tu devrais procéder
    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
    public class Panel extends JPanel {
     
       private Image image = new IconImage( "image1.png" );
     
       @Override
       protected void paintComponent( Graphics g ) { 
          if ( image!=null ) {
              g.drawImage( image, 0 , 0 , this.getWigth() , this.getHeight() , this )
          }
       }
     
       // Pour changer le background
       public void setBackGround( Image image ) {
         this.image=image;
         repaint();
      }
     
    }

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2015
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Ok merci beaucoup, je vais tester cet aprem

    Par contre maintenant j'aimerais insérer une image de petite taille dans ma fenêtre, mais après que ma fenêtre à été crée ( par exemple dès que l’utilisateur à réalisé une certaine action, l'image s'affiche à un endroit précis de la fenêtre ).

    Dans ma classe Panel j'avais rajouté une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void addImage( Image image , int x , int y , int tx , int ty ) {
     
    Graphics g = this.getGraphics();
    g.drawImage( image , x , y , tx , ty , this );
     
    }
    Mais comme pour le background ça ne marchait pas.


    Suite à ta réponse, j'avais pensé à procéder de la sorte :
    - Je crée une liste d'image en attributs non initialisé.
    - Je crée aussi les listes pour les x, y, tx, et ty (position et taille)
    - Je les dessine toutes dans le paintComponent (comme les images ne sont pas initialisé, j'espère que ça ne va rien faire pour le moment)
    - Puis dès je veux tracer une image, j'appelle addImage qui va 1) créer l'image 2) la mettre dans la liste 3) et faire un repaint

    Voilà je ne sais pas si cela marche ou si c'est propre de faire ça ( je le redit je ne maîtrise pas du tout les interfaces graphiques ).

    Merci ^^

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

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Oui, c'est ça l'idée. Tu peux utiliser soit une liste de Rectangle, plutôt que de gérer 4 listes pour les coordonnées, ou créer une classe, et ne faire qu'une seule liste. Il faut faire surtout attention à la problématique de conflits sur la (ou les listes) entre threads (le thread applicatif et le thread Swing), puisqu'elles pourront être parcourue d'une part pour dessiner, et d'autre part pour y ajouter une nouvelle image.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    public class Panel extends JPanel {
     
       private Image image = new IconImage( "image1.png" );
       private final List<LocatedImage> images = new ArrayList<>();
     
       @Override
       protected void paintComponent( Graphics g ) { 
          if ( image!=null ) {
              g.drawImage( image, 0 , 0 , this.getWigth() , this.getHeight() , this )
          }
          for(LocatedImage locImage : images) {
              locImage.drawImage(g);
          }
       }
     
       // Pour changer le background
       public void setBackGround( Image image ) {
         this.image=image;
         repaint();
      }
     
      public void addImage(Image image, int x, int y, int width, int height) { 
           SwingUtilities.invokeLater(()-> addImage(new LocatedImage(image,x,y,width,height))); // on exécute l'ajout sur l'Event Dispatch Thread pour éviter les conflits de manipulation de la liste
      }
     
        // ne doit être exécutée que dans l'EDT
       private void addImage( LocatedImage image ) {
         this.images.add(image);
         repaint();
      }
     
     
      private class LocatedImage {
           private int x;
           private int y;
           private int width;
           private int height;
           private Image image;
           public LocatedImage(Image image, int x, int y, int width, int height) {
               this.image=Object.requiredNonNull(image);
               this.x=x;
               // etc..
           }
     
           public void drawImage(Graphics g) {
                g.drawImage(image,x,y,width,height,Panel.this);
           }
      }
     
    }

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2015
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2015
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    J'ai testé avec des rectangles et tout marche très bien ^^

    Merci à toi

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

Discussions similaires

  1. Insérer une image dans une application
    Par Invité dans le forum JBuilder
    Réponses: 4
    Dernier message: 23/04/2006, 18h19
  2. [MFC]Insérer une image dans un CListCtrl
    Par DestyNov@ dans le forum MFC
    Réponses: 8
    Dernier message: 04/03/2005, 14h36
  3. Comment insérer une image dans une cellule d'un TDrawGrid ?
    Par kanux dans le forum Composants VCL
    Réponses: 4
    Dernier message: 15/01/2005, 18h58
  4. [Crystal Reports 9] comment insérer une image dans Détails
    Par VVE dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 22/10/2003, 17h06

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