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 un JComboBox a un JTable


Sujet :

Composants Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 18
    Points : 11
    Points
    11
    Par défaut Ajouter un JComboBox a un JTable
    Bonjours
    bon j'ai une petite question que je vais essayer de le dtailler au max.
    en faite j'ai une table de rapports parmit ses colonne la colonne ID (un seul rapport peut etre realise par un ou plusieur intervenants)
    donc, je veux ajouter une colonne intervenant qui contenir des combobox qui sera rempli par les nom des intervenants
    chaque combobox sera rempli par une requete sql qui va utiliser l'ID du rapport de la table rapport
    j'ai essayer le code ci dessous mais ca marche pas, lorsque je clic sur le combobx je doit cliquer deux fois pour que le popup soit afficher
    et le combobox est rempli par des noms autre que les noms des intervenant qui'ont fait ce rapport. je pense que la class TableComponentCombobox est appelé a chaque fois que je clic sur le combobox.
    la class:
    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
    public class TableComponentCombobox extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     
    	int id=Integer.valueOf(table.getValueAt(row,0).toString()).intValue();//obtenir l'ID du rapport
    	ArrayList arraylisttype=new ArrayList();
    	int i=0,j=0;
    	try{
    		Connection connec=ConnexionMysql.ConnecrDb();
    		Statement s=connec.createStatement();
    		ResultSet r=s.executeQuery("SELECT nom_intervenant, prenom_intervenant  FROM `effectuer_correctif` "
    				+ "INNER JOIN intervenant "
    				+ "ON intervenant.`ID_INTERVENANT`=effectuer_correctif.`ID_INTERVENANT` "
    				+ "WHERE `ID_RAPPORT`='"+id+"';");//la requete pour remplir le combobox
    		while(r.next())
    		{
    			arraylisttype.add(r.getString("nom_intervenant")+" "+r.getString("prenom_intervenant"));
    			i=i+1;
    		}
     
    	}
    	catch(SQLException e)
    	{
    		e.printStackTrace();
    	}
    	String[] stringintervenant=new String[i];
    	for(j=0;j<i;j++){
    		stringintervenant[j]=(String)arraylisttype.get(j);	
    	}
     
    table.getModel().setValueAt(new JComboBox(), row, column);
    table.getColumnModel().getColumn(column).setCellEditor(new DefaultCellEditor(new JComboBox<>(stringintervenant)));
     
     
    	return new JComboBox(stringintervenant);
     
    }
    }
    l'appel de la class:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DefaultTableModel tablemodel=(DefaultTableModel) DbUtils.resultSetToTableModel(r);//r: est le resultat d'une requete
    		tablemodel.addColumn("Intervenant(s)");
    		tablerapportpreventif.setModel(tablemodel);
    		tablerapportpreventif.getColumnModel().getColumn(7).setCellRenderer(new TableComponent());
    		tablerapportpreventif.getColumnModel().getColumn(8).setCellRenderer(new TableComponentCombobox());//appel de la class TableComponentCombobox
    le resultat obtenit:
    Nom : Capture.JPG
