Bonjour.

J'ai un JTable qui contient des "JNumberField" (un JTextField qui n'accepte que des chiffres) et des JComboBox.

Le but c'est que l'ont puisse ajouter autant de lignes que l'on veux à ce tableau. Je vais essayer d'expliquer simplement : La dernière ligne du tableau est toujours vide (valeur 0 à chaque case). Si l'on modifie l'une de ces cases (dans la dernière ligne) le JTable ajoute une nouvelle ligne. Aussi, si on change une ligne en plein milieu pour en faire une ligne "vide" (valeur encore = à 0 à chaque case de cette ligne) elle s'efface automatiquement.

Mon problème :
J'ai essayer de reprendre un code, mais quand je fait ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
class TableModel extends AbstractTableModel{
	private Object[][] data;
.
.
.
	public void setValueAt(Object value, int row, int col)
	{
		this.data[row][col] = value;
	}
}
Et bien ce n'est pas juste le "data[row][col]" qui change mais data[toutes les lignes][col] ...

Pour vérifier j'ai essayer ça :
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
		public void setValueAt(Object value, int row, int col)
		{
			System.out.print(row + "x" + col + " : " + value + " = ");
			this.data[row][col] = value;
			for (int i = 0; i < getRowCount(); i++ )
				for (int j = 0; j < getColumnCount(); j++ )
					System.out.print(i + "x" + j + " : " + this.data[i][j] + " / ");
			System.out.println();
 
 
			System.out.print(row + "x" + col + " : " + value + " = ");
			this.data[row][col] = 2;
			for (int i = 0; i < getRowCount(); i++ )
				for (int j = 0; j < getColumnCount(); j++ )
					System.out.print(i + "x" + j + " : " + this.data[i][j] + " / ");
			System.out.println();
		}
