I've been coding a program and I've faced several issues that I was able to address properly. However, my program is throwing a ConcurrentModificationException
and I'm not sure what I can do.
I'm coding with NetBeans 8.0.2 to create a Java desktop application (as required by my professor). The aim of the program is to manage a hotel. So, it has some parts like "Customers", "Staff" and "Booking" (the one giving me problems).
On each part, I have a JTable
that uses a DefaultTableModel
. In every part, I'm using files on the hard drive to make the changes persistent. I've coded new customer/staff classes. Now, I'm trying to code booking and unbooking methods. Everything has gone pretty well until I got to the "unbooking" part.
After the table and model I have an ArrayList
. In this particular part, I have three of them:
The booking part was fine, I'm able to modify the table, the file and the ArrayList
without any errors, and my program actually does what it should. But I'm unable to get the unbooking part to work. It should basically be the reverse of booking.
I will post a small part of my code, but if you need to know anything else or need some more parts of my code I would gladly share it.
My code:
public class GestionInstalaciones extends javax.swing.JFrame {
private final String ruta = System.getProperties().getProperty("user.dir");
private final File archivo = new File (ruta+"\\Instalaciones.txt");
private final DefaultTableModel modelo = new DefaultTableModel();
private final ArrayList contenidoInstalaciones;
private final ArrayList contenidoInstalacionesOcupadas;
private final ArrayList contenidoInstalacionesLibres;
public GestionInstalaciones() {
initComponents ();
contenidoInstalaciones = new ArrayList();
contenidoInstalacionesOcupadas = new ArrayList();
contenidoInstalacionesLibres = new ArrayList();
//Añadimos las columnas a la tabla.
modelo.addColumn ("Tipo");
modelo.addColumn ("Nombre Instalacion");
modelo.addColumn ("NIF del Ocupante");
cargarTabla();
}
private void cargarTabla(){
this.contenidoInstalaciones.clear();
FileReader fr = null;
BufferedReader br;
String tipo;
String nombre;
String NIFocupante;
String[] partes;
String linea;
try{
fr = new FileReader(archivo);
br = new BufferedReader(fr);
while ((linea=br.readLine())!=null) {
//Adding info to general ArrayList
this.contenidoInstalaciones.add(linea);
//Splitting line into 3 components.
partes = linea.split(",",3);
tipo = partes[0];
nombre = partes[1];
NIFocupante = partes[2];
//Skipping header.
if ( tipo.equals( "Tipo" )) { continue; }
//Añadimos la fila al modelo.
modelo.addRow(partes);
}
TablaInstalaciones.setModel(modelo);
}
//Capturamos excepciones y cerramos fichero.
catch(IOException e) {}
finally { try { if ( null != fr ) { fr.close(); } } catch (IOException e2){ } }
}//end cargarTabla()
private void botonLiberarInstalacionActionPerformed(java.awt.event.ActionEvent evt) {
Object linea;
int contador=0;
String aux;
String tiposATrabajar = "";
String[] tiposAInsertar;
Iterator instalacionesOcupadas;
//Cleaning of already booked ArrayList.
//this.contenidoInstalacionesOcupadas.clear();
instalacionesOcupadas = contenidoInstalacionesOcupadas.iterator();
this.comboTipoALiberar.removeAllItems();
this.comboTipoALiberar.addItem("Seleccione");
//Reading the general Table.
for (int z = 0; z < TablaInstalaciones.getRowCount() ; z++) {
//The booking parameter is on the 3rd place.
if(!TablaInstalaciones.getValueAt(z,2).equals("")){
//Putting the line into the ArrayList for booked rooms..
linea = TablaInstalaciones.getValueAt(z,0) + "," + TablaInstalaciones.getValueAt(z,1) + "," + TablaInstalaciones.getValueAt(z,2);
this.contenidoInstalacionesOcupadas.add(linea);
contador++;
}
}
**//Reading the booked ArrayList to put the right values on the combobox related.
//===> THIS LINE IS GIVING THE ERROR !!!
while(instalacionesOcupadas.hasNext()) {**
aux = instalacionesOcupadas.next().toString().split(",",3)[0];
//Checking to add only 1 kind of each room type.
if(!tiposATrabajar.contains(aux)); {
if (tiposATrabajar.equals("")) { tiposATrabajar=aux; }
else { tiposATrabajar = tiposATrabajar + "," + aux; }
}
}
//
tiposAInsertar = tiposATrabajar.split(",");
//Adding the type into the combobox.
for (String elemento: tiposAInsertar){ this.comboTipoALiberar.addItem(elemento.replace(",","")); }
}
If the contents of the Collection
you are iterating through have been changed since the last time you have used an iterator, you will get an exception if you try to use or reuse it. Create a new one - as a general rule, don't reuse an iterator.
You are:
You should modify the list before creating the iterator.
Also, you should try to minimize the scope of local variables.
As opposed to:
Iterator<String> someIterator = strings.iterator();
while (someIterator.hasNext()) {
doSomething();
}
You should probably do:
for (Iterator<String> iter = strings.iterator(); iter.hasNext();) {
doSomething();
}
Of course, if you (as you said) do not need to modify the list, use a for-each loop:
for (String s : strings) {
doSomething();
}
Some unrelated points:
extends java.awt.JFrame
? Import it and use JFrame
instead.Iterator
only in front of your for
loop you wouldn't have had this problem.Collection
s will only err at run-time, while generic ones will give compile errors instead.