Affichages : 1387
Taille : 100,7 Ko
    qu'il est la modification a ajouter pour corriger ce probleme?

  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 : 54
    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,

    Le TableCellRenderer sert à faire le rendu (= l'affichage). Pour éditer (changer la valeur), ce que fait une JCombBox, il faut utiliser un TableCellEditor. Si on veut avoir un rendu de cellule qui ressemble à une JComboBox, il suffit d'avoir une combo qui ne contient que la valeur à afficher.

    POC :

    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
    public class JTableCombo {
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Démo"); // création de la fenêtre
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // lorsqu'on clique sur la "croix", on quitte l'application
     
    		frame.add(new JScrollPane(createJTable())); // on créé la JTable, qu'on met dans un scrollpane, qu'on met au centre de la fenêtre
     
    		// affichage de la fenêtre en 400x400 centrée dans l'écran
    		frame.setSize(400, 400); 
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static Component createJTable() {
                    // des données
    		Object[][] data = { { 1, "toto", "machin" },
    				{ 2, "toto", "truc" },
    				{ 3, "toto", "bidule" } };
                    // les titres des colonnes
    		String[] cols = { "id","nom","valeur" };
     
                    // création d'une JTable simple avec les données et colonnes définies ci-dessus
    		JTable table = new JTable(data,cols);
     
    		ComboCellEditor comboCellEditor = new ComboCellEditor(); // je créé une instance de ma classe de rendu/éditeur
    		table.getColumnModel().getColumn(2).setCellRenderer(comboCellEditor); // je l'affecte à la colonne 3 en tant que composant de rendu
    		table.getColumnModel().getColumn(2).setCellEditor(comboCellEditor); // je l'affecte à la colonne 3 en tant qu'éditeur
     
    		table.setSurrendersFocusOnKeystroke(true); // nécessaire pour avoir la combo qui passe en édition quand on commence à taper
     
    		table.setRowHeight(table.getRowHeight()+3); // truc en dur pour améliorer la préz...mais devrait être générique 
     
    		return table;
    	}
     
            /**
              * Cette classe combine la notion d'éditeur sous forme de combo et de renderer sous forme de combo
              * On utilise un DefaultCellEditor qui a déjà toute la mécanique pour gérer un TableCellEditor de type combo
              */
    	public static class ComboCellEditor extends DefaultCellEditor implements TableCellRenderer {
     
    		private JComboBox<String> combo;
     
    		public ComboCellEditor() {
    			super(new JComboBox<>());  // on créé le DefaultCellEditor en lui passant la combo
    			combo=(JComboBox<String>) getComponent();  // je récupère la combo passé dans le constructeur juste avant parce que je vais avoir besoin de travailler avec plus tard (je la stocke dans un attribut donc)
    			// combo.setEditable(true); // éventuellement pour rendre la saisie libre (ici on peut aussi ajouter l'autocompletion)
    			combo.addFocusListener(new FocusAdapter() { // j'enregistre un focuslistener qui va réagir quand la combo prend le focus pour ouvrir automatiquement la liste de la combo (dès qu'on va commencer à taper dans le champ, la combo va passer en édition et donc afficher la liste déroulante)
    				@Override
    				public void focusGained(FocusEvent arg0) {
    					combo.setPopupVisible(true);
    				}
    			});
    			super.setClickCountToStart(1); // je réduis le nombre de clic pour passer en édition à 1 (par défaut dans une JTable, c'est 2, d'où le besoin de double-cliquer)
    		} 
     
                    // méthode de TableCellEditor destinée à créer le composant éditeur qui sera utilisé pour modifier la valeur de la cellule en cours d'édition dans la JTable
    		@Override
    		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
    				int column) {
    			combo.setModel(new DefaultComboBoxModel<>(loadValues((Integer)table.getModel().getValueAt(row, 0)))); // je remplis la combo avec un nouveau modèle contenant le résultat de ma requête
    			if ( isSelected ) { // pour afficher la combo sélectionnée quand la cellule est séctionnée
    				combo.setBackground(table.getSelectionBackground());
    			}
    			else { // sinon je l'affiche dans la couleur normal
    				combo.setBackground(table.getBackground());
    			}
    			return super.getTableCellEditorComponent(table, value, isSelected, row, column); // je rappelle la méthode normale qui va se charger du reste du rendu de l'éditeur
    		}
     
                    // méthode de TableCellRenderer destinée à créer le composant qui affiche la valeur dans la colonne
    		@Override
    		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
    			JComboBox<String> renderCombo = new JComboBox<>(new DefaultComboBoxModel<>(new String[]{(String)value})); // je créé une nouvelle combo avec juste une valeur pour faire un rendu qui ressemble à un éditeur
    			// ici, normalement on doit faire tout le rendu standard, en fonction de isSelected et hasFocus (ici, seul selected est traité)
    			if ( isSelected ) {
    				renderCombo.setBackground(table.getSelectionBackground());
    			}
    			else {
    				renderCombo.setBackground(table.getBackground());
    			}
    			return renderCombo;
    		}
     
    	}
     
    	public static String[] loadValues(int value) {
    		// ici tu remplaces par ta requête
    		switch(value) {
    		case 1:
    			return new String[]{"machin","machin1","machin2"};
    		case 2:
    			return new String[]{"truc","truc1","truc2"};
    		case 3:
    			return new String[]{"bidule","bidule1","bidule2"};
    		}
    		return null;
    	}
     
    }
    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Merci joel.drigo ca marche bien, merci beaucoup.


    Just une petit question:
    j'ai ajouter une mouseclicked au tableau pour obtenir l'ID pour l'utiliser dans une traitement. mais lorsque je clic sur les combobox le mouseclicked ne s'active pas
    comment je peut remidier a se probleme.


    si possible pouvez vous expliqer moi le code precedent en ajoutant des commentaire (j'ai un probleme avec les render et editor) svp

  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 : 54
    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
    Citation Envoyé par Zakaroove Voir le message
    Just une petit question:
    j'ai ajouter une mouseclicked au tableau pour obtenir l'ID pour l'utiliser dans une traitement. mais lorsque je clic sur les combobox le mouseclicked ne s'active pas
    comment je peut remidier a se probleme.
    C'est parce qu'il ne faut pas utiliser un mouselistener. Je suppose qu'en plus tu l'as affecté à la JTable, donc c'est la JTable qui réagit et la combo capte tous les clics (parce qu'elle est au-dessus de la JTable et passe directe en édition dès qu'on clique), et donc la JTable ne les reçoit pas lorqu'on clique sur la combo.
    Il vaut mieux utiliser les évenements de sélection :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // on ne permet de sélectionner qu'une ligne à la fois
    	table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
     
    		@Override
    		public void valueChanged(ListSelectionEvent event) {
    			if ( !event.getValueIsAdjusting() ) {
    				int id = (Integer)table.getValueAt(table.getSelectedRow(),0);
    			}
    		}
    	});
    Citation Envoyé par Zakaroove Voir le message
    si possible pouvez vous expliqer moi le code precedent en ajoutant des commentaire (j'ai un probleme avec les render et editor) svp
    J'ai ajouté des commentaires, mais je ne sais pas si ça va t'aider plus que ça. Ce qu'il faut bien comprendre :

    • L'affichage, ou rendu, est réalisée par un TableCellRenderer
    • L'édition (la modification) est effectuée par TableCellEditor
    • On peut affecter ces composants soit colonne par colonne, soit par type (on définit par exemple un composant de rendu qui affiche une checkbox pour la classe Boolean.class)
    • Le principe de base est que ce sont des fabriques : renderer ou editor, ce sont des classes qui doivent créer un composant graphique, mais souvent la fabrique est le composant lui-même. Ainsi on évite de créer plein de composants (bon dans mon exemple, c'est ce que je fais pour simplifier, mais j'aurais aussi bien pu utiliser la même instance de combo)... Pour le renderer, la manière utilisée pour afficher toutes les cellules le permet : c'est juste une sorte de copie du rendu graphique (le composant de rendu ne peut pas recevoir d'évenement par exemple). Pour l'éditeur, on n'en utilise qu'un seul à l'instant t, donc on peut utiliser toujours le même (dans mon code, on ne change que le modèle à chaque fois).
    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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup joel.drigo

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    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 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    L'exemple habituel pris expliquer pour le renderer de Swing c'est que c'est comme un tampon encreur qui pour chaque ligne est rechargé en encre (potentiellement de couleur différente, et en faisant tourner des moelles pour changer le texte ou la date) avant d'aller tamponner la ligne suivante. Donc pour éviter d'en créer un nouveau, on en utilise un seul qui est reconfiguré (changement de texte, icône, police, couleur, etc. en fonction du contenu) pour chaque ligne a dessiner.
    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

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/06/2007, 20h39
  2. Comment ajouter un listener dans un JTable
    Par @yoyo dans le forum Composants
    Réponses: 5
    Dernier message: 09/05/2007, 14h01
  3. Réponses: 6
    Dernier message: 20/09/2006, 11h01
  4. supprimer un item d'un jcombobox dans une jtable
    Par bellout dans le forum Composants
    Réponses: 6
    Dernier message: 22/06/2006, 16h06
  5. [swing] modifier l'ajout d'objet dans un JTable
    Par Invité dans le forum Composants
    Réponses: 2
    Dernier message: 17/05/2006, 13h02

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