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 :

Mon setValueAt ne fonctionne pas.


Sujet :

Composants Java

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Mon setValueAt ne fonctionne pas.
    Bonjour,

    je sollicite un coups de mains car je bloque depuis plusieurs jours et je ne trouve pas la source de mon problème.

    La classe affiche un tableau vide correspondant a une matrice carrée "lanceur.matrice" de taille "lanceur.taille" (qui sont des variables statique de la classe lanceur).
    Je souhaite éditer les valeurs des cases pour remplir ma matrice.



    J'ai créé un modele avec AbstractTableModel
    et défini isCellEditable et setValueAt.

    Le problème : quand je saisi une valeur dans le tableau et que je valide, l'enregistrement ne se fait pas.

    Auriez vous des pistes que je pourrais explorer ?



    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
    import java.awt.GridLayout;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
     
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    public class fenetresaisie extends JFrame {
     
    	JFrame fenetre = new JFrame();
    	JPanel contenu = new JPanel();
     
    	fenetresaisie() {
     
     
    		//parametre de la fenetre
    		fenetre.setTitle("Projet 6");
    		fenetre.setSize(500,300);
    		fenetre.setLocationRelativeTo(null);
    		fenetre.setResizable(true);
    		fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		//affectation d'un gestionnaire de disposition
    		GridLayout disposition = new GridLayout(2,2);
    		contenu.setLayout(disposition);
     
    		//creation d'untableau des entetes
    		Integer[] entete = new Integer[lanceur.taille];
    		for(int i=0; i<lanceur.taille; i++){
    			entete[i] = i;			
    		}
     
     
    		//affichage du tableau
    		JTable tableau = new JTable(new modeletab(lanceur.matrice, entete));
     
    		//TEST modif données
    		tableau.setValueAt(4,1,1);
     
    		contenu.add(new JScrollPane(tableau));
     
    		//TEST bricole pour affichage
    		JButton valider = new JButton("OK");
    		affich gogo = new affich();
    		valider.addActionListener(gogo);
    		contenu.add(valider);
     
    		//y ajouter le contenu et le rendre visible
    		fenetre.setContentPane(contenu);
    		fenetre.setVisible(true);
    	}
    }
     
    class affich implements ActionListener {
    	public void actionPerformed(ActionEvent evenement){
    		for(int X=0; X<lanceur.taille; X++){
    			for(int Y=0; Y<lanceur.taille; Y++){
    				System.out.print("|"+lanceur.matrice[X][Y]+"|");
    			}
    			System.out.print("\n");
    		}
    	}
    }
     
    //classe modele personalisée
    class modeletab extends AbstractTableModel {
     
    	private Integer[][] donnee;
    	private Integer[] titre;
     
    	public modeletab(Integer[][] donnee , Integer[] titre){
    		this.donnee = donnee;
    		this.titre = titre;
    	}
     
    	public int getRowCount() {
    		return this.donnee.length;
    	}
    	public int getColumnCount() {
    		return this.titre.length;
    	}
    	public Integer getValueAt(int row, int col){
    		return this.donnee[row][col];
    	}
    	public boolean isCellEditable(int row, int col){
    		return true;
    	}
    	public void setValueAt(Integer val,int row, int col){
    			lanceur.matrice[row][col]= val;
    			fireTableCellUpdated(row,col);
    	}
    }

  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,

    Il y a plusieurs problèmes :

    • Dans ta classe de modèle tu as fait une méthode : public void setValueAt(Integer val,int row, int col). Or la méthode de TableModel, c'est public void setValueAt(Object val,int row, int col) : c'est cette méthode qui est appelée, et pas la tienne, parce que le modèle manipule les données par la classe Object. En plus, par défaut, le type des données est String.
    • Ensuite, tu vas avoir un problème avec le type de données : par défaut, c'est du String : donc tu vas être obligé de faire de la conversion vers Integer. Autant indiquer que tu ne manipules que de l'Integer en ajoutant à ta classe de modèle la méthode suivante :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      @Override
      public Class<?> getColumnClass(int columnIndex) {
         return Integer.class;
      }
      La méthode setValueAt devient donc :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      public void setValueAt(Object  val,int row, int col){
         Integer valint=val==null?0:(Integer) val; // ici j'ai fait que si on vide la cellule, on remplace par 0, sinon tu auras des null dans ta matrice 
         lanceur.matrice[row][col]= valint;
         fireTableCellUpdated(row,col);
      }
    • Si on vide une case, ça met null dans la case de la matrice : dans la méthode précédente j'ai modifié ça pour que ça mette 0 dans ce cas, ce qui me semble plus logique pour une matrice
    • Le reste des problèmes n'empechent pas le programme de fonctionner, mais ce sont des choses améliorables.
      1. dans la méthode setValueAt tu modifie le tableau de la classe lanceur (matrice) : il serait plus logique et cohérent de modifier donnee (même s'il s'agit en fait de la même instance). D'autant plus que si tu modifiais par la suite ton code pour différencier les deux instances (donnee et matrice), afin de ne pas modifier ta matrice d'origine directement afin de pouvoir annuler la saisie (ton bouton devenant un bouton de validation qui copie donnee vers matrice)
        La méthode deviendrait donc :
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        public void setValueAt(Object  val,int row, int col){
           Integer valint=val==null?0:(Integer) val;
           donnee[row][col]= valint;
           fireTableCellUpdated(row,col);
        }
      2. Ensuite pourquoi créer une JFrame (variable fenetre) à l'intérieur d'une classe de JFrame (fenetresaisie) que tu n'affiches jamais ? Autant virer fenetre, et directement afficher fenetresaisie (toutes les méthode que tu appelles sur fenetre, tu les appelles sur this)
      3. Au lieu d'utiliser un GridLayout, ce qui fait que tu as un bouton de la taille de la jtable, utilises un BorderLayout et mets ta jtable au centre et ton bouton au sud.
    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
    Novembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Salut,

    merci beaucoup pour ton aide.

    En effet mon problème initial était bien dû au fait que je n'utilisait pas le type Object.
    Je pensais que comme Integer était également un objet ça passait.

    Tu te serais arrêté la c'était déjà super mais tu m'a rajouté du bonus !

    en effet je pensais ensuite forcer le type
    Pour le Null en zero j'avais fait un if(val != null){ }else{ } ... mais clairement ta méthode est plus sexy.
    Sinon les 3 points restants trahissent mon coté macgyver du code, ça sent un peu la bricole... faut que je range tout ça.

    Encore merci, je marque le topic comme résolu.

  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 leofactory Voir le message
    Je pensais que comme Integer était également un objet ça passait.
    Integer est bien une classe qui étend Object.

    Mais java se base sur le type de la variable, pas le type de l'instance pour choisir la méthode à appeler quand il a à choisir entre 2 méthodes.

    Essayes le code suivant pour illustrer :
    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 Demo {
     
    	public static void main(String[] args) {
     
    		Integer integer = new Integer(100);
    		Object object = integer;
     
    		method(object); // la méthode method(Object) sera appelée
    		method(integer); // la méthode method(Integer) sera appelée
     
    	}
     
    	public static void method(Object object) {
    		System.out.println("Appel method(Object): " + object);
    	}
     
    	public static void method(Integer object) {
    		System.out.println("Appel method(Integer): " + object);
    	}
     
    }
    qui affiche :

    Appel method(Object): 100
    Appel method(Integer): 100
    Dans les deux cas d'appel de method(), l'instance est bien un Integer, mais pour java, dans le premier cas, c'est un Object, et il va choisir la méthode avec argument de type Object et dans le second cas, c'est un Integer, donc il va choisir la méthode avec argument de type Integer.
    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. la publication de mon appli ne fonctionne pas
    Par tchecko dans le forum Accès aux données
    Réponses: 4
    Dernier message: 07/10/2006, 11h59
  2. Réponses: 1
    Dernier message: 30/08/2006, 19h00
  3. [VB.Net/DataReader] Pourquoi mon ExecuteReader ne fonctionne pas ?
    Par emeraudes dans le forum Accès aux données
    Réponses: 8
    Dernier message: 21/08/2006, 13h38
  4. Réponses: 14
    Dernier message: 17/08/2006, 10h29
  5. mon trigger ne fonctionne pas !
    Par japi33 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 20/03/2006, 21h26

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