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

AWT/Swing Java Discussion :

méthode setVAlueAt() qui renvoie une erreur


Sujet :

AWT/Swing Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut méthode setVAlueAt() qui renvoie une erreur
    Bonjour

    j'essais de faire appel à la methode setVAlueAt() afin de faire un firetablecellupdated(), mais le code me renvoie un NullPointeurException sur la ligne d'appel de setVAlueAt(), j'ai déja passer de longue heure à chercher sur le net sans résultat raison pour laquelle je pose directement la question

    ma classe qui affiche le tableau

    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
     
    @SuppressWarnings("serial")
    public class AffichageLu extends AbstractTableModel implements TableModelListener {
     
    	private final String[] Titres = { "Titre", "Auteur",
    			 "Dernier Chap", "Date Dernier Chap", "Dernier Chap Lu", "Date Derniere lecture"};
    	private List<Manga> manga = null;
     
     
    	public void addManga(Manga mang) {
    		int index = ((List<Manga>) manga).size();
    		((List<Manga>) manga).add(mang);
    		this.fireTableDataChanged();
    		fireTableRowsInserted(index, index);
    		fireTableRowsInserted(manga.size() -1, manga.size() -1);
    	}
     
    	/** modification des cellules de la table **/
    	public boolean isCellEditable(int row, int col){
    		if (col == 4 || col==0) 
    		return true;  // Modification des données possible
    		else
    		return false; // Modification des données impossible
    		}
     
    	public Manga getMangaAt(int row) {
    		if (row >= manga.size())
    			return null;
    		else
    			return manga.get(row);
    	}
     
    	public AffichageLu(List<Manga> manga) {
     
    		this.manga = manga;
    	}
     
    	@Override
    	public int getColumnCount() {
    		return Titres.length;
    	}
     
    	@Override
    	public int getRowCount() {
    		return manga.size();
    	}
     
    	@Override
    	public String getColumnName(int column) {
    		return Titres[column];
    	}
    	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    		 System.out.println("AffichageLu : setValueAt -> ***   Test méthode" );
    	};
     
     
    	@Override
    	public Object getValueAt(int row, int column) {
    		switch (column) {
    		case 0:			
    			return manga.get(row).getTitre();
    		case 1:
    			return manga.get(row).getAuteur();
    		case 2:			
    				return manga.get(row).getDernierChapitre();
    		case 3:
    			return manga.get(row).getDateDernierChap();
    		case 4:
    			return manga.get(row).getDernierChapitreLu();
    		case 5:
    			return manga.get(row).getDateDerniereLecture();  
    		default:
    			return "";
    		}
    	}
     
        public void removeManga(int rowIndex) {
        	manga.remove(rowIndex);
     
            fireTableRowsDeleted(rowIndex, rowIndex);
        }
     
    	@Override
    	public void tableChanged(TableModelEvent e) {
    		 int row = e.getFirstRow();
    	        int column = e.getColumn();
     
    	        System.out.println("AffichageLu : TableChanged -> ***   Test méthode" );
     
    	        TableModel model = (TableModel)e.getSource();
    	        String columnName = model.getColumnName(column);
    	        Object data = model.getValueAt(row, column);
     
    	        System.out.println("AffichageLu : TableChanged -> ***   Test récuperation de donnée de la table -> " + data );
    	}
     
    }
    et la classe qui gère l'afffichage du tableau

    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
     
     
    @SuppressWarnings("serial")
    public class GestionAffichageLu extends JFrame implements ActionListener,
    		TableModelListener {
     
    	private JPanel contentPane;
    	public JTable table;
    	private AffichageLu model;
     
    	ConnexionMangaLu con = new ConnexionMangaLu();
    	MiseAJourScans majr = new MiseAJourScans();
    	FormulaireMiseAJour form;
     
    	JComboBox<?> texte = new JComboBox<Object>();
    	AutoCompleteSupport<String> support;
     
    	private JPopupMenu popupMenu = new JPopupMenu();
    	public int selectedRow;
     
    	@SuppressWarnings("static-access")
    	public GestionAffichageLu() {
     
    		this.setTitle("Mangas Lu");
     
    		Dimension dimension = java.awt.Toolkit.getDefaultToolkit()
    				.getScreenSize();
    		int height = (int) dimension.getHeight();
    		int width = (int) dimension.getWidth();
    		setBounds(-10, 0, width, height);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		contentPane.setLayout(new BorderLayout(0, 0));
    		// setContentPane(contentPane);
     
    		JPanel menu = new JPanel();
     
    		con.connection();
    		ArrayList<Manga> mangaList = con.getAllMangas();
     
    		model = new AffichageLu(mangaList);
     
    		table = new JTable();
    		// / table.getModel().addTableModelListener(this);
    		table.setAutoCreateRowSorter(true); // initialisation du tri
    		table.setModel(model);
    		getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
     
    		final TableRowSorter<AffichageLu> sorter = new TableRowSorter<AffichageLu>(
    				model);
    		table.setOpaque(true);
    		table.setRowSorter(sorter);
     
    		texte.setPreferredSize(new Dimension(0, 0));
     
    		con.connection();
    		ArrayList<String> completion = con.lectureTitre();
     
    		// Créer un tableau de même taille que le nombre d'objet de ArrayList
    		String tab[] = new String[completion.size()];
     
    		// Transforme Le ArrayList en Tableau
    		tab = completion.toArray(tab);
     
     
    		JMenuItem menuItem3 = new JMenuItem("MAJ derniere lecture");
     
    		menuItem3.setActionCommand("");
     
    		menuItem3.addActionListener((ActionListener) this);
     
    		menuItem3.addActionListener(new MAJDerniereLecture());
     
     
    		popupMenu.add(menuItem3);
     
    		String[] items = { "Tous", "En Cours", "Terminer" };
    		JComboBox<String> combobox = new JComboBox<>(items);
     
     
    		GridLayout boutons = new GridLayout(18, 2, 0, 10);
    		menu.setLayout(boutons);
    		menu.setBorder(BorderFactory.createEmptyBorder(5, 2, 20, 5));
     
    		texte.setOpaque(false);
     
    		ItemListener listener = new ItemListener() {
    			public void itemStateChanged(ItemEvent e) {
    				if (e.getStateChange() == ItemEvent.SELECTED) {
    					String filtrage = combobox.getSelectedItem().toString();
     
    					/**
                                             * si selection sur combocox = Tous, on remet le filtrage a
                                             * null sinon filtrage selon le choix
                                             ***/
    					if (!filtrage.equals("Tous"))
    						sorter.setRowFilter(RowFilter.regexFilter(filtrage));
    					else {
    						sorter.setRowFilter(null);
    					}
     
    				}
    			}
    		};
     
    		combobox.addItemListener(listener);
     
     
     
    		maj.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				close();
    				if (!majr.majScans(0, 1))
    					new GestionAffichageLu();
    			}
    		});
     
    		table.setDefaultRenderer(Object.class, new MonCellRenderer());
     
     
    		getContentPane().add(menu, BorderLayout.WEST);
    		setVisible(true);
     
    	}
     
     
     
    	private void showPopup(MouseEvent e) {
    		if (e.isPopupTrigger()) {
    			Point p = new Point(e.getX(), e.getY());
     
    			selectedRow = table.rowAtPoint(p); // recuperation de la ligne
    			popupMenu.show(e.getComponent(), e.getX(), e.getY());
    		}
    	}
     
     
    	/*** Menu clic droit : Mise à Jour *****/
    	private class MAJDerniereLecture extends AbstractAction {
    		private MAJDerniereLecture() {
    			super("MAJDerniereLecture");
    		}
     
    		public void actionPerformed(ActionEvent e) {
     
    			Object cellule = table.getValueAt(selectedRow, 0);
    			new FormulaireMiseAJour(cellule.toString(), 1);
     
    		}
    	}
     
     
    	/* affichage */
    	class MonCellRenderer extends DefaultTableCellRenderer {
     
     
     
    		@SuppressWarnings("static-access")
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
     
    			Object valeurDernierChap = table.getModel().getValueAt(
    					table.convertRowIndexToModel(row), 2);
     
    			/* recuperation de l'etat de chaque cellule du tableau */
    			Component cell = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row, column);
     
    			/* application de la police "Courier New" et de fond "bold + italic" */
    			cell.setFont(new Font("Courier New bold", Font.ITALIC, 15));
     
    			Object valeur = table.getValueAt(row, 4);
     
    			double val1 = 0;
    			double val2 = 0;
     
    			try {
    				val1 = Double.parseDouble((String) valeurDernierChap);
    				val2 = Double.parseDouble((String) valeur);
    			} catch (Exception e) {
    				// TODO: handle exception
    			}
     
    			String statusValue = null;
     
    			con.connection();
     
    			statusValue = con.recupStatut(table.getModel()
    					.getValueAt(table.convertRowIndexToModel(row), 0)
    					.toString());
    			/*
    			 * application de couleur sur cellule selon le contenu de la cellule
    			 * *
    			 */
     
    			if (statusValue == null) {
    				statusValue = "En Cours";
    			} else if (statusValue.equals("Terminer")) {
    				setBackground(Color.GRAY);
    				if (val1 > val2) {
    					if (column == 2) {
    						setBackground(Color.GREEN);
    					}
    				}
     
    			} else if (statusValue.equals("En Cours")) {
    				setBackground(Color.CYAN);
     
    				if (val1 > val2) {
    					if (column == 2) {
    						setBackground(Color.GREEN);
    					}
    				}
     
    			} else if (valeur == null) {
    				setBackground(Color.YELLOW);
    			} else {
    				setBackground(null);
    			}
     
     
    			return cell;
    		}
     
     
    	}
     
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		System.out
    				.println("GestionAffichageLu : actionPerformed -> ***   Test appel méthode");
    		table.setValueAt(form.getDernierScanLu(), selectedRow, 4);
     
    	}
     
    	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    		 System.out.println("GestionAffichageLu : setValueAt -> ***   Test méthode" );
         fireTableCellUpdated(selectedRow,4);
    	}
     
    	@Override
    	public void tableChanged(TableModelEvent e) {
     
    		int row = e.getFirstRow();
    		int column = e.getColumn();
     
    		System.out
    				.println("GestionAffichageLu : TableChanged -> ***   Test méthode");
     
    		TableModel model = (TableModel) e.getSource();
    		String columnName = model.getColumnName(column);
    		Object data = model.getValueAt(row, column);
     
    		System.out
    				.println("GestionAffichageLu : TableChanged -> ***   Test récuperation de donnée de la table : "
    						+ data);
     
    	}
     
    }

    Si l'un de vous a une idée de la cause de cette erreur et de la solution ( ou une piste ) je suis preneur

    je vous remerci d'avance

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

    Peux-tu nous montrer la stacktrace complète ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    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
     
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at GestionAffichageLu.actionPerformed(GestionAffichageLu.java:429)
    	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    	at javax.swing.AbstractButton.doClick(Unknown Source)
    	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    	at java.awt.Component.processMouseEvent(Unknown Source)
    	at javax.swing.JComponent.processMouseEvent(Unknown Source)
    	at java.awt.Component.processEvent(Unknown Source)
    	at java.awt.Container.processEvent(Unknown Source)
    	at java.awt.Component.dispatchEventImpl(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Window.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    	at java.awt.EventQueue.access$500(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.awt.EventQueue$4.run(Unknown Source)
    	at java.awt.EventQueue$4.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.awt.EventQueue.dispatchEvent(Unknown Source)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.run(Unknown Source)
    par contre la ligne ne correspond pas exactement puisque j'ai un peu raccourci le code en enlevant les élement inutile à la compréhension du pb mais l'erreur est bien sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    table.setValueAt(form.getDernierScanLu(), selectedRow, 4);
    dans la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    @Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
    		System.out
    				.println("GestionAffichageLu : actionPerformed -> ***   Test appel méthode");
    		table.setValueAt(form.getDernierScanLu(), selectedRow, 4);
     
    	}

  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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Donc c'est soit table qui est null, soit form. Je ne vois nulle part dans le précédent code d'initialisation de form (un truc du genre form = new ..., ou form = uneMethode(.... Donc il est probablement null. D'où une NullPointerException lors de l'invocation de form.getDernierScanLu()

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    effectivement c'etait ca le probleme je l'ai rsolu en rajoutant un constructeur vide dans la classe FormulaireMiseAJour pour l'instancier

    mais ca me ramène à mon 1er probleme que je n'avais pas réussi à résoudre qui celui de la mise à jour de la table lors d'une modification d'information

    j'essai de le notifier à la table avec la méthode firetablecellupdate dans la methode setVAlueAt() mais ce ne passe pas ou alors il ya une facon bien précise de le faire ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    		 System.out.println("GestionAffichageLu : setValueAt -> ***   Test méthode" );
    		fireTableCellUpdated(rowIndex, columnIndex);
    	}
    d'ailleur eclipse me signale qu'il ya une erreur sur la ligne fire. . .

  6. #6
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Là, tu me montres la méthode dans ta classe GestionAffichageLu, qui est une JFrame. Il n'y a pas de méthode fireTableCellUpdated dans JFrame et tu n'as pas écrit de méthode s'appelant comme ça, donc cette méthode n'existe pas, normal que ça ne compile pas.

    De toute manière, pour modifier le modèle, il faut invoquer la méthode sur le modèle, ou sur la jtable, qui va invoquer celle du modèle.

    Ensuite, c'est dans le modèle que tu dois implémenter cette méthode pour qu'elle modifie la ou les variables que tu utilises pour stocker tes données. C'est le pendant de getValueAt(). Ensuite l'appelle de fireTableCellUpdated va permettre à la JTable que tu as modifié cette valeur dans ton modèle et elle va faire ce qu'il faut pour réagir à ça.

    Si on regarde ta méthode de lecture dans le modèle :

    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
     
     
    	@Override
    	public Object getValueAt(int row, int column) {
    		switch (column) {
    		case 0:			
    			return manga.get(row).getTitre();
    		case 1:
    			return manga.get(row).getAuteur();
    		case 2:			
    				return manga.get(row).getDernierChapitre();
    		case 3:
    			return manga.get(row).getDateDernierChap();
    		case 4:
    			return manga.get(row).getDernierChapitreLu();
    		case 5:
    			return manga.get(row).getDateDerniereLecture();  
    		default:
    			return "";
    		}
    	}
    Il faut que setValueAt du modèle fasse en quelque sort l'inverse de ce que ça fait.

    Par 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
     
        @Override
        public void setValueAt(Object value, int row, int column) {
                    // ici gérer en amont les valeur invalide de row 
                    if ( manga==null || row<0 || row>=manga.getSize() ) {
                           throw new IllegalArgumentException("Ligne inexistante: " + row);
                    }
    		switch (column) {
    		case 0:			
    			manga.get(row).setTitre((String)value); // il faut évidemment que la méthode existe
                            break;
    		case 1:
    			/* etc */
                    default:
                            throw new IllegalArgumentException("Colonne inexistante: " + column);
    		}
                    fireTableCellUpdated ();
    }

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    Bonjour, désolé pour la réponse tardive.

    j'ai essayer l'implémentation que vous avez proposé.

    dans la classe qui appelle à la mise à jour
    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
     	ok.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent event) {
     
    				System.out
    				.println("FormulaireMiseAJour : ok.addactionlistener -> ***   Test appel méthode"); 
     
    				aff = new AffichageLu();
     
    				aff.update(getDernierScanLu());
     
    				close();
     
     
     
    			}
    		});
    ensuite dans la classe qui gere le remplissage et le modele ( AffichageLu )
    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
     
    public void update(String string){
    		setValueAt(string, gestion.getSelectedRow(), 4);
     
    	}
     
    	    public void setValueAt(Object value, int row, int column) {
    	                /* ici gérer en amont les valeur invalide de row 
    	                if ( manga==null || row<0 || row>=manga.size() ) {
    	                       throw new IllegalArgumentException("Ligne inexistante: " + row);
    	                }  */
    			switch (column) {
    			case 4:			
    				System.out.println("AffichageLu : SetVAlueAt -> "+ (String)value );
    				manga.get(row).setDernierChap((String)value);
    	                        break;
    			case 1:
    				/* etc */
    	                default:
    	                        throw new IllegalArgumentException("Colonne inexistante: " + column);
    			}
    	                fireTableCellUpdated (row, column);
    	}
    et la classe complete
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
     
     
     
    @SuppressWarnings("serial")
    public class AffichageLu extends AbstractTableModel implements
    		TableModelListener {
     
    	private final String[] Titres = { "Titre", "Auteur", "Dernier Chap",
    			"Date Dernier Chap", "Dernier Chap Lu", "Date Derniere lecture" };
    	private List<Manga> manga = null;
    	GestionAffichageLu gestion = new GestionAffichageLu(0);
     
    	public AffichageLu(){
     
    	}
    	public void addManga(Manga mang) {
    		int index = ((List<Manga>) manga).size();
    		((List<Manga>) manga).add(mang);
    		// this.fireTableDataChanged();
    		fireTableRowsInserted(index, index);
    		fireTableRowsInserted(manga.size() - 1, manga.size() - 1);
    	}
     
    	/*
    	 * public void updateManga(int row) { fireTableCellUpdated(row, 2); }
    	 */
    	/** modification des cellules de la table **/
    	public boolean isCellEditable(int row, int col) {
    		if (col == 4 || col == 0)
    			return true; // Modification des données possible
    		else
    			return false; // Modification des données impossible
    	}
     
    	public Manga getMangaAt(int row) {
    		if (row >= manga.size())
    			return null;
    		else
    			return manga.get(row);
    	}
     
    	public void deleteMangaAt(int row) {
    		if (row < manga.size()) {
    			manga.remove(row);
    			// fireTableRowsDeleted(row, row);
    		}
    	}
     
    	public AffichageLu(List<Manga> manga) {
     
    		this.manga = manga;
    	}
     
    	@Override
    	public int getColumnCount() {
    		return Titres.length;
    	}
     
    	@Override
    	public int getRowCount() {
    		return manga.size();
    	}
     
    	@Override
    	public String getColumnName(int column) {
    		return Titres[column];
    	}
     
    	@Override
    	public Object getValueAt(int row, int column) {
    		switch (column) {
    		case 0:
    			return manga.get(row).getTitre();
    		case 1:
    			return manga.get(row).getAuteur();
    		case 2:
    			return manga.get(row).getDernierChapitre();
    		case 3:
    			return manga.get(row).getDateDernierChap();
    		case 4:
    			return manga.get(row).getDernierChapitreLu();
    		case 5:
    			return manga.get(row).getDateDerniereLecture();
    		default:
    			return "";
    		}
    	}
     
    public void update(String string){
    		setValueAt(string, gestion.getSelectedRow(), 4);
     
    	}
     
    	    public void setValueAt(Object value, int row, int column) {
    	                /* ici gérer en amont les valeur invalide de row 
    	                if ( manga==null || row<0 || row>=manga.size() ) {
    	                       throw new IllegalArgumentException("Ligne inexistante: " + row);
    	                }  */
    			switch (column) {
    			case 4:			
    				System.out.println("AffichageLu : SetVAlueAt -> "+ (String)value );
    				manga.get(row).setDernierChap((String)value);
    	                        break;
    			case 1:
    				/* etc */
    	                default:
    	                        throw new IllegalArgumentException("Colonne inexistante: " + column);
    			}
    	                fireTableCellUpdated (row, column);
    	}
     
    	@Override
    	public void tableChanged(TableModelEvent e) {
    		int row = e.getFirstRow();
    		int column = e.getColumn();
     
    		System.out.println("AffichageLu : TableChanged -> ***   Test méthode");
     
    		TableModel model = (TableModel) e.getSource();
    		String columnName = model.getColumnName(column);
    		Object data = model.getValueAt(row, column);
     
    		System.out
    				.println("AffichageLu : TableChanged -> ***   Test récuperation de donnée de la table -> "
    						+ data);
    	}
     
    }
    et enfin dans la classe Manga
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void setDernierChap(String val){
     
    		form.maj();
    	}
    la classe complete
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
     
    public class Manga {
     
    	private String titre;
    	private String genre;
    	private String auteur;
    	private String annee;
    	private String DernierChapitre;
    	private String DateDernierChap;
    	private String DernierChapitreLu;
    	private String DateDerniereLecture;
    	private String synopsie;
    	private String image;
    	private String status;
     
    	FormulaireMiseAJour form;
     
    	public Manga(String titre, String genre, String auteur, String annee,
    			String dernierChapitre, String dateDernierChap,
    			String dernierChapitreLu, String dateDerniereLecture,
    			String synopsie, String image, String status) {
    		super();
    		this.titre = titre;
    		this.genre = genre;
    		this.auteur = auteur;
    		this.annee = annee;
    		DernierChapitre = dernierChapitre;
    		DateDernierChap = dateDernierChap;
    		DernierChapitreLu = dernierChapitreLu;
    		DateDerniereLecture = dateDerniereLecture;
    		this.synopsie = synopsie;
    		this.image = image;
    		this.status = status;
    	}
     
    	public Manga(String titre, String genre, String auteur,
    			String dernierChapitre, String dateDernierChap,
    			String dernierChapitreLu, String dateDerniereLecture, String status) {
    		super();
    		this.titre = titre;
    		this.genre = genre;
    		this.auteur = auteur;
    		DernierChapitre = dernierChapitre;
    		DateDernierChap = dateDernierChap;
    		DernierChapitreLu = dernierChapitreLu;
    		DateDerniereLecture = dateDerniereLecture;
    		this.status = status;
    	}
     
    	public Manga(String titre, String genre, String auteur, String annee,
    			String dernierChapitre, String dateDernierChap,
    			String dernierChapitreLu, String dateDerniereLecture,
    			String synopsie, String status) {
    		super();
    		this.titre = titre;
    		this.genre = genre;
    		this.auteur = auteur;
    		this.annee = annee;
    		DernierChapitre = dernierChapitre;
    		DateDernierChap = dateDernierChap;
    		DernierChapitreLu = dernierChapitreLu;
    		DateDerniereLecture = dateDerniereLecture;
    		this.synopsie = synopsie;
    		this.status = status;
    	}
     
    	public Manga(String genre, String auteur, String annee,
    			String dernierChapitre, String synopsie, String status) {
    		super();
    		this.genre = genre;
    		this.auteur = auteur;
    		this.annee = annee;
    		DernierChapitre = dernierChapitre;
    		this.synopsie = synopsie;
    		this.status = status;
    	}
     
    	public String getTitre() {
    		return titre;
    	}
     
    	public String getGenre() {
    		return genre;
    	}
     
    	public String getAuteur() {
    		return auteur;
    	}
     
    	public String getAnnee() {
    		return annee;
    	}
     
    	public String getDernierChapitre() {
    		return DernierChapitre;
    	}
     
    	public String getDateDernierChap() {
    		return DateDernierChap;
    	}
     
    	public String getDernierChapitreLu() {
    		return DernierChapitreLu;
    	}
     
    	public String getDateDerniereLecture() {
    		return DateDerniereLecture;
    	}
     
    	public String getSynopsie() {
    		return synopsie;
    	}
     
    	public String getImage() {
    		return image;
    	}
     
    	public String getStatus() {
    		return status;
    	}
     
     
    	public void setDernierChap(String val){
     
    		form.maj();  // pour pouvoir se connecter a la base de donnée et faire la MAJ 
    	}
     
    }
    et donc le problème est que j'ai une erreur dans la methode setValue ... à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    manga.get(row).setDernierChap((String)value);
    je pense que le probleme vient du get(row) puisque je ne pense pas qu'il vienne de setDernierChap et value n'est pas null

    l'erreur renvoyer
    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
     
    AffichageLu : SetVAlueAt -> 40.0
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    	at AffichageLu.setValueAt(AffichageLu.java:106)
    	at AffichageLu.update(AffichageLu.java:94)
    	at FormulaireMiseAJour$2.actionPerformed(FormulaireMiseAJour.java:141)
    	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    	at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source)
    	at java.awt.Component.processMouseEvent(Unknown Source)
    	at javax.swing.JComponent.processMouseEvent(Unknown Source)
    	at java.awt.Component.processEvent(Unknown Source)
    	at java.awt.Container.processEvent(Unknown Source)
    	at java.awt.Component.dispatchEventImpl(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    	at java.awt.Container.dispatchEventImpl(Unknown Source)
    	at java.awt.Window.dispatchEventImpl(Unknown Source)
    	at java.awt.Component.dispatchEvent(Unknown Source)
    	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    	at java.awt.EventQueue.access$500(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.awt.EventQueue$3.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.awt.EventQueue$4.run(Unknown Source)
    	at java.awt.EventQueue$4.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    	at java.awt.EventQueue.dispatchEvent(Unknown Source)
    	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    	at java.awt.EventDispatchThread.run(Unknown Source)
    donc auriez vous une idée pour ce probleme ? ou alors auriez vous une idée plus simple pour mettre tout ca en place ?

    Merci

  8. #8
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    aff = new AffichageLu();
    aff.update(getDernierScanLu());
    Là, tu crées un modèle que la JTable ne connait pas, et en plus la liste manga y est null, donc, forcément, ça fait une NullPointerException lorsque de l'appel get().

    C'est le modèle de la JTable que tu dois manipuler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    model.update(getDernierScanLu());
    (Nonobstant GestionAffichageLu gestion = new GestionAffichageLu(0); qui me semble étrange : je ne vois pas de lien avec la JTable..., donc avec sa sélection...)

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    D'apres ce que je sais et que j'ai compris de vos explications précédentes, une fois l'information récupéré c'est le modele de la table ( representer dans mon cas par la classe " AffichageLu " ) qu'il faut notifier afin qu'il fasse une mise à jour de sa liste et le renvoie au tableau ( a moins que le tableau et le modèle ne font qu'un ). A moins que je n'ai pas tout compris puisque mon code ne fonctionne toujours pas.

    D'après ce que j'avais trouver sur le net avant de mettre ma question sur le forum, l'affichage ( ma classe " AffichageLu " ) et la gestion du tableau ( ma classe " GestionAffichageLu" ) se font dans la meme classe, et d'après ce que j'ai trouver dans le manuel d'utilisation de fire... ( a moins que je n'ai pas tout compris dessus ) cette mise a jour de la table a été prévu pour les cas où on modifie les informations directement sur le tableau.

    Tout ceci qui m'enmene à la supposition " peut etre que ca ne peut pas fonctionner avec mon implémentation " puisque le cheminement de mon programme est le suivant :
    1. récupération de l'information a mettre a jour, non directement modifié sur la table mais par une JFrame qui apparait lorsqu'on demande la mise jour ( la classe FormulaireMiseAJour
    2. Mise à jour de l'info dans la BDD
    3. Mise à jour de la JTable

    donc es ce que le fait que je récupere l'information sur une JFrame et non directement sur la table peut influer sur le fonctionnement ou la mise en oeuvre de cette fonctionnalité ?

    ou alors je suis à coté de la plaque depuis le début ce qui serait tout aussi possible


    PS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GestionAffichageLu gestion = new GestionAffichageLu(0);
    etais juste pour initialiser la classe afin de na pas avoir un null,

  10. #10
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par louisard Voir le message
    D'apres ce que je sais et que j'ai compris de vos explications précédentes, une fois l'information récupéré c'est le modele de la table ( representer dans mon cas par la classe " AffichageLu " ) qu'il faut notifier afin qu'il fasse une mise à jour de sa liste et le renvoie au tableau ( a moins que le tableau et le modèle ne font qu'un ). A moins que je n'ai pas tout compris puisque mon code ne fonctionne toujours pas.
    Non, le modèle notifie la JTable. Et la JTable c'est la JTable (la vue dans un MVC), et modèle c'est le modèle (le modèle dans un MVC). La JTable affiche les données du modèle. Comme les données de ton modèle (AffichageLu) sont stockées dans une liste interne au modèle, la table ne peut pas savoir quand tu modifies cette liste, donc il faut notifier la JTable, en appelant la méthode adaptée (dans ton cas, fireTableCellUpdated, méthode de AbstractTableModel, qui va dire à la JTable "hé, j'ai modifié la cellule x,y, fait ce que tu as à faire en conséquence).

    Citation Envoyé par louisard Voir le message
    D'après ce que j'avais trouver sur le net avant de mettre ma question sur le forum, l'affichage ( ma classe " AffichageLu " ) et la gestion du tableau ( ma classe " GestionAffichageLu" ) se font dans la meme classe, et d'après ce que j'ai trouver dans le manuel d'utilisation de fire... ( a moins que je n'ai pas tout compris dessus ) cette mise a jour de la table a été prévu pour les cas où on modifie les informations directement sur le tableau.
    JE ne sais pas ce qu'est ton GestionAffichageLu (d'autant plus que je n'en ai pas le code) et je ne vois pas à quoi il sert en plus. C'est quoi que tu appelles "tableau", la JTable ? Evite les termes qui peuvent porter à confusion (un tableau en Java c'est un tableau(par exemple [c]String[] array={"toto","titi"};[/code], et une JTable n'est pas un tableau).
    En ce qui concerne les classes, normalement c'est mieux d'avoir des classes de modèle, de vue et de controleur séparées, c'est plus souple et modulable. Mais e n'est pas obligatoire pour que ça fonctionne, et c'est probablement plus simple d'avoir qu'une seule classe. Et il est souvent plus simple d'intégrer le contrôleur à la vue pour accèder directement à ses composants graphiques, mais ça c'est quand on développe soi-même la vue. La JTable ce n'est pas toi qui la développe, donc autant faire un contrôlleur séparé, si tu en as besoin. Ensuite, le contrôleur doit connaitre la vue sinon difficile qu'il puisse agir dessus. Donc je te disais que je ne voyais pas le lien entre la JTable et ton GestionAffichageLu parce qu'a part un rôle de controleur, je ne voyais pas à quoi ça pouvait bien servir, mais comme il n'y en a pas (de lien avec une JTable), je ne vois pas à quoi il sert.

    Citation Envoyé par louisard Voir le message
    donc es ce que le fait que je récupere l'information sur une JFrame et non directement sur la table peut influer sur le fonctionnement ou la mise en oeuvre de cette fonctionnalité ?
    Non, peu importe. Ce qui importe c'est mettre à jour les différents objets qui représentent la même chose lorsqu'il est nécessaire d'en utiliser plusieurs. Le mieux étant d'arriver à représenter une information par un objet unique, comme ça pas besoin de chercher à mettre à jour l'information à plusieurs endroits, et pas de risque que ça ne fonctionne pas ou que ça fonctionne à moitié. Mais ça peut être un peu plus complexe pour un débutant je le conçois.

    Dans ton cas, la succession des opérations que tu décris me paraissent bien convenir, au détail près que j'aurais écrit :

    1. récupération de l'information a mettre a jour, non directement modifié sur la table mais par une JFrame qui apparait lorsqu'on demande la mise jour ( la classe FormulaireMiseAJour
    2. Mise à jour de l'info dans la BDD
    3. Mise à jour du modèle de la JTable






    Citation Envoyé par louisard Voir le message
    PS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GestionAffichageLu gestion = new GestionAffichageLu(0);
    etais juste pour initialiser la classe afin de na pas avoir un null,
    [/quote]
    Alors, ce genre de truc, il faut que tu le marques quelque part, à côté de "ne jamais sauter à pieds joints sur un piège à ours armé" : "ne jamais instancier un objet juste pour ne pas avoir un null".
    On ne créé pas des instances juste pour le fun : une instance représente une unité de donnée, chaque instance étant distincte, ce qui signifie qu'une instance ne connait pas les autres (oublions les moyens qu'on pourrait mettre en place pour que si).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Machin{
        private int val;
        public void setValeur(int val) {
             this.val=val;
        }
        public int getValeur() {
             return val;
        }
     
    }
    Si quelque part dans le code tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Machin machin = new Machin();
    machin.setValeur(42);
    Et que quelque part ailleurs tu as ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println( machin.getValeur() );
    et que ça te fait une NullPointerException et que tu fais un new Machin() pour l'éviter, et bien, ça t'affichera 0, et pas 42, ce qu'on voudrait afficher.

    Dans ton cas, si tu dois mettre à jour une ligne correspondant à une sélection (de je ne sais quoi), c'est par rapport à cette sélection que tu dois le faire, pas par rapport à une autre.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    Non, le modèle notifie la JTable. Et la JTable c'est la JTable (la vue dans un MVC), et modèle c'est le modèle (le modèle dans un MVC). La JTable affiche les données du modèle. Comme les données de ton modèle (AffichageLu) sont stockées dans une liste interne au modèle, la table ne peut pas savoir quand tu modifies cette liste, donc il faut notifier la JTable, en appelant la méthode adaptée (dans ton cas, fireTableCellUpdated, méthode de AbstractTableModel, qui va dire à la JTable "hé, j'ai modifié la cellule x,y, fait ce que tu as à faire en conséquence).
    Ok maintenant je comprend mieux, j'avais toujours penser que les 2 étaient une même entité.

    JE ne sais pas ce qu'est ton GestionAffichageLu (d'autant plus que je n'en ai pas le code) et je ne vois pas à quoi il sert en plus.
    le code de cette classe
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
     
     
    @SuppressWarnings("serial")
    public class GestionAffichageLu extends JFrame implements ActionListener {
     
    	private JPanel contentPane;
    	private JTable table;
    	private AffichageLu model;
    	Manga manga;
     
    	ConnexionMangaLu con = new ConnexionMangaLu();
    	MiseAJourScans majr = new MiseAJourScans();
    	FormulaireLu form;
     
    	JComboBox<?> texte = new JComboBox<Object>();
    	AutoCompleteSupport<String> support;
     
    	private JPopupMenu popupMenu = new JPopupMenu();
    	private int selectedRow;
     
    	public GestionAffichageLu(int v){
     
    	}
     
    	@SuppressWarnings("static-access")
    	public GestionAffichageLu() {
     
    		this.setTitle("Mangas Lu");
     
    		Dimension dimension = java.awt.Toolkit.getDefaultToolkit()
    				.getScreenSize();
    		int height = (int) dimension.getHeight();
    		int width = (int) dimension.getWidth();
    		setBounds(-10, 0, width, height);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		contentPane.setLayout(new BorderLayout(0, 0));
    		// setContentPane(contentPane);
     
    		JPanel menu = new JPanel();
     
    		con.connection();
    		ArrayList<Manga> mangaList = con.getAllMangas();
     
    		model = new AffichageLu(mangaList);
     
    		table = new JTable();
    		table.setAutoCreateRowSorter(true); // initialisation du tri
    		table.setModel(model);
    		getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
     
    		final TableRowSorter<AffichageLu> sorter = new TableRowSorter<AffichageLu>(
    				model);
    		table.setOpaque(true);
    		table.setRowSorter(sorter);
     
    		texte.setPreferredSize(new Dimension(0, 0));
     
    		con.connection();
    		ArrayList<String> completion = con.lectureTitre();
     
    		// Créer un tableau de même taille que le nombre d'objet de ArrayList
    		String tab[] = new String[completion.size()];
     
    		// Transforme Le ArrayList en Tableau
    		tab = completion.toArray(tab);
     
    		final EventList<String> liste = GlazedLists.eventListOf(tab);
     
    		support = AutoCompleteSupport.install(texte, liste);
    		/* recherche des correspondance des lettres entrées */
    		support.setFilterMode(TextMatcherEditor.CONTAINS);
     
     
     
    		table.addMouseListener(new MouseAdapter() {
    			@Override
    			public void mouseReleased(MouseEvent e) {
    				if (e.getButton() == MouseEvent.BUTTON3) {
    					showPopup(e);
    				}
    			}
    		});
     
     
    		JMenuItem menuItem3 = new JMenuItem("MAJ derniere lecture");
     
     
    		menuItem3.setActionCommand("");
     
    		menuItem3.addActionListener((ActionListener) this);
     
     
    		menuItem3.addActionListener(new MAJDerniereLecture());
     
     
     
     
    		popupMenu.add(menuItem3);
     
    		String[] items = { "Tous", "En Cours", "Terminer" };
    		JComboBox<String> combobox = new JComboBox<>(items);
     
    		JButton couleur3 = new JButton(" Nouveau Chapitre");
     
     
    		JLabel labelVide3 = new JLabel();
     
    		maj.setFont(fontCouleur);
    		button.setFont(fontCouleur); 
    		nouv.setFont(fontCouleur);
     
    		GridLayout boutons = new GridLayout(18, 2, 0, 10);
    		menu.setLayout(boutons);
    		menu.setBorder(BorderFactory.createEmptyBorder(5, 2, 20, 5));
     
    		texte.setOpaque(false);
     
    		ItemListener listener = new ItemListener() {
    			public void itemStateChanged(ItemEvent e) {
    				if (e.getStateChange() == ItemEvent.SELECTED) {
    					String filtrage = combobox.getSelectedItem().toString();
     
    					/**
                                             * si selection sur combocox = Tous, on remet le filtrage a
                                             * null sinon filtrage selon le choix
                                             ***/
    					if (!filtrage.equals("Tous"))
    						sorter.setRowFilter(RowFilter.regexFilter(filtrage));
    					else {
    						sorter.setRowFilter(null);
    					}
     
    				}
    			}
    		};
     
    		combobox.addItemListener(listener);
     
    		button.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				String text = texte.getSelectedItem().toString().toUpperCase();
    				if (text.length() == 0) {
    					sorter.setRowFilter(null);
    				} else {
    					sorter.setRowFilter(RowFilter.regexFilter(text, 0));
    				}
    			}
    		});
     
    		maj.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				close();
    				if (!majr.majScans(0, 1))
    					new GestionAffichageLu();
    			}
    		});
     
    		nouv.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				form = new FormulaireLu("");
    			}
    		});
    		table.setDefaultRenderer(Object.class, new MonCellRenderer());
     
     
    		menu.add(couleur3);
     
    		getContentPane().add(menu, BorderLayout.WEST);
    		setVisible(true);
     
    		// this.setDefaultLookAndFeelDecorated(true);
    		this.setExtendedState(this.MAXIMIZED_BOTH); // met la taille au maximum
    													// par defaut
    	}
     
    	private void close() {
    		this.dispose();
    	}
     
    	public int getSelectedRow() {
    		return selectedRow;
    	}
     
    	private void showPopup(MouseEvent e) {
    		if (e.isPopupTrigger()) {
    			Point p = new Point(e.getX(), e.getY());
    			selectedRow = table.rowAtPoint(p); // recuperation de la ligne
    			popupMenu.show(e.getComponent(), e.getX(), e.getY());
    		}
    	}
     
     
    	/***   Menu clic droit  : Mise à Jour *****/
    	private class MAJDerniereLecture extends AbstractAction {
    		private MAJDerniereLecture() {
    			super("MAJDerniereLecture");
    		}
     
    		public void actionPerformed(ActionEvent e) {
     
    			Object cellule = table.getValueAt(selectedRow, 0);
    			new FormulaireMiseAJour(cellule.toString());
    			// System.out.println("GestionAffichageLu: MAJDerniereLecture: test attente");
     
    		}
    	}
     
     
    	/* affichage */
    	class MonCellRenderer extends DefaultTableCellRenderer {
     
    		public Component getTableCellRendererComponent(JTable table,
    				Object value, boolean isSelected, boolean hasFocus, int row,
    				int column) {
     
    			Object valeurDernierChap = table.getModel().getValueAt(
    					table.convertRowIndexToModel(row), 2);
     
    			/* recuperation de l'etat de chaque cellule du tableau */
    			Component cell = super.getTableCellRendererComponent(table, value,
    					isSelected, hasFocus, row,column );
     
    			/* application de la police "Courier New" et de fond "bold + italic" */
    			cell.setFont(new Font("Courier New bold", Font.ITALIC, 15));
     
    			Object valeur = table.getValueAt(row, 4);
     
    			double val1 = 0;
    			double val2 = 0;
     
    			try {
    				val1 = Double.parseDouble((String) valeurDernierChap);
    				val2 = Double.parseDouble((String) valeur);
    			} catch (Exception e) {
    				// TODO: handle exception
    			}
     
     
     
    			String statusValue = null;
     
    			con.connection();
     
    			statusValue = con.recupStatut(table.getModel().getValueAt(
    					table.convertRowIndexToModel(row), 0).toString());
    			/*
    			 * application de couleur sur cellule selon le contenu de la cellule
    			 * *
    			 */
     
    			if (statusValue.equals("Terminer")) {
    				setBackground(Color.GRAY);
    				if (val1 > val2)
    				{
    					if (column == 2) {
    						setBackground(Color.GREEN);
    					}
    				}
     
     
    			} else if (statusValue.equals("En Cours")) {
    				setBackground(Color.CYAN);
     
    				if (val1 > val2)
    				{
    					if (column == 2) {
    						setBackground(Color.GREEN);
    					}
    				}
     
    			} else if (valeur == null) {
    				setBackground(Color.YELLOW);
    			} else {
    				setBackground(null);
    			}
     
    			return cell;
    		}
     
    	}
     
    	@Override
    	public void actionPerformed(ActionEvent arg0) {
    		// TODO Auto-generated method stub
     
    	}
     
     
     
     
     
    }
    personnellement je pense que c'est cette classe qui remplit le rôle de Controleur dans le MVC

    C'est quoi que tu appelles "tableau", la JTable ? Evite les termes qui peuvent porter à confusion (un tableau en Java c'est un tableau(par exemple [c]String[] array={"toto","titi"};[/code], et une JTable n'est pas un tableau).
    Désolé je n'ai pas fais attention je voulais effectivement parler de la JTable

    En ce qui concerne les classes, normalement c'est mieux d'avoir des classes de modèle, de vue et de controleur séparées, c'est plus souple et modulable. Mais e n'est pas obligatoire pour que ça fonctionne, et c'est probablement plus simple d'avoir qu'une seule classe. Et il est souvent plus simple d'intégrer le contrôleur à la vue pour accèder directement à ses composants graphiques, mais ça c'est quand on développe soi-même la vue
    Lorsque j'ai commencer a coder ce projet je le faisait au feeling ( vu que je commencais vraiment en java ), donc je ne l'ai pas implémenter sous la forme d'un MVC, et après quand connu MVC et vu ses interets je ne pouvais pas restructurer entierement mon code vu que j'avais deja trop de classe.

    Donc je te disais que je ne voyais pas le lien entre la JTable et ton GestionAffichageLu parce qu'a part un rôle de controleur, je ne voyais pas à quoi ça pouvait bien servir, mais comme il n'y en a pas (de lien avec une JTable), je ne vois pas à quoi il sert.
    C'est cette classe qui gere l'affichage ( coloration, selection, menu sur clic droit, . . . )

    Non, peu importe. Ce qui importe c'est mettre à jour les différents objets qui représentent la même chose lorsqu'il est nécessaire d'en utiliser plusieurs. Le mieux étant d'arriver à représenter une information par un objet unique, comme ça pas besoin de chercher à mettre à jour l'information à plusieurs endroits, et pas de risque que ça ne fonctionne pas ou que ça fonctionne à moitié. Mais ça peut être un peu plus complexe pour un débutant je le conçois.
    Je confirme, la manipulation des tables et des modèle d'es pas une mince affaire . Je conçois et je comprend très bien le besoin de n'avoir à modifier qu'une seule fois les données ( procédé que j'essai d'appliquer au maximum ) mais dans ce cas les données doivent forcément être modifié a 2 endroit, dans la BDD et dans la liste que contient le modèle ( je pense ).

    Alors, ce genre de truc, il faut que tu le marques quelque part, à côté de "ne jamais sauter à pieds joints sur un piège à ours armé" : "ne jamais instancier un objet juste pour ne pas avoir un null".
    On ne créé pas des instances juste pour le fun : une instance représente une unité de donnée, chaque instance étant distincte, ce qui signifie qu'une instance ne connait pas les autres (oublions les moyens qu'on pourrait mettre en place pour que si).
    Pour le coup c'est une grande nouvelle puisque je n'en savais rien.
    Mais prenons un exemple 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
     
     
    public class Affichage extends JFrame{
     
        public Affichage(){
        	this.setTitle("Mangas Lu");
        	setVisible(true);
        }
     
        public void test(){
        	this.dispose();
        }
     
    }
    Dans une 1ere classe on instancie cette classe Affichage elle s'affiche bien en créant une Frame, mais si dans une 2eme classe on veux simplement faire appel la méthode test() afin de justement fermer cette frame qui est ouverte on ne pourra pas le faire alors ce qui est la raison pour laquelle j'ai fais un 2eme constructeur ( en restant sur le meme exemple ) de ce style afin de pouvoir acceder a la classe sans avoir a reafficher une nouvelle frame tout en evitant d'avoir un pointeur sur null au moment de l'appel de la méthode.
    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
     
    public class Affichage extends JFrame{
     
       public Affichage(int v){
       }
       public Affichage(){
        	this.setTitle("Mangas Lu");
        	setVisible(true);
        }
     
        public void test(){
        	this.dispose();
        }
     
    }
    mais bon d'après ce que vous m'avez c'est a ne jamais faire, donc je suppose qu'il ya un procédé pour éviter ce genre de piège, que je serai bien content de connaitre, car j'ai deja eu plusieurs cas dans le meme style.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    Apres meilleur compréhension de vos explications,j'ai modifié le code afin qu'il recharger le la liste contenu dans le modèle completement pour ne plus avoir a ne modifié qu'une ligne mais toutes les lignes ( c'a m'avait l'air plus simple )

    Donc dans la classe GestionAffichageLiu j'ai ajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public void update(){
    		con.connection();
    		ArrayList<Manga> mangaList = con.getAllMangas();
     
    		model = new AffichageLu(mangaList);		
    		model.fireTableDataChanged();
     
    	}
    mais pour l'appeler dans la classe FormulaireMiseAJour je suis toujouts confronté au probleme du pointeur null du à la non initialisation de la classe appelé

    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
     
    	ok.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent event) {
     
    				System.out
    				.println("FOrmulaireMiseAJour : ok.addactionlistener -> ***   Test appel méthode"); 
     
    				if (con.majManga(getTitre2().toUpperCase(), getDernierScanLu())) {
    					close();
    				} else {
    					JOptionPane.showMessageDialog(null,
    							"La mise à jour à échouer\n Veuiller réessayer",
    							"Error", JOptionPane.ERROR_MESSAGE);		
    				} 
     
    				frame = new GestionAffichageLu();
    			//	frame.update();
     
    				close();
     
     
     
    			}
    		});

    donc pour l'instant avec les modification actuelles il fait bien la mise à jour de la base de donnée mais il ouvre une fenetre a chaque fois pour réafficher et ce n'es pas du tout ce que je veux

  13. #13
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par louisard Voir le message
    Apres meilleur compréhension de vos explications,j'ai modifié le code afin qu'il recharger le la liste contenu dans le modèle completement pour ne plus avoir a ne modifié qu'une ligne mais toutes les lignes ( c'a m'avait l'air plus simple )
    Je ne vois pas comment tu as pu comprendre que je parlais de recharger toutes les données.


    Donc dans la classe GestionAffichageLiu j'ai ajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public void update(){
    		con.connection();
    		ArrayList<Manga> mangaList = con.getAllMangas();
     
    		model = new AffichageLu(mangaList);		
    		model.fireTableDataChanged();
     
    	}
    [/quote]
    En l'occurence, ce que tu fais avec le modèle là ne sert à rien, puisqu'il n'est pas lié à la JTable. Il faudrait au moins faire un table.setModel(model); !

    Voici un 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
    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    public class DemoJTable {
     
    	public static void main(String[] args) {
     
    		// une fenêtre pour l'UI
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		ZeModel model = new ZeModel(); // création d'un modèle personalisé
    		JTable table = new JTable(model); // affectation du modèle à la JTable : ainsi elle connait ce modèle = cette instance de modèle
    		table.setRowSorter(new TableRowSorter<ZeModel>(model));
    		table.setFillsViewportHeight(true);
     
    		JPanel panel = new JPanel(new BorderLayout()); // un panel pour l'affichage
    		panel.add(new JScrollPane(table)); // la table au centre dans un scrollpane
     
    		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); // un panel pour les boutons
    		JButton reloadButton = new JButton("Recharger tout"); // un bouton pour recharger toutes les données
    		buttonPanel.add(reloadButton);
    		JButton modifyButton = new JButton("Modifier machin"); // un bouton pour modifier dans un formulaire la propriété machin
    		modifyButton.setEnabled(false);
    		buttonPanel.add(modifyButton);
    		panel.add(buttonPanel, BorderLayout.SOUTH); // le panel des boutons en dessous de la table
     
    		frame.add(panel);
     
    		DaoMock dao = new DaoMock(); // juste pour simuler une DB
    		model.setRows(dao.select()); // initialisation du modèle
     
    		reloadButton.addActionListener(e-> model.setRows(dao.select())); // action pour recharger les données
    		modifyButton.addActionListener(e-> modifyData(table, model, dao)); // action pour modifier machin
     
    		table.getSelectionModel().addListSelectionListener(e-> changeSelection(e.getValueIsAdjusting(), table, modifyButton)); // permet d'avoir le bouton de modification actif uniquement lorsqu'une seule ligne est sélectionnée
     
    		// affichage de la fenêtre
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static void modifyData(JTable table, ZeModel model, DaoMock dao) {
    		Window window = SwingUtilities.getWindowAncestor(table);
    		int rowSelected = table.getSelectedRow(); // ligne sélectionnée
    		int columnIndex = ZeModel.Column.MACHIN.ordinal(); // la colonne qu'on veut modifier
    		String value = (String) model.getValueAt(table.convertRowIndexToModel(rowSelected), columnIndex); // on récupère la valeur à modifier par le modèle
    		String newValue = JOptionPane.showInputDialog(window, "Saisie le machin :", value);  // affichage du formulaire
    		if ( newValue!=null && !value.equals(newValue) ) { // si l'utilisateur a validé sa saisie et qu'elle est différente de l'original
    			if ( dao.updateMachin( model.getRow(rowSelected).getId(), newValue) ) { // on met à jour la DB
    				// si la sauvegarde réussi, on met à jour le modèle
    				model.setValueAt(newValue, rowSelected, columnIndex); // et si pas d'erreur, on met à jour le modèle
    			}
    			else {
    				JOptionPane.showMessageDialog(window, "Erreur mise à jour");
    			}
    		}
    	}
     
    	private static void changeSelection(boolean valueIsAdjusting, JTable table, JButton modifyButton) {
    		if ( !valueIsAdjusting ) {
    			modifyButton.setEnabled(table.getSelectedRowCount()==1);
    		}
    	}
     
    	public static class ZeModel extends AbstractTableModel {
     
    		// la liste des colonnes à afficher
    		public enum Column {
    			NOMBRE("Nombre",int.class),
    			TRUC("Truc",String.class),
    			MACHIN("Machin", String.class);
     
    			private final String label;
    			private final Class<?> type;
    			private Column(String label, Class<?> type) {
    				this.label=label;
    				this.type=type;
    			}
     
    			public String getLabel() {
    				return label;
    			}
     
    			public Class<?> getType() {
    				return type;
    			}
     
    			public static Column of(int columnIndex) {
    				return Column.values()[columnIndex];
    			}
     
    		}
     
    		private final List<Data> datalist = new ArrayList<>();
     
    		// initialise le modèle
    		public void setRows(List<Data> data) { 
    			datalist.clear(); // supprime les données actuelles
    			datalist.addAll(data); // ajoute toutes les nouvelles données
    			fireTableDataChanged(); // notifie la JTable que les données ont changé
    		} 
     
    		// ajout d'une ligne (pour exemple)
    		public void addRow(Data data) {
    			if ( !datalist.contains(data) ) { // si la ligne n'est pas déjà dans le modèle
    				datalist.add(data); // on l'ajoute
    				fireTableRowsInserted(datalist.size()-1, datalist.size()-1); // on notifie la JTable qu'une nouvelle ligne a été ajoutée
    			}
    		}
     
    		// suppression d'une ligne (pour exemple)
    		public void removeRow(Data data) {
    			int index = datalist.indexOf(data); // on cherche la position de la données dans la liste
    			if (index>=0 ) { // si la donnée est présente dans la liste
    			   datalist.remove(index); // on la supprime
    			   fireTableRowsInserted(index, index);  // on notifie la JTable qu'une ligne a été supprimée
    			}
    		}
     
    		public Data getRow(int rowIndex) {
    			return datalist.get(rowIndex);
    		}
     
    		@Override
    		public int getColumnCount() {
    			return Column.values().length;
    		}
     
    		@Override
    		public int getRowCount() {
    			return datalist.size();
    		}
     
    		// récupère la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public Object getValueAt(int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case NOMBRE:
    				return data.getId();
    			case TRUC:
    				return data.getTruc();
    			case MACHIN:
    				return data.getMachin();
    			default:
    				throw new IllegalArgumentException();
    			}
    		}
     
    		// modifie la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public void setValueAt(Object value, int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case TRUC:
    				data.setTruc((String) value);
    				break;
    			case MACHIN:
    				data.setMachin((String) value);
    				break;
    			default:
    				throw new IllegalArgumentException();
    			}
    			fireTableCellUpdated(rowIndex, columnIndex); // notifie la table qu'on a modifié la donnée (on le fait systématiquement, on pourrait optimiser en comparant l'ancien et le nouveau et ne faire la notif que s'ils sont différents)
    		}
     
    		@Override
    		public String getColumnName(int columnIndex) {
    			return Column.of(columnIndex).getLabel();
    		}
     
    		@Override
    		public Class<?> getColumnClass(int columnIndex) {
    			return Column.of(columnIndex).getType();
    		}
     
    		@Override
    		public boolean isCellEditable(int rowIndex, int columnIndex) {
    			return false; // on utilise un formulaire pour modifier les données, on désactive donc toute saisie directe dans la JTable
    		}
     
    	}
     
    	// réprésente les informations à gérer
    	public static class Data {
     
    		private final int id;
    		private String truc;
    		private String machin;
     
    		public Data(int nombre, String truc, String machin) {
    			this.id=nombre;
    			this.truc=truc;
    			this.machin=machin;
    		}
    		public Data(Data data) {
    			this.id=data.id;
    			this.truc=data.truc;
    			this.machin=data.machin;
    		}
     
    		public int getId() {
    			return id;
    		}
     
    		public void setTruc(String truc) {
    			this.truc = truc;
    		}
     
    		public String getTruc() {
    			return truc;
    		}
     
    		public void setMachin(String machin) {
    			this.machin = machin;
    		}
     
    		public String getMachin() {
    			return machin;
    		} 
     
    		@Override
    		public String toString() {
    			return Arrays.asList(id, truc, machin).toString();
    		}
     
    	}
     
    	// cette classe simule la base de données, elle ne doit pas figurer dans une implémentation réelle
    	public static class DaoMock { 
     
    		private final List<Data> datalist = new ArrayList<>();
     
     
    		public DaoMock() {
    			for(int i=0; i<1000; i++) {
    				datalist.add(new Data(i, generate(), generate()));
    			}
    		}
     
    		// simule un select
    		public List<Data> select() { 
    			return datalist.stream().map(Data::new).collect(Collectors.toList());
    		} 
     
    		// simule un update
    		public boolean updateMachin(int id, String newMachin) {
    			boolean error = ThreadLocalRandom.current().nextBoolean(); // simule une erreur aléatoire
    			if ( !error ) {
    				datalist.stream().filter(data-> data.getId()==id).forEach(data-> data.setMachin(newMachin)); // modifie la donnée voulue
    			}
    			return error;
    		}
     
    		private static String generate() { // génère des chaines aléatoirement
    			StringBuilder sb=new StringBuilder();
    			for(int i=ThreadLocalRandom.current().nextInt(3, 8); i>=0; i--) {
    				char c = (char) ('a'+ThreadLocalRandom.current().nextInt(26));
    				sb.append(c);
    			}
    			return sb.toString();
    		}
     
    	}
     
    }


    mais pour l'appeler dans la classe FormulaireMiseAJour je suis toujouts confronté au probleme du pointeur null du à la non initialisation de la classe appelé
    [/QUOTE]
    Et moi, comme je n'ai toujours connaissance que d'une partie du code et des informations, je ne peux pas te dire où se situe le problème.

  14. #14
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par louisard Voir le message
    Ok maintenant je comprend mieux, j'avais toujours penser que les 2 étaient une même entité.
    le code de cette classe [CODE]

    @SuppressWarnings("serial")
    public class GestionAffichageLu extends JFrame implements ActionListener {
    Donc GestionAffichageLu, c'est la fenêtre qui affiche la JTable avec tous les trucs à gérer qui tourne autour. En MVC, c'est la vue et le controleur réunis, ce qui est une pratique courante.
    Mais tu ne peux pas afficher d'une part ta fenêtre avec new GestionAffichageLu().setVisible(true) et utiliser d'autre part un new GestionAffichageLu(0) pour manipuler la première fenêtre. Ce sont deux instances différentes, elles n'ont pas de lien. C'est comme si tu prenais une photo que tu la photocopiais, et que tu écrivais un truc sur la photocopie : le truc ne s'écrit pas sur l'original.


    Citation Envoyé par louisard Voir le message
    personnellement je pense que c'est cette classe qui remplit le rôle de Controleur dans le MVC
    Oui, c'est bien ça, mais c'est aussi, comme je le disais, la vue.

    Citation Envoyé par louisard Voir le message
    Lorsque j'ai commencer a coder ce projet je le faisait au feeling ( vu que je commencais vraiment en java ), donc je ne l'ai pas implémenter sous la forme d'un MVC, et après quand connu MVC et vu ses interets je ne pouvais pas restructurer entierement mon code vu que j'avais deja trop de classe.
    Swing est déjà plus ou moins MVC, donc en utilisant un composant comme la JTable, tu fais du MVC.

    Citation Envoyé par louisard Voir le message
    Je confirme, la manipulation des tables et des modèle d'es pas une mince affaire . Je conçois et je comprend très bien le besoin de n'avoir à modifier qu'une seule fois les données ( procédé que j'essai d'appliquer au maximum ) mais dans ce cas les données doivent forcément être modifié a 2 endroit, dans la BDD et dans la liste que contient le modèle ( je pense ).
    Je parlais au sein de l'application. Evidemment la base de données c'est autre chose. Quoiqu'il existe des systèmes qui rendent transparent cette dualité donnée sur serveur/donnée sur client, mais c'est une autre histoire./

    Citation Envoyé par louisard Voir le message
    Pour le coup c'est une grande nouvelle puisque je n'en savais rien.
    [...]
    mais bon d'après ce que vous m'avez c'est a ne jamais faire, donc je suppose qu'il ya un procédé pour éviter ce genre de piège, que je serai bien content de connaitre, car j'ai deja eu plusieurs cas dans le meme style.
    On utilise les références des objets pour ça, qu'on se passe par paramètres.

    Par exemple, avec l'exemple que je t'ai donnée, on pourrait faire :

    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    public class DemoJTable {
     
    	public static void main(String[] args) {
     
    		// une fenêtre pour l'UI
    		JFrame frame = new JFrame("Démo");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		ZeModel model = new ZeModel(); // création d'un modèle personalisé
    		JTable table = new JTable(model); // affectation du modèle à la JTable : ainsi elle connait ce modèle = cette instance de modèle
    		table.setRowSorter(new TableRowSorter<ZeModel>(model));
    		table.setFillsViewportHeight(true);
     
    		JPanel panel = new JPanel(new BorderLayout()); // un panel pour l'affichage
    		panel.add(new JScrollPane(table)); // la table au centre dans un scrollpane
     
    		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); // un panel pour les boutons
    		JButton reloadButton = new JButton("Recharger tout"); // un bouton pour recharger toutes les données
    		buttonPanel.add(reloadButton);
    		JButton modifyButton = new JButton("Modifier machin"); // un bouton pour modifier dans un formulaire la propriété machin
    		modifyButton.setEnabled(false);
    		buttonPanel.add(modifyButton);
    		panel.add(buttonPanel, BorderLayout.SOUTH); // le panel des boutons en dessous de la table
     
    		frame.add(panel);
     
    		DaoMock dao = new DaoMock(); // juste pour simuler une DB
    		model.setRows(dao.select()); // initialisation du modèle
     
    		reloadButton.addActionListener(new ReloadActionListener(model, dao)); // action pour recharger les données
    		modifyButton.addActionListener(new ModifyActionListener(table, model, dao)); // action pour modifier machin
     
    		table.getSelectionModel().addListSelectionListener(e-> changeSelection(e.getValueIsAdjusting(), table, modifyButton)); // permet d'avoir le bouton de modification actif uniquement lorsqu'une seule ligne est sélectionnée
     
    		// affichage de la fenêtre
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	private static class ReloadActionListener implements ActionListener {
     
    		private final ZeModel model;
    		private final DaoMock dao;
     
    		public ReloadActionListener(ZeModel model, DaoMock dao) {
    			this.model=model;
    			this.dao=dao;
    		}
     
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			model.setRows(dao.select());
    		}
     
     
    	}
     
    	private static class ModifyActionListener implements ActionListener {
     
    		private final JTable table;
    		private final ZeModel model;
    		private final DaoMock dao;
     
    		public ModifyActionListener(JTable table, ZeModel model, DaoMock dao) {
    			this.table=table;
    			this.model=model;
    			this.dao=dao;
    		}
     
    		@Override
    		public void actionPerformed(ActionEvent e) {
    	 		Window window = SwingUtilities.getWindowAncestor(table);
    			int rowSelected = table.getSelectedRow(); // ligne sélectionnée
    			int columnIndex = ZeModel.Column.MACHIN.ordinal(); // la colonne qu'on veut modifier
    			String value = (String) model.getValueAt(table.convertRowIndexToModel(rowSelected), columnIndex); // on récupère la valeur à modifier par le modèle
    			String newValue = JOptionPane.showInputDialog(window, "Saisie le machin :", value);  // affichage du formulaire
    			if ( newValue!=null && !value.equals(newValue) ) { // si l'utilisateur a validé sa saisie et qu'elle est différente de l'original
    				if ( dao.updateMachin( model.getRow(rowSelected).getId(), newValue) ) { // on met à jour la DB
    					// si la sauvegarde réussi, on met à jour le modèle
    					model.setValueAt(newValue, rowSelected, columnIndex); // et si pas d'erreur, on met à jour le modèle
    				}
    				else {
    					JOptionPane.showMessageDialog(window, "Erreur mise à jour");
    				}
    			}
    		}
     
    	}
     
     
    	private static void changeSelection(boolean valueIsAdjusting, JTable table, JButton modifyButton) {
    		if ( !valueIsAdjusting ) {
    			modifyButton.setEnabled(table.getSelectedRowCount()==1);
    		}
    	}
     
    	public static class ZeModel extends AbstractTableModel {
     
    		// la liste des colonnes à afficher
    		public enum Column {
    			NOMBRE("Nombre",int.class),
    			TRUC("Truc",String.class),
    			MACHIN("Machin", String.class);
     
    			private final String label;
    			private final Class<?> type;
    			private Column(String label, Class<?> type) {
    				this.label=label;
    				this.type=type;
    			}
     
    			public String getLabel() {
    				return label;
    			}
     
    			public Class<?> getType() {
    				return type;
    			}
     
    			public static Column of(int columnIndex) {
    				return Column.values()[columnIndex];
    			}
     
    		}
     
    		private final List<Data> datalist = new ArrayList<>();
     
    		// initialise le modèle
    		public void setRows(List<Data> data) { 
    			datalist.clear(); // supprime les données actuelles
    			datalist.addAll(data); // ajoute toutes les nouvelles données
    			fireTableDataChanged(); // notifie la JTable que les données ont changé
    		} 
     
    		// ajout d'une ligne (pour exemple)
    		public void addRow(Data data) {
    			if ( !datalist.contains(data) ) { // si la ligne n'est pas déjà dans le modèle
    				datalist.add(data); // on l'ajoute
    				fireTableRowsInserted(datalist.size()-1, datalist.size()-1); // on notifie la JTable qu'une nouvelle ligne a été ajoutée
    			}
    		}
     
    		// suppression d'une ligne (pour exemple)
    		public void removeRow(Data data) {
    			int index = datalist.indexOf(data); // on cherche la position de la données dans la liste
    			if (index>=0 ) { // si la donnée est présente dans la liste
    			   datalist.remove(index); // on la supprime
    			   fireTableRowsInserted(index, index);  // on notifie la JTable qu'une ligne a été supprimée
    			}
    		}
     
    		public Data getRow(int rowIndex) {
    			return datalist.get(rowIndex);
    		}
     
    		@Override
    		public int getColumnCount() {
    			return Column.values().length;
    		}
     
    		@Override
    		public int getRowCount() {
    			return datalist.size();
    		}
     
    		// récupère la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public Object getValueAt(int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case NOMBRE:
    				return data.getId();
    			case TRUC:
    				return data.getTruc();
    			case MACHIN:
    				return data.getMachin();
    			default:
    				throw new IllegalArgumentException();
    			}
    		}
     
    		// modifie la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public void setValueAt(Object value, int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case TRUC:
    				data.setTruc((String) value);
    				break;
    			case MACHIN:
    				data.setMachin((String) value);
    				break;
    			default:
    				throw new IllegalArgumentException();
    			}
    			fireTableCellUpdated(rowIndex, columnIndex); // notifie la table qu'on a modifié la donnée (on le fait systématiquement, on pourrait optimiser en comparant l'ancien et le nouveau et ne faire la notif que s'ils sont différents)
    		}
     
    		@Override
    		public String getColumnName(int columnIndex) {
    			return Column.of(columnIndex).getLabel();
    		}
     
    		@Override
    		public Class<?> getColumnClass(int columnIndex) {
    			return Column.of(columnIndex).getType();
    		}
     
    		@Override
    		public boolean isCellEditable(int rowIndex, int columnIndex) {
    			return false; // on utilise un formulaire pour modifier les données, on désactive donc toute saisie directe dans la JTable
    		}
     
    	}
     
    	// réprésente les informations à gérer
    	public static class Data {
     
    		private final int id;
    		private String truc;
    		private String machin;
     
    		public Data(int nombre, String truc, String machin) {
    			this.id=nombre;
    			this.truc=truc;
    			this.machin=machin;
    		}
    		public Data(Data data) {
    			this.id=data.id;
    			this.truc=data.truc;
    			this.machin=data.machin;
    		}
     
    		public int getId() {
    			return id;
    		}
     
    		public void setTruc(String truc) {
    			this.truc = truc;
    		}
     
    		public String getTruc() {
    			return truc;
    		}
     
    		public void setMachin(String machin) {
    			this.machin = machin;
    		}
     
    		public String getMachin() {
    			return machin;
    		} 
     
    		@Override
    		public String toString() {
    			return Arrays.asList(id, truc, machin).toString();
    		}
     
    	}
     
    	// cette classe simule la base de données, elle ne doit pas figurer dans une implémentation réelle
    	public static class DaoMock { 
     
    		private final List<Data> datalist = new ArrayList<>();
     
     
    		public DaoMock() {
    			for(int i=0; i<1000; i++) {
    				datalist.add(new Data(i, generate(), generate()));
    			}
    		}
     
    		// simule un select
    		public List<Data> select() { 
    			return datalist.stream().map(Data::new).collect(Collectors.toList());
    		} 
     
    		// simule un update
    		public boolean updateMachin(int id, String newMachin) {
    			boolean error = ThreadLocalRandom.current().nextBoolean(); // simule une erreur aléatoire
    			if ( !error ) {
    				datalist.stream().filter(data-> data.getId()==id).forEach(data-> data.setMachin(newMachin)); // modifie la donnée voulue
    			}
    			return error;
    		}
     
    		private static String generate() { // génère des chaines aléatoirement
    			StringBuilder sb=new StringBuilder();
    			for(int i=ThreadLocalRandom.current().nextInt(3, 8); i>=0; i--) {
    				char c = (char) ('a'+ThreadLocalRandom.current().nextInt(26));
    				sb.append(c);
    			}
    			return sb.toString();
    		}
     
    	}
     
    }
    Ou encore on peut se baser sur la portée des variables (note bien la différence de déclaration des classes d'action listener) :

    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
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    public class DemoJTable extends JFrame {
     
    	private final JTable table;
    	private final ZeModel model;
    	private final DaoMock dao;
     
    	public DemoJTable(String titre, DaoMock dao) {
    		super(titre);
    		this.dao=dao;
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		model = new ZeModel(); // création d'un modèle personalisé
    		table = new JTable(model); // affectation du modèle à la JTable : ainsi elle connait ce modèle = cette instance de modèle
    		table.setRowSorter(new TableRowSorter<ZeModel>(model));
    		table.setFillsViewportHeight(true);
     
    		JPanel panel = new JPanel(new BorderLayout()); // un panel pour l'affichage
    		panel.add(new JScrollPane(table)); // la table au centre dans un scrollpane
     
    		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); // un panel pour les boutons
    		JButton reloadButton = new JButton("Recharger tout"); // un bouton pour recharger toutes les données
    		buttonPanel.add(reloadButton);
    		JButton modifyButton = new JButton("Modifier machin"); // un bouton pour modifier dans un formulaire la propriété machin
    		modifyButton.setEnabled(false);
    		buttonPanel.add(modifyButton);
    		panel.add(buttonPanel, BorderLayout.SOUTH); // le panel des boutons en dessous de la table
     
    		add(panel);
     
    		model.setRows(dao.select()); // initialisation du modèle
     
    		reloadButton.addActionListener(new ReloadActionListener()); // action pour recharger les données
    		modifyButton.addActionListener(new ModifyActionListener()); // action pour modifier machin
     
    		table.getSelectionModel().addListSelectionListener(e-> changeSelection(e.getValueIsAdjusting(), table, modifyButton)); // permet d'avoir le bouton de modification actif uniquement lorsqu'une seule ligne est sélectionnée
     
    		// affichage de la fenêtre
    		setSize(600, 400);
    		setLocationRelativeTo(null);
     
    	}
     
    	private class ReloadActionListener implements ActionListener {
     
    		@Override
    		public void actionPerformed(ActionEvent arg0) {
    			model.setRows(dao.select());
    		}
     
    	}
     
     
    	private class ModifyActionListener implements ActionListener {
     
    		@Override
    		public void actionPerformed(ActionEvent e) {
    	 		Window window = SwingUtilities.getWindowAncestor(table);
    			int rowSelected = table.getSelectedRow(); // ligne sélectionnée
    			int columnIndex = ZeModel.Column.MACHIN.ordinal(); // la colonne qu'on veut modifier
    			String value = (String) model.getValueAt(table.convertRowIndexToModel(rowSelected), columnIndex); // on récupère la valeur à modifier par le modèle
    			String newValue = JOptionPane.showInputDialog(window, "Saisie le machin :", value);  // affichage du formulaire
    			if ( newValue!=null && !value.equals(newValue) ) { // si l'utilisateur a validé sa saisie et qu'elle est différente de l'original
    				if ( dao.updateMachin( model.getRow(rowSelected).getId(), newValue) ) { // on met à jour la DB
    					// si la sauvegarde réussi, on met à jour le modèle
    					model.setValueAt(newValue, rowSelected, columnIndex); // et si pas d'erreur, on met à jour le modèle
    				}
    				else {
    					JOptionPane.showMessageDialog(window, "Erreur mise à jour");
    				}
    			}
    		}
     
    	}
     
    	private static void changeSelection(boolean valueIsAdjusting, JTable table, JButton modifyButton) {
    		if ( !valueIsAdjusting ) {
    			modifyButton.setEnabled(table.getSelectedRowCount()==1);
    		}
    	}
     
    	public static void main(String[] args) {
     
    		// une fenêtre pour l'UI
    		new DemoJTable("Démo", new DaoMock()).setVisible(true);
     
    	} 
     
    	public static class ZeModel extends AbstractTableModel {
     
    		// la liste des colonnes à afficher
    		public enum Column {
    			NOMBRE("Nombre",int.class),
    			TRUC("Truc",String.class),
    			MACHIN("Machin", String.class);
     
    			private final String label;
    			private final Class<?> type;
    			private Column(String label, Class<?> type) {
    				this.label=label;
    				this.type=type;
    			}
     
    			public String getLabel() {
    				return label;
    			}
     
    			public Class<?> getType() {
    				return type;
    			}
     
    			public static Column of(int columnIndex) {
    				return Column.values()[columnIndex];
    			}
     
    		}
     
    		private final List<Data> datalist = new ArrayList<>();
     
    		// initialise le modèle
    		public void setRows(List<Data> data) { 
    			datalist.clear(); // supprime les données actuelles
    			datalist.addAll(data); // ajoute toutes les nouvelles données
    			fireTableDataChanged(); // notifie la JTable que les données ont changé
    		} 
     
    		// ajout d'une ligne (pour exemple)
    		public void addRow(Data data) {
    			if ( !datalist.contains(data) ) { // si la ligne n'est pas déjà dans le modèle
    				datalist.add(data); // on l'ajoute
    				fireTableRowsInserted(datalist.size()-1, datalist.size()-1); // on notifie la JTable qu'une nouvelle ligne a été ajoutée
    			}
    		}
     
    		// suppression d'une ligne (pour exemple)
    		public void removeRow(Data data) {
    			int index = datalist.indexOf(data); // on cherche la position de la données dans la liste
    			if (index>=0 ) { // si la donnée est présente dans la liste
    			   datalist.remove(index); // on la supprime
    			   fireTableRowsInserted(index, index);  // on notifie la JTable qu'une ligne a été supprimée
    			}
    		}
     
    		public Data getRow(int rowIndex) {
    			return datalist.get(rowIndex);
    		}
     
    		@Override
    		public int getColumnCount() {
    			return Column.values().length;
    		}
     
    		@Override
    		public int getRowCount() {
    			return datalist.size();
    		}
     
    		// récupère la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public Object getValueAt(int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case NOMBRE:
    				return data.getId();
    			case TRUC:
    				return data.getTruc();
    			case MACHIN:
    				return data.getMachin();
    			default:
    				throw new IllegalArgumentException();
    			}
    		}
     
    		// modifie la valeur de la ligne rowIndex et la colonne columnIndex
    		@Override
    		public void setValueAt(Object value, int rowIndex, int columnIndex) {
    			final Data data = datalist.get(rowIndex);
    			switch(Column.of(columnIndex)) {
    			case TRUC:
    				data.setTruc((String) value);
    				break;
    			case MACHIN:
    				data.setMachin((String) value);
    				break;
    			default:
    				throw new IllegalArgumentException();
    			}
    			fireTableCellUpdated(rowIndex, columnIndex); // notifie la table qu'on a modifié la donnée (on le fait systématiquement, on pourrait optimiser en comparant l'ancien et le nouveau et ne faire la notif que s'ils sont différents)
    		}
     
    		@Override
    		public String getColumnName(int columnIndex) {
    			return Column.of(columnIndex).getLabel();
    		}
     
    		@Override
    		public Class<?> getColumnClass(int columnIndex) {
    			return Column.of(columnIndex).getType();
    		}
     
    		@Override
    		public boolean isCellEditable(int rowIndex, int columnIndex) {
    			return false; // on utilise un formulaire pour modifier les données, on désactive donc toute saisie directe dans la JTable
    		}
     
    	}
     
    	// réprésente les informations à gérer
    	public static class Data {
     
    		private final int id;
    		private String truc;
    		private String machin;
     
    		public Data(int nombre, String truc, String machin) {
    			this.id=nombre;
    			this.truc=truc;
    			this.machin=machin;
    		}
    		public Data(Data data) {
    			this.id=data.id;
    			this.truc=data.truc;
    			this.machin=data.machin;
    		}
     
    		public int getId() {
    			return id;
    		}
     
    		public void setTruc(String truc) {
    			this.truc = truc;
    		}
     
    		public String getTruc() {
    			return truc;
    		}
     
    		public void setMachin(String machin) {
    			this.machin = machin;
    		}
     
    		public String getMachin() {
    			return machin;
    		} 
     
    		@Override
    		public String toString() {
    			return Arrays.asList(id, truc, machin).toString();
    		}
     
    	}
     
    	// cette classe simule la base de données, elle ne doit pas figurer dans une implémentation réelle
    	public static class DaoMock { 
     
    		private final List<Data> datalist = new ArrayList<>();
     
     
    		public DaoMock() {
    			for(int i=0; i<1000; i++) {
    				datalist.add(new Data(i, generate(), generate()));
    			}
    		}
     
    		// simule un select
    		public List<Data> select() { 
    			return datalist.stream().map(Data::new).collect(Collectors.toList());
    		} 
     
    		// simule un update
    		public boolean updateMachin(int id, String newMachin) {
    			boolean error = ThreadLocalRandom.current().nextBoolean(); // simule une erreur aléatoire
    			if ( !error ) {
    				datalist.stream().filter(data-> data.getId()==id).forEach(data-> data.setMachin(newMachin)); // modifie la donnée voulue
    			}
    			return error;
    		}
     
    		private static String generate() { // génère des chaines aléatoirement
    			StringBuilder sb=new StringBuilder();
    			for(int i=ThreadLocalRandom.current().nextInt(3, 8); i>=0; i--) {
    				char c = (char) ('a'+ThreadLocalRandom.current().nextInt(26));
    				sb.append(c);
    			}
    			return sb.toString();
    		}
     
    	}
     
    }
    A noter que le premier exemple que je t'ai donné utilise aussi la portée des variables mais également le fait qu'elles soient dit effectivly final (en d'autres termes, on ne pourrait pas utiliser d'autres instances en remplacement), alors qu dans le cas ci-dessus elles pourraient ne pas l'être.

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    Bonjour

    Ca fonctionne enfinnnnnnn ( bien qu'il m'ait fallu du temps pour comprendre entierement le code )

    Merci beaucoup pour les explications

    PS: j'ai une autre question

    J'essai faire tourner mon programme sur un autre PC, bien que j'ai installer le JRE je n'arrive pas à le faire tourner
    sur un pc avec W10 comme le mien : il tourne juste le debut du programme en me creant les repertoire
    sur un PC avec W8 : rien du tout

    auriez vous une idée de la raison de cela ?

    merci

  16. #16
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par louisard Voir le message
    J'essai faire tourner mon programme sur un autre PC, bien que j'ai installer le JRE je n'arrive pas à le faire tourner
    sur un pc avec W10 comme le mien : il tourne juste le debut du programme en me creant les repertoire
    sur un PC avec W8 : rien du tout
    Lance-le en console pour voir les exceptions.

  17. #17
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    sur mon pc ou sur les autres pc ?

  18. #18
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Sur celui où l'application ne fonctionne pas, évidemment.

  19. #19
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 41
    Points : 15
    Points
    15
    Par défaut
    J'ai essayer et me met ce message d'erreur " Erreur : impossible de trouver ou charger la classe principale OtakuNoShinbun.jar "

    d’ailleurs j'ai essayer sur mon PC aussi ( en console ) et il me met la même erreur, mais lorsque je le lance directement par l'executable sur mon PC il fonctionne très bien.

    Trop bizarre

  20. #20
    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
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Il n'y a rien de bizarre : il faut taper la bonne commande. Genre java -jar OtakuNoShinbun.jar, alors que toi tu tapes java OtakuNoShinbun.jar, donc Java s'attend à ce qu'il existe une classe s'appelant OtakuNoShinbun.jar.

Discussions similaires

  1. [XL-MAC 2011] Macro qui marche sous excel windows mais qui renvoie une erreur 438 sous mac
    Par xavion dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 25/10/2016, 13h53
  2. Clé qui renvoie une Erreur 403
    Par DiverSIG dans le forum IGN API Géoportail
    Réponses: 5
    Dernier message: 20/07/2016, 17h36
  3. [MySQL] Formulaire php qui renvoie une erreur a l'envoie dans la bdd
    Par Varghos dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 20/04/2014, 11h15
  4. Méthode générique qui renvoie une Map
    Par stof dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 01/03/2010, 14h37
  5. Requete sql vers ORACLE qui renvoi une erreur
    Par lilou77 dans le forum Oracle
    Réponses: 7
    Dernier message: 29/01/2007, 09h52

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