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 :

2 JTables affichant différemment et simultannément les mêmes données


Sujet :

Composants Java

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 6
    Points : 4
    Points
    4
    Par défaut 2 JTables affichant différemment et simultannément les mêmes données
    Chers collègues, bonjour
    Soit une table de données par exemple un annuaire :

    Nom; Prénom; Adresse; téléphone
    ---------------------------------
    Dupond;Pierre;12 rue Tabaga; 2135889900
    Leneuf;Charles;3 bd des iles; 0123456

    Classiquement je souhaite l'afficher tel que ci-dessus (vue Table) ou bien sous forme de fiche (vue Fiche) :
    Libellé :Valeur
    -------------
    Nom : Dupond
    Prénom : Pierre
    Adresse : 12 rue Tabaga
    Téléphone : 2135889900

    Je souhaiterai même présenter ces données sous les 2 aspects simultanément. Par exemple, une fenêtre avec
    -à gauche la vue Table pour choisir un des lignes
    -à droite la vue fiche pour voir les détails d'une ligne et y saisir des modifs.

    Pour cela je peux utiliser 2 JTables. Mais je suis contraint d'utiliser aussi 2 TableModel différents : un pour la vueTable, l'autre pour la vueFiche, puisque la disposition des données est différente.



    Modèle
    |---> TableModel_Table --------> JTable_Table
    |---> TableModel_Fiche --------> JTable_Fiche

    Du coup, je me retrouve obligé de gérer au niveau de ma structure de données (le "Modèle" au sens MVC) les accès concurrents de mes 2 TableModel.
    -si le modèle évolue (changement d'une valeur), alors je dois appeler un méthode de chaque TableModel pour qu'il se mette à jour
    -si une valeur de la JTable change, le TableModel est modifié (ça c'est automatique) mais du coup je dois enregistrer les nouvelles valeurs du TableModel dans le Modèle

    En bref, je me retrouve à devoir réinventer la roue (TableModel ne me sert plus à grand chose : il ne permet pas le découplage entre le "Modèle" et la "Vue")

    Donc, voici mes questions :
    -le TableModel permet il, contrairement à ce que j'ai cru comprendre, de gérer plusieurs JTables organisées différemment ?
    -si, comme je le crains, le TableModel ne le permet pas et que je suis obligé de gérer l'accès concurrent dans mon Modèle : connaissez vous une classe ou une interface qui gère déjà ça pour que je n'ai pas à tout réinventer. Ou bien, à quel "DesignPattern" devrais-je me conformer ?
    (je précise que mon Modèle n'est pas géré par une base de données, donc je ne peux pas compter sur les fonctionnalité du SGBD pour gérer l'accès concurrent)

    (Bien entendu ce problème n'est pas spécifique des JTables)

    J'espère avoir été le plus clair possible dans mon explication
    Merci d'avance de votre lecture attentive...et à bientôt de vous lire.

  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,

    La table qui présente la liste d'objets et la fiche qui présente plusieurs lignes de propriétés d'un même objet de cette liste n'ont manisfestement pas la même forme, donc pas le même modèle. Le plus simple pour faire ça, et de partager les mêmes données, est ne pas utiliser un modèle standard de table, fondé sur des vecteurs de valeurs, mais de mettre directement dans le modèle des objets, dont on affiche dans la table les propriétés, et d'utiliser l'instance de l'objet actuellement sélectionné dans la table comme modèle de base pour la ficher.

    Si tu regardes l'interface TableModel, tu pourras voir qu'il suffit de définir, en résumé, le lien entre des coordonnées de case (ligne et colonne), et la propriété qu'on veut afficher dans la case, ainsi que la nombre de colonnes et de lignes. Il est plus facile de se fonder sur AbstractTableModel, pour bénéficier de la base évenementielle nécessaire au bon fonctionnement dynamique de la JTable.

    Dans le cas de table liste, le nombre de lignes est le nombre d'objets (mettons stockés dans une List), et dans le cas de la fiche le nombre de lignes est le nombre de propriétés que tu veux afficher, qui peut être le nombre de colonnes de l'autre table : tu peux éventuellement encapsuler le modèle de la table liste dans celui de la table fiche, si la fiche affiche toutes les colonnes de la liste, pour généraliser (dans ce cas, tu peux même utiliser directement un DefaultTableModel pour le modèle de la table liste) : en plus, la méthode getValueAt() du modèle de fiche, pour la colonne 0, peut appeler directement getColumnName() du modèle de JTable pour l'affichage des noms de colonnes de la liste ne première colonne de la table fiche. Si le modèle de fiche contient le numéro de ligne sélectionné, il peut de même accèder aux propriétés de l'objet servies par le modèle de la table liste.
    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
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Bonjour joel.drigo, merci pour cette réponse rapide et détaillée.
    Je ne vois pas comment faire à partir de ce que tu expliques, mais je vais préciser ce que je crois en avoir compris :

    J'avais déjà réalisé séparément
    -une JTable_table connectée sur un TableModel_table (qui lui-même lit/écrit un fichier de données)
    -une JTable_fiche connectée sur un TableModel_fiche (qui lui-même lit/écrit le même fichier de données)
    Effectivement dans chaque TableModel il suffit de définir convenablement quelques méthodes (setValueAt, getValueAt,getRowCount,getColumnCount,getColumnName...)
    Cela signifie que le TableModel est spécifiquement adapté à une forme de présentation.

    Dans l'idéal, il faudrait que l'on puisse définir un TableModel_commun qui réagirait différemment selon qu'il est sollicité par une JTable_table ou une JTable_fiche.

    Est-ce que ce que tu suggères c'est de faire 2 table_model (TableModel_table etTableModel_fiche) qui héritent d'un TableModel_commun ?
    A bientôt
    Yves

  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
    Je parlais de faire une implémentation d'un TableModel qui en encapsule un autre. En fait, on peut le prendre par les deux "côtés". Mais le plus simple, à priori (sans y réfléchir plus que ça), je pense que c'est plus simple d'encapsuler le modèle de liste dans celui de fiche.

    Soit un modèle pour la liste, un modèle par défaut même fonctionnerait dans le cas général, et un modèle qui encapsule pour la fiche (qui écoute la sélection de la JTable pour savoir quelle ligne afficher). Un exemple succinct de l'idée (je remplis pas tout, mais tu devrais pouvoir compléter facilement (ça c'est le modèle de la JTable fiche) :

    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
    public class FicheModel extends AbstractTableModel {
     
    	private static final String[] COLUMN_NAMES = {"Nom","Valeur"};
    	private static final int COLUMN_NOM_INDEX = 0;
    	private static final int COLUMN_VALUE_INDEX = 1;
     
    	private TableModel modelListe;
     
    	private int selectedIndex=-1;
     
    	public FicheModel(JTable tableListe) {
    		modelListe = tableListe.getModel();
    		tableListe.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
     
    			@Override
    			public void valueChanged(ListSelectionEvent e) {
    				selectedIndex = e.getFirstIndex();
    			}
    		});
    		modelListe.addTableModelListener(new TableModelListener() {
     
    			@Override
    			public void tableChanged(TableModelEvent e) {
    				// ici il faut coder les branchements sur les évenements :
     
    				// exemple :
    				if ( e.getFirstRow()>=selectedIndex && e.getLastRow()>=selectedIndex ) {
    					if ( e.getType()==TableModelEvent.UPDATE ) {
     
    						// mise à jour
     
    						fireTableCellUpdated(selectedIndex, e.getColumn());
     
     
    					}
    				}
     
    			}
    		});
    	}
     
    	@Override
    	public String getColumnName(int column) {
    		return COLUMN_NAMES[column];
    	}
     
    	@Override
    	public Class<?> getColumnClass(int columnIndex) {
    		switch(columnIndex) {
    		case COLUMN_NOM_INDEX:
    			return String.class;
    		case COLUMN_VALUE_INDEX:	
    			return Object.class; // à voir si toutes tes colonnes sont du même type, auquel cas, tu peux retourner ici ce type
    		default:
    			return null;
    		}
    	}
     
    	@Override
    	public int getRowCount() {
    		// le nombre de ligne, c'est le nombre de colonnes de l'autre, quand il y a sélection
    		if ( selectedIndex<0 ) {
    			return 0;
    		}
    		else {
    			return modelListe.getColumnCount(); 
    		} 
    	}
     
    	@Override
    	public int getColumnCount() {
    		// le nombre de colonnes, c'est 2 (une pour Nom, une pour Valeur
    		if ( selectedIndex<0 ) {
    			return 0;
    		}
    		else {
    			return 2; 
    		} 
    	}
     
    	@Override
    	public Object getValueAt(int rowIndex, int columnIndex) {
    		if ( selectedIndex<0 ) {
    			return null;
    		}
    		else {
    			switch(columnIndex) {
    			case COLUMN_NOM_INDEX:
    				return modelListe.getColumnName(rowIndex); // le nom de la propriété
    			case COLUMN_VALUE_INDEX:	
    				return modelListe.getValueAt(selectedIndex, rowIndex); // la valeur de la propriété
    			default:
    				return null;
    			}
    		} 
    	}
     
    }
    Reste bien sûr l'aspect dynamique par rapport aux datas (les évènements qui mettent à jour la jtable liste lorsqu'une valeur de propriété change). Et cette classe marche (aux bugs prêts, parce que j'ai rien testé) seulement pour une JTable liste à sélection unique, forcément.
    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
    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
    L'autre cas c'est le cas similaire à l'exemple de modèle dynamique dans le tutoriel avec l'objet Ami pour la table liste. On utilise la même instance de Ami que celle de la ligne sélectionnée dans la liste, qu'on met dans le modèle de la jtable fiche, qui serait grossièrement comme ça (j'ai encore moins mis de 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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    public class FicheModel2 extends AbstractTableModel {
     
    	// ici j'ai mis ami en argument pour être cohérent avec mon explication, mais c'est ta classe bien sûr
    	private Ami selection;
     
    	public FicheModel2() {
    	}
     
    	public void setSelection(Ami ami) {
                    if ( this.ami!=null ) {
                         // débrancher les écouteurs de changement de propriétés de this.ami
                    }
    		this.ami=ami;
    		fireTableDataChanged();
                    if ( this.ami!=null ) {
                         // brancher les écouteurs de changement de propriétés de this.ami, pour que la table fiche se mette à jour
                    }
    	}
     
    	@Override
    	public int getRowCount() {
    		return ami==null?0:1;
    	}
     
    	@Override
    	public int getColumnCount() {
    		return 2;
    	}
     
    	@Override
    	public Object getValueAt(int rowIndex, int columnIndex) {
    		Object value = null;
    		if ( ami!=null) {
    			switch( columnIndex ) {
    			case 0:
    				switch( rowIndex ) {
    				case 0:
    					value = "nom de la première prop"...
    					...
    				}
    			case 1:
    				switch( rowIndex ) {
    				case 0:
    					value = ami.get...
    				}
    			}
    		}
    		return value;
    	}
     
    }
    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.

Discussions similaires

  1. Agir avec les mêmes données
    Par punisher999 dans le forum JDBC
    Réponses: 1
    Dernier message: 18/10/2010, 01h21
  2. Réponses: 6
    Dernier message: 26/11/2009, 17h15
  3. Réponses: 3
    Dernier message: 17/02/2009, 13h43
  4. Rappeler le formulaire avec les mêmes données.
    Par macben dans le forum Struts 1
    Réponses: 6
    Dernier message: 30/06/2008, 18h09
  5. [MySQL] la page détaillée affiche toujours les mêmes données
    Par paricilas dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 19/02/2007, 10h50

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