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

Composants Java Discussion :

Ajouter une image dans une colonne jTable


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut Ajouter une image dans une colonne jTable
    Bonjour à tous !

    Je cherche à insérer dans une colonne d'une jTable une image, j'ai regardé sur internet sur pas mal de forum mais je n'ai rien trouvé, je vous joins mon code qui vous aidera certainement :
    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
     
            listCustomer.stream().filter((client) -> (!client.getLastname().equals(""))).map((client) -> {
                DefaultTableModel modele3 = (DefaultTableModel)jTableClient.getModel();
                Object[] obj = new Object[5];
                obj[0] = client.getLastname();
                obj[1] = client.getFirstname();
                if(client.getType().equals("idcard")){
                    obj[2] = client.getId();
                }else{
                    obj[3] = client.getId();
                }
                ImageIcon icon = new ImageIcon("img.jpg");   /** C'est à cet endroit que je veux mettre mon image */
                obj[4] = icon;
     
                modele3.addRow(obj);
                return modele3;
            }).map((modele3) -> {
                jTableClient.setModel(modele3);
                return modele3;
            }).forEach((_item) -> {
                jTableClient.repaint();
            });
    En vous remerciant d'avance à tous

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 097
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 097
    Par défaut
    Il te faut pour cela un renderer pour la cellule qui contient l'image. Le renderer peut étendre JLabel qui permet d'afficher facilement une image (s'il ne contient pas de texte).

    Je t'invite a lire ceci
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    Merci pour ta réponse wax78, j'ai regardé le lien que tu m'as donné, essayé dans tous les sens et j'ai rien compris.
    C'est très compliqué juste pour afficher une simple image

  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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Le principe de l'affichage d'une JTable c'est que chaque case est dessinée par un composant graphique, tout comme dans n'importe quelle JFrame/JPanel. Le rendu de chaque case est fait par un TableCellRenderer. Par défaut, une JTable n'affiche que des String, parce qu'elle génère automatiquement des TableCellRenderer qui font un rendu direct des valeurs par un toString(), ce qui ne fonctionne évidemment pas pour une Image.

    Un TableCellRender, c'est simplement un composant qui génère un dessin en fonction de la donnée qu'il y a dans la cellule, et d'autres informations (comme le fait que la cellule est sélectionnée ou pas par exemple).

    Java fournit un TableCellRenderer déjà implémenté qui utilise un JLabel pour simplifier le rendu : DefaultTableCellRender. Il suffit de reprendre le principe pour faire le rendu d'une image.

    Ensuite on associe soit à un type, soit à une colonne, le TableCellRenderer.

    Ci-après un exemple, tout simplement fondé sur le DefaultTableCellRenderer, avec un exemple de colonne avec icône (l'icône dépend du texte dans la cellule), et un exemple avec une image (la donnée est le chemin (relatif) de l'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
    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
    public class ExempleImageJTable {
     
    	private static final String[] COLUMN_NAMES = {"Texte", "Texte avec icône", "Image"};
    	private static final Object[][] ROW_DATA = {
    		{ "XXXX", "OUI", "suricate.jpg" },
    		{ "YYYY", "NON", "toto.jpg" },
    		{ "ZZZZ", "OUI", "suricate.jpg" }
    	};
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("JTable avec image");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JTable table = new JTable(ROW_DATA, COLUMN_NAMES);
     
    		table.getColumnModel().getColumn(1).setCellRenderer(new IconCellRenderer());
    		table.getColumnModel().getColumn(2).setCellRenderer(new ImageCellRenderer());
     
    		JPanel panel = new JPanel(new BorderLayout());
    		panel.add(table.getTableHeader(), BorderLayout.NORTH);
    		panel.add(new JScrollPane(table), BorderLayout.CENTER);
     
    		frame.getContentPane().add(panel);
     
    		frame.setSize(400, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	public final static class IconCellRenderer extends DefaultTableCellRenderer {
     
    		private final static ImageIcon OUI_IMAGE = new ImageIcon("ok-icon.png");
    		private final static ImageIcon NON_IMAGE = new ImageIcon("no-icon.png");
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
     
    			Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
     
    			JLabel label = (JLabel)component;
    			if ( "OUI".equals(value) ) {
    				label.setIcon(OUI_IMAGE);
    			}
    			else if ( "NON".equals(value) ) {
    				label.setIcon(NON_IMAGE);
    			}
    			else {
    				label.setIcon(null);
    			}
     
    			return component;
    		}
     
     
    	}
     
    	public final static class ImageCellRenderer extends DefaultTableCellRenderer {
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
     
    			Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
     
    			JLabel label = (JLabel)component;
    			String cheminImage = String.valueOf(value);
     
    			ImageIcon icon = new ImageIcon(cheminImage);
     
    			if ( icon.getImageLoadStatus()==java.awt.MediaTracker.COMPLETE ) {
    				label.setIcon(icon);
    				table.setRowHeight(row, icon.getIconHeight());
    			}
    			else {
    				label.setIcon(null);
    				table.setRowHeight(row, table.getRowHeight());
    			}
    			label.setText(""); // on efface le texte
     
     
    			return component;
    		}
     
     
    	}
     
    }
    Le rendu :
    Nom : Capture.PNG
Affichages : 2288
Taille : 65,5 Ko

    Les images utilisées pour faire fonctionner l'exemple :


    Nom : no-icon.png
Affichages : 1967
Taille : 794 octets
    Nom : ok-icon.png
Affichages : 1976
Taille : 879 octets
    Nom : suricate.jpg
Affichages : 1982
Taille : 2,8 Ko


    Bien sûr, tu peux directement mettre l'image dans la colonne, sous forme d'ImageIcon, en utilisant un TableCellRenderer comme ç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
    28
    29
    30
    31
    32
    33
    34
    public final static class ImageIconCellRenderer extends DefaultTableCellRenderer {
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
     
    			Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
     
    			JLabel label = (JLabel)component;
     
                            if ( value instanceof ImageIcon ) {
    			   ImageIcon icon = (ImageIcon)value;
     
    			   if ( icon.getImageLoadStatus()==java.awt.MediaTracker.COMPLETE ) {
    				label.setIcon(icon);
    				table.setRowHeight(row, icon.getIconHeight());
    			   }
    			   else {
    				label.setIcon(null);
    				table.setRowHeight(row, table.getRowHeight());
    			   }
    			   label.setText(""); // on efface le texte
                            }
                            else {
    				label.setIcon(null);
    				table.setRowHeight(row, table.getRowHeight());
                            }
     
    			return component;
    		}
     
     
    	}
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    Bonjour Joël !

    Une nouvelle fois, MERCI de ton aide ! Cependant j'ai un soucis pour le chargement de mes images, j'ai utilisé la 2ème méthode de ton exemple c'est à dire "ImageCellRenderer" mais je ne passe pas dans la condition "if ( icon.getImageLoadStatus()==java.awt.MediaTracker.COMPLETE ) {" celle où normalement je devrait avoir le setIcon(monimage). Là, j'ai setIcon(null).
    Je vais te poster mon code pour que tu puisse voir mon erreur :

    Code où je charge mes données, y compris le chemin de l'image en fonction d'une condition
    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
     
                DefaultTableModel modele3 = (DefaultTableModel)jTableClient.getModel();
     
                Object[] obj = new Object[5];
     
                obj[0] = client.getLastname();
                obj[1] = client.getFirstname();
                if(client.getType().equals("idcard")){
                    obj[2] = client.getId();
                }else{
                    obj[3] = client.getId();
                }
     
                /** Image à afficher */
                if (CheckMiniResaCustomer(client.getId()) == true){
                    obj[4] = getClass().getResource("/***/projet/ressources/yes_16_16.png");
                }else{
                    obj[4] = getClass().getResource("/***/projet/ressources/no_16_16.png");
     
                }            
                modele3.addRow(obj);
     
                jTableClient.getColumnModel().getColumn(4).setCellRenderer(new ImageCellRenderer());
     
                return modele3;
            }).map((modele3) -> {
                jTableClient.setModel(modele3);
                return modele3;
            }).forEach((_item) -> {
                jTableClient.repaint();
            });
    Code que j'ai repris de ton 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
     
    public final class ImageCellRenderer extends DefaultTableCellRenderer {
     
        @Override
        public Component getTableCellRendererComponent(JTable table,
                        Object value, boolean isSelected, boolean hasFocus, int row,
                        int column) {
     
                Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
     
                JLabel label = (JLabel)component;
                String cheminImage = String.valueOf(value);
     
                ImageIcon icon = new ImageIcon(cheminImage);
     
                if ( icon.getImageLoadStatus()==java.awt.MediaTracker.COMPLETE ) {
                        label.setIcon(icon);
                        table.setRowHeight(row, icon.getIconHeight());
                }
                else {
                        label.setIcon(null);
                        table.setRowHeight(row, table.getRowHeight());
                }
                label.setText(""); // on efface le texte
     
     
                return component;
        }
    }
    En te remerciant d'avance.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 256
    Par défaut
    C'est du "png", il y a un format spécifique ?

  7. #7
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Citation Envoyé par Jb_One73 Voir le message
    C'est du "png", il y a un format spécifique ?
    Oui j'avais mal regardé ton code : ça doit être du png entrelacé, donc il se charge progressivement. Donc il ne doit pas être complet au retour. C'est plus sioux, parce qu'il faudrait attendre qu'il soit chargé pour notifier la cellule de se rafraîchir. Tu ne fais pas une application web et un 16x16 c'est pas lourd à charger, donc tu devrais le convertir en non entrelacé. Et ne le charger qu'une seule fois, en mettant les 2 images en variable statique final de ta classe.

    Sinon, pourquoi charger l'image de manière aussi compliquée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getClass().getResource("/***/projet/ressources/yes_16_16.png");
    Si tu charges l'image par getResource(), ce qui est bien sûr bien mieux que par File, le chemin doit être relatif au classpath (ou à la classe d'appel) : il ne doit pas à priori figurer de dossier de projet dedans, et pas besoin de wildcards. Ton image est dans un dossier : et le chemin de cette image relatif à ta racine de packages. Autant, simplifier ça.

    Ensuite, tu mets les URL dans la table, c'est une façon de faire, mais puisqu'on va les mettre en variable statique final, autant mettre les ImageIcon, et tu pourras mettre directement les ImageIcon dans la colonne de data, et utiliser le troisième renderer. Peut-être même qu'en entrelacé, on pourra profiter du délai d'affichage de la JTable pour que les images soient bien chargées, mais normalement il ne faudrait pas compter dessus.

    Ensuite, pas là peine de faire jTableClient.getColumnModel().getColumn(4).setCellRenderer(new ImageCellRenderer()); à chaque fois : une fois au début ça suffit, mais ça fonctionnera si tu ne fais à chaque fois : tu fais juste plusieurs fois quelque chose qui n'a besoin d'être fait qu'une seule fois, ce qui consomme un peu de temps pour rien.

    [EDIT]Ah, puis, j'oubliais : tu mets des URL dans la colonne de la table, or mon exemple ne traite que les String, donc comme des filename, pas comme des URL. Il faudrait modifier comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    JLabel label = (JLabel)component;
    		ImageIcon icon = null;
    		if ( value instanceof URL ) {
    			icon = new ImageIcon((URL)value);
    		}
    		else {
    			String cheminImage = String.valueOf(value);
    			icon = new ImageIcon(cheminImage);
    		}
    Mais c'était juste un exemple à la base : ici, le problème c'est qu'on recharge toutes les images à chaque rafraîchissement de la table. Il faut voir combien de ligne il y a, le poids des images, et la fréquence de rafraîchissement. C'est la moins bonne solution des trois en fait.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

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

Discussions similaires

  1. [Débutant] Manipulation d'images : intégrer une image dans une image
    Par noscollections dans le forum VB.NET
    Réponses: 2
    Dernier message: 17/10/2014, 11h51
  2. Réponses: 1
    Dernier message: 21/01/2011, 10h17
  3. Mettre une Image dans une Image
    Par shadowhocine dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 19/12/2006, 18h40
  4. Réponses: 3
    Dernier message: 30/10/2006, 11h21
  5. Insérer une légende dans une image avec une police plus petite
    Par Paulinho dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 3
    Dernier message: 29/04/2006, 14h19

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