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 :

Mise à jour cellule JTable


Sujet :

Composants Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2009
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 64
    Par défaut Mise à jour cellule JTable
    Bonjour à tous,

    Je développe une application Java/MySQL en essayant de respecter la norme MVC.

    Je rencontre quelques petites difficultés avec cette architecture, notamment dans l'utilisation des JTable. Je vais donner un exemple en détail de mon code pour vous expliquer les problèmes que je rencontre.

    Pour commencer la Vue, qui affichera une liste de PERSONNE dans une JTable, un bouton pour supprimer une personne, un bouton pour ajouter une personne et un label pour afficher une erreur éventuelle (ex : échec de connection a la base de donnée).
    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 ViewPersonne implements ActionListener {
    	private ControlPersonne control;
    	private ModelPersonne model;
            private JTable tblPersonne;
    	private JButton btnNewPersonne;
    	private JButton btnDelPersonne;
    	private JLabel lblError;
     
    	public ViewPersonne(ControlPersonne control, ModelPersonne model) {
    		super();
     
    		this.control = control;
    		this.model = model;
     
    		this.tblPersonne = new JTable(model);
    		this.btnNewPersonne = new JButton();
    		this.btnDelPersonne = new JButton();
                    this.lblError = new JLabel();
    	}
     
            public void setTextError(String error) {
    		this.lblError.setText(error);
    		this.lblError.repaint();
    	}
     
    	...
     
    	@Override
    	public void actionPerformed(ActionEvent ev) {
    		if (ev.getSource() == btnNewPersonne) {
    			control.NewPersonne();
    		}
    		else if (ev.getSource() == btnDelPersonne) {
    			control.deletePersonne();
    		}
    	}
    Ensuite les modèles, une classe personne (nom et age) et une classe héritant de AbstractTableModel étant le modèle de la JTable.
    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
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
     
    public class PersonneTableModel extends AbstractTableModel {
    	private String[] title;
    	private ArrayList<PersonneModel> listPersonne;
     
     
    	public PersonneTableModel() {
    		super();
     
    		this.title = new String[] { "NOM", "AGE" };
    		this.listPersonne = new ArrayList<PersonneModel>();
    	}
     
    	@Override
    	public String getColumnName(int col) {
    		return title[col];
    	}
     
    	@Override
    	public int getColumnCount() {
    		return title.length;
    	}
     
    	@Override
    	public int getRowCount() {
    		return listPersonne.size();
    	}
     
    	@Override
    	public Class<?> getColumnClass(int columnIndex) {
    		switch (columnIndex) {
    			case 0:
    				return String.class;
    			case 1: 
    				return Integer.class;
    			default:
    				return Object.class;
    		}
    	}
     
    	@Override
    	public Object getValueAt(int row, int col) {
    		PersonneModel personne = listPersonne.get(row);
     
    		switch (col) {
    			case 0:
    				return personne.getNom();
    			case 1:
    				return personne.getAge();
    			default:
    				return null;
    		}
    	}
     
    	@Override
    	public boolean isCellEditable(int rowIndex, int columnIndex) {
    		return true; //Toutes les cellules éditables	
    	}
     
    	@Override
    	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    		if(aValue != null){
    			PersonneModel personne = listPersonne.get(rowIndex);
    			String value = aValue.toString();
     
    	                switch(columnIndex){
    				case 0:
    					personne.setNom(value);
    					break;
    				case 1:
    					personne.setAge(Integer.parseInt(value));
    					break;
    	                }
     
    	                fireTableCellUpdated(rowIndex, columnIndex);
    	    }
     
    	}
     
    	public void setListPersonne(ArrayList<PersonneModel> listPersonne) {
    		// efface les items de la liste
    		int lastIndex = getRowCount() - 1;
     
    		if (lastIndex >= 0) {
    			this.listPersonne.clear();
    			fireTableRowsDeleted(0, lastIndex);
    		}
     
    		// ajoute les items à la liste		
    		if (listPersonne != null && listPersonne.size() > 0) {
     
    			for (PersonneModel p : listPersonne) {
    				addPersonne(p);
    			}
    		}
    	}
     
    	public void addPersonne(PersonneModel personne) {
    		int index = getRowCount;
     
    		listPersonne.add(index, personne);
    		fireTableRowsInserted(index, index);
    	}
     
    	public void removePersonne(PersonneModel personne) {
    		int index = listPersonne.indexOf(personne);
     
    		if (index >= 0) {
    			listPersonne.remove(index);
     
    			fireTableRowsDeleted(index, index);
    		}
    	}
    }
    Je me pose une question par rapport à ce AbstractTableModel , fait il partie de ma vue parcequ'il est développé pour fonctionner avec la JTable, ou fait il partie de mon Modèle ?

    Pour terminer mon controller et pour exemple la méthode supprimer personne, le controller tentera de supprimer la personne sélectionné dans la base de données et si la suppression est OK, il supprimera la personne de la JTable par l'intermédiaire de son modèle sinon il affichera l'erreur dans un label de la View.
    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
     
    public void deletePersonne () {
     	try {
     		PersonneModel personne = model.getPersonneSelected();
     
    		// Ici un modèle statique permettant d'effectuer les requête SQL sur la table Personne
    		PersonneRequest.deletePersonne(dataBase.getConnection(), personne);
    		dataBase.commitDatas();
     
    		// le modele informera la vue de la suppression
    		model.removePersonne(personne);
    		view.setTextError("");
    	} 
    	 catch (SQLException e) {
    		// si erreur prévient la vue
    	 	view.setTextError(e.getMessage());
    	}
    	 catch (Exception e) {
    		// si erreur prévient la vue
    	 	view.setTextError(e.getMessage());
    	}
    }
    Cette façon de procéder me permet de capter les erreurs SQL éventuelles avant de supprimer la ligne dans la JTable.

    Je rencontre un problème pour l'édition et la mise à jour d'une cellule en base de données. J'utilise une classe editor héritant de la classe DefaultCellEditor. Une fois la modification effectuée, la méthode setValueAt du modèle de la table (décrit plus haut) est appelée. Mon problème ici est que la cellule sera mise à jour dans la JTable avant de l'être dans ma base de données.

    Pour palier ce problème je pourrai faire ma requête SQL directement dans la méthode setValueAt mais si il y a une erreur, je ne sais pas comment l'afficher dans la vue.
    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
     
    public class PersonneTableModel extends AbstractTableModel {
    	private String[] title;
    	private ArrayList<PersonneModel> listPersonne;
     
    	...
     
    	@Override
    	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    		if(aValue != null){
    			try {
    				PersonneModel personne = listPersonne.get(rowIndex);
    				String value = aValue.toString();
     
    				switch(columnIndex){
    					case 0:
    						personne.setNom(value);
    						break;
    					case 1:
    						personne.setAge(Integer.parseInt(value));
    						break;
    				}	
     
    				// Ici un modèle statique permettant d'effectuer les requête SQL sur la table Personne
    				PersonneRequest.updatePersonne(dataBase.getConnection(), personne);
    				dataBase.commitDatas();
     
    				 fireTableCellUpdated(rowIndex, columnIndex);
    			} 
    			 catch (SQLException e) {
    				// si erreur on ne connait pas le label erreur de la vue
    			}
    			 catch (Exception e) {
    				// si erreur on ne connait pas le label erreur de la vue
    			}  
    	    }
    	}
     
    	...
    }
    De plus je souhaite faire toutes les requêtes SQL depuis mon controller, pour que celui ci puisse interagir avec la vue comme il le souhaite.

    Sinon je pourrai donner la référence de mon controller au modèle de la table mais cela ne respecterai plus la norme MVC et rendrait le modèle dépendant du controller.

    J'ai mis beaucoup de code ici en espérant qu'il puisse servir à quelques un et pour avoir votre avis sur cette façon de procéder.
    Vos idées sur mon problème de conception sont les bienvenues.

    Merci

  2. #2
    Membre confirmé
    Inscrit en
    Octobre 2006
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 200
    Par défaut
    Salut,

    Pour répondre à ta première question:
    Je me pose une question par rapport à ce AbstractTableModel , fait il partie de ma vue parcequ'il est développé pour fonctionner avec la JTable, ou fait il partie de mon Modèle ?
    Le Framework Swing est basé de manière générale sur un design pattern MVC. Donc, de manière logique ta classe héritant d'AbstractTableModel fait partie du modèle !
    Tous les composants en Swing (que ce soit une cellule de de JTable ou un Texfield) ont 3 choses, que tu peux donc assimiler au deisgn pattern MVC:

    - Un model => Modèle
    - Un renderer => Vue
    - Un editor => Controller

    Alors je me trompe peut-être mais perso c'est comme ça que j'ai compris les choses.
    Ceci dit, je vois les choses encore plus bizarrement (après ai-je raison ou tort, je ne sais pas) mais lorsque je développe, je vois en réalité 2 design pattern MCV imbriqués !
    Le design pattern de l'application en général, et le design patten utilisé par Swing dans la vue (donc je redécompose ma vue en MVC également !).

    Pour ta 2ème question:
    Pour palier ce problème je pourrai faire ma requête SQL directement dans la méthode setValueAt mais si il y a une erreur, je ne sais pas comment l'afficher dans la vue.
    Si tu n'as pas besoin de redéfinir un éditeur particulier, ne le fais pas en tous cas c'est mon opinion !

Discussions similaires

  1. Mise à jour automatique JTable
    Par encours dans le forum Composants
    Réponses: 8
    Dernier message: 30/08/2011, 12h49
  2. [XL - 2010] Mise à jour cellule avec formule macro
    Par scrouet dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 06/07/2011, 11h46
  3. Mise à jour cellule macro perso
    Par pascalouh dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 22/06/2009, 11h02
  4. Mise à jour de JTable depuis une Base de Données.
    Par hmd01 dans le forum Composants
    Réponses: 3
    Dernier message: 13/03/2007, 17h51
  5. [C# 1.1] Mise à jour cellules dans un datagrid
    Par celos dans le forum Windows Forms
    Réponses: 10
    Dernier message: 14/06/2006, 10h26

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