omaza1990
omaza1990

Reputation: 144

Deleting rows JTable

I have a JTable where I want to delete selected rows but it doesn't work the right way.

I select a row, press Delete and it appears deleted from the table. I close the program, reopen it, and the same logs appear as initially. And if I select multiple rows, it doesn't delete.

¿Where is the error?

Code:

public class Listado_clientes extends javax.swing.JFrame{
    public Listado_clientes() {
        initComponents();

        try {
            DefaultTableModel modelo = new DefaultTableModel();
            tabla_clientes.setModel(modelo);

            PreparedStatement ps = null;
            ResultSet rs = null;
            Connection con = Conexiones.conexion_a_BBDD("agenda");

            String sql = "SELECT dni, nombre, apellidos, telefono, direccion, ciudad, email FROM clientes";
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();

            ResultSetMetaData rsMd = (ResultSetMetaData) rs.getMetaData();
            int cantidadColumnas = rsMd.getColumnCount();

            modelo.addColumn("DNI");
            modelo.addColumn("NOMBRE");
            modelo.addColumn("APELLIDOS");
            modelo.addColumn("TELEFONO");
            modelo.addColumn("DIRECCION");
            modelo.addColumn("CIUDAD");
            modelo.addColumn("EMAIL");

            //Crear las columnas de la tabla, con el ancho X.
            tabla_clientes.getColumnModel().getColumn(0).setPreferredWidth(90); //aquí el DNI
            tabla_clientes.getColumnModel().getColumn(1).setPreferredWidth(110);
            tabla_clientes.getColumnModel().getColumn(2).setPreferredWidth(160);
            tabla_clientes.getColumnModel().getColumn(3).setPreferredWidth(80);
            tabla_clientes.getColumnModel().getColumn(4).setPreferredWidth(140);
            tabla_clientes.getColumnModel().getColumn(5).setPreferredWidth(100);
            tabla_clientes.getColumnModel().getColumn(6).setPreferredWidth(150);

            //Recorrer el array e imprimir los datos en las celdas.
            while (rs.next()) {
                Object[] rows= new Object[cantidadColumnas];
                for (int i=0; i<cantidadColumnas; i++) {
                    rows[i] = rs.getObject(i+1);
                }
                modelo.addRow(rows);
            }
        } catch (SQLException ex) {
            System.err.println(ex.toString());
        }
    }


    private void button_eliminarActionPerformed(java.awt.event.ActionEvent evt) {                                                
        DefaultTableModel modelo = (DefaultTableModel) tabla_clientes.getModel();

        int row = tabla_clientes.getSelectedRow();
        int confirm = JOptionPane.showConfirmDialog(null, "¿Deseas eliminar los clientes?", "ADMINISTRADOR", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
        if (JOptionPane.OK_OPTION == confirm){
            if (fila >= 0) {
               int[] rowsselec  = tabla_clientes.getSelectedRows();

                for (int i=0; i<rowsselec.length; i++){
                    modelo.removeRow(rowsselec[i]);
                    String dni_delete = (String) tabla_clientes.getValueAt(i, 0);
                    Conexiones.eliminar_cliente(dni_delete);
                }
               label_contador.setText("There are "+Conexiones.contar_clientes()+" registered  clients.");
            }else{
                JOptionPane.showMessageDialog(null, "Debe seleccionar al menos un cliente.");
            }
        }
    }   
}

eliminar_cliente():

public static void eliminar_cliente(String DNI){
        String bbdd = Conexiones.bbdd;
        Connection c = (Connection) Conexiones.conexion_a_BBDD(bbdd);
        Statement stm;
        ResultSet rs;
        try{
            //Preparamos la consulta a realizar...
            stm = c.createStatement();
            //Consulta para eliminar un cliente en la base de datos.
            String eliminar_clientes = "DELETE FROM clientes WHERE dni = '"+DNI+"';";
            int resultado1 = 1;
            //System.out.println(eliminar_clientes);
            resultado1 = stm.executeUpdate(eliminar_clientes);
            if(resultado1<=0){
                throw new SQLException();
            }else{
                //System.out.println("Cliente eliminado de la tabla clientes.");
            }
            JOptionPane.showMessageDialog(null, "Borrado realizado con éxito.");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                c.close();
            } catch (SQLException ex) {
                Logger.getLogger(Conexiones.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Upvotes: 1

Views: 94

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

press Delete and it appears deleted from the table. I close the program, reopen it, and the same logs appear as initially

This is unlikely an issue with you table, but an issue with your database handling - since the row reappears when you re-run the program.

So, two things...

First, make sure that autoCommit is enabled, if not, you have to explicitly call Connection#commit to commit the transition, otherwise it will be automatically rollback when the connection is closed

Second, you really should be making use of PreparedStatements

String bbdd = Conexiones.bbdd;
Connection c = (Connection) Conexiones.conexion_a_BBDD(bbdd);
try (PreparedStatement stm = c.prepareStatement("DELETE FROM clientes WHERE dni = ?")) {
    //Consulta para eliminar un cliente en la base de datos.
    //String eliminar_clientes = "DELETE FROM clientes WHERE dni = '" + DNI + "';";
    stm.setString(1, DNI);
    int resultado1 = 1;
    //System.out.println(eliminar_clientes);
    resultado1 = stm.executeUpdate();
    if (resultado1 <= 0) {
        // No haría esto, devolvería el resultado, arrojar una excepción aquí podría causar otros problemas
        throw new SQLException();
    }
    c.commit();
} catch (SQLException ex) {
    ex.printStackTrace();
} finally {
    try {
        c.close();
    } catch (SQLException ex) {
        ex.printStackTrace();
    }
}

See Using Prepared Statements for more details.

You may also want to take a look at The try-with-resources Statement - it will make your life simpler

Updated

This seems wrong to me...

for (int i=0; i<rowsselec.length; i++){
    modelo.removeRow(rowsselec[i]);
    String dni_delete = (String) tabla_clientes.getValueAt(i, 0);
    Conexiones.eliminar_cliente(dni_delete);
}

you remove the row at i and then you get the value of for the first column of the row at i...but the row would have been removed from the table/model, so you'd be getting the next row's value ...

You should

  • Get the row id
  • Remove it from the database
  • Remove the row from the table

For example...

for (int i=0; i<rowsselec.length; i++){
    String dni_delete = (String) tabla_clientes.getValueAt(i, 0);
    Conexiones.eliminar_cliente(dni_delete);
    modelo.removeRow(rowsselec[i]);
}

This means that if something goes wrong, you will know it, because the row hasn't been removed from the table

Upvotes: 1

Related Questions