Et j'ai obtenu ceci dans la console quand j'avais 2 lignes (tout était à 2, j'ai mis 1 dans la 2eme colonne) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
0x0 : 0 = 0x0 : 0 / 0x1 : 2 / 1x0 : 0 / 1x1 : 2 / 
0x0 : 0 = 0x0 : 2 / 0x1 : 2 / 1x0 : 2 / 1x1 : 2 / 
// Entré de la valeur
0x1 : 1 = 0x0 : 2 / 0x1 : 1 / 1x0 : 2 / 1x1 : 1 / 
0x1 : 1 = 0x0 : 2 / 0x1 : 2 / 1x0 : 2 / 1x1 : 2 /
Je sais pas du tout d'où peut venir ce problème donc je vous met la classe complette :
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
public class SkillTable extends JTable
{
	private static final String[] comboStrings =
		{"0", "1", "2"};
	public static final Object[] emptyRow =
		{0, comboStrings[0]};
	private static final String[] title =
		{"Niveau", "Compétence"};
 
	public SkillTable () {
		super();
		setModel(new TableModel(new Object[][]
			{emptyRow, emptyRow}, title));
		getColumn(title[0]).setCellEditor(new JComponentEditor(new JNumberField(0, 100))); // JNumberField(val mini, val maxi)
		getColumn(title[1]).setCellEditor(new JComponentEditor(new JComboBox<String>(comboStrings)));
	}
 
	// Model de la table
	public class TableModel extends AbstractTableModel
	{
		private Object[][] data;
		private String[] title;
 
		//Constructeur
		public TableModel (Object[][] data, String[] title) {
			this.data = data;
			this.title = title;
			setRowHeight(24);
		}
 
		//Retourne le nombre de colonnes
		public int getColumnCount()
		{
			return this.title.length;
		}
 
		//Retourne le nombre de lignes
		public int getRowCount()
		{
			return this.data.length;
		}
 
		//Retourne la valeur à l'emplacement spécifié
		public Object getValueAt(int row, int col)
		{
			return this.data[row][col];
		}
 
		//Retourne la valeur à l'emplacement spécifié
		public void setValueAt(Object value, int row, int col)
		{
			this.data[row][col] = value;
		}
 
		// Retourne le titre de la colonne à l'indice spécifié
		public String getColumnName(int col)
		{
			return this.title[col];
		}
 
		//Retourne la classe de la donnée de la colonne
		public Class getColumnClass(int col)
		{
			return this.data[0][col].getClass();
		}
 
		//Méthode permettant de retirer une ligne du tableau
		public void removeRow(int position)
		{
			int indice = 0, indice2 = 0;
			int nbRow = this.getRowCount() - 1, nbCol = this.getColumnCount();
			Object temp[][] = new Object[nbRow][nbCol];
 
			for (Object[] value : this.data)
			{
				if (indice != position)
				{
					temp[indice2++ ] = value;
				}
				indice++ ;
			}
			this.data = temp;
			temp = null;
 
			this.fireTableDataChanged();
		}
 
		//Permet d'ajouter une ligne dans le tableau
		public void addRow()
		{
			this.addRow(emptyRow);
		}
 
		//Permet d'ajouter une ligne dans le tableau
		public void addRow(Object[] data)
		{
			int indice = 0, nbRow = this.getRowCount(), nbCol = this.getColumnCount();
 
			Object temp[][] = this.data;
			this.data = new Object[nbRow + 1][nbCol];
 
			for (Object[] value : temp)
				this.data[indice++ ] = value;
 
			this.data[indice] = data;
			temp = null;
 
			this.fireTableDataChanged();
		}
 
		public boolean isCellEditable(int row, int col)
		{
			return true;
		}
	}
 
	// DefaultCellEditor avec ajout/suppression de lignes
	public class JComponentEditor extends DefaultCellEditor
	{
		public JComponentEditor (JTextField name) {
			super(name);
		}
 
		public JComponentEditor (JComboBox name) {
			super(name);
		}
 
		// On fait juste les ajout/retraits de lignes avant de renvoyer la cell
		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
				int row, int column)
		{
			check(row, column);
			return super.getTableCellEditorComponent(table, value, isSelected, row, column);
		}
 
		protected void check(int row, int column)
		{
			if (row == (getRowCount() - 1)) // Dernière case
			{
				TableModel model = ((TableModel) getModel());
				for (int i = 0; i < model.getColumnCount(); i++ ) // Pour chaque case
				{
					// On ajoute une ligne si elle n'est pas vide et on quitte
					Object o = model.getValueAt(row, i);
					if (o instanceof Integer)
					{
						int v = (Integer) o;
						if (v != 0)
						{
							addRow(row);
							return;
						}
					}
					else if (o instanceof String)
					{
						String v = (String) o;
						if (!(v.equals("") || v.equals("0")))
						{
							addRow(row);
							return;
						}
					}
				}
			}
			else
			{
				TableModel model = ((TableModel) getModel());
				for (int i = 0; i < model.getColumnCount(); i++ ) // Pour chaque case
				{
					// On quitte si la ligne n'est pas vide
					Object o = model.getValueAt(row, i);
					if (o instanceof Integer)
					{
						int v = (Integer) o;
						if (v != 0)
							return;
					}
					else if (o instanceof String)
					{
						String v = (String) o;
						if (!(v.equals("") || v.equals("0")))
							return;
					}
				}
 
				// la ligne est vide, on la supprime
				removeRow(row);
			}
		}
 
		private void addRow(int row)
		{
			((TableModel) getModel()).addRow();
 
			for (int i = 0; i < emptyRow.length; i++ )
			{
				//On affecte un nouveau libellé à une celulle de la ligne
				((AbstractTableModel) getModel()).setValueAt(emptyRow[i], row, i);
				//Permet de dire à notre tableau qu'une valeur a changé
				((AbstractTableModel) getModel()).fireTableCellUpdated(row, i);
			}
		}
 
		private void removeRow(int row)
		{
			if (getRowCount() > 1)
			{
				((TableModel) getModel()).removeRow(row);
			}
		}
	}
}