JTable sobre JTable

Iniciado por CartosP, 14 Marzo 2018, 14:30 PM

0 Miembros y 1 Visitante están viendo este tema.

CartosP


Buenos días amigos, tengo un problema que me esta atormentando y al que no consigo darle una solución. Cuando le extraigo los datos una BBDD y se los agrego a la tabla todo va bien. Si presiono sobre otra pestaña se me carga la siguiente tabla sin problemas, pero si hago un clip sobre algún elemento de la segunda tabla cargada, se me visualiza la primero tabla que cargue y no logro eliminar esa tabla que permanece en segundo plano.

Este es mi código y muchas gracias de antemano.


import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

public class Principal {

   public static void main(String[] args) {
      
      MarcoProductos marco1=new MarcoProductos();
      marco1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      marco1.setVisible(true);

   }

}

class MarcoProductos extends JFrame{
   
   JPanel superior=new JPanel();
   private JComboBox nombreTablas=new JComboBox();
   private DatabaseMetaData datosBBDD;
   private ResultSet rs;
   private Connection con;
   private Statement st;
   private ResultSetModeloTabla modelo;
   //private DefaultTableModel modelo2;
   //private JButton reiniciar=new JButton("Reiniciar");
   
   
   
   public MarcoProductos() {
      setTitle("Productos");
      setBounds(400,300,800,400);
      
      try {
         con=DriverManager.getConnection("jdbc:mysql://localhost:8889/ping", "", "");         
         datosBBDD=con.getMetaData();
         rs=datosBBDD.getTables(null, null, null, null);
         
         while(rs.next()) {
            //Para conseguir los nombres de la tabla
            nombreTablas.addItem(rs.getString("TABLE_NAME"));
         }
         
         
      } catch (SQLException e) {
         
         e.printStackTrace();
      }
      //------------------------------------------------------------------------>>Action
      
      nombreTablas.addActionListener(new ActionListener() {

         
         public void actionPerformed(ActionEvent e) {
            
            String tablaSeleccionada=(String) nombreTablas.getSelectedItem();
            String consulta="SELECT * FROM "+tablaSeleccionada;
            
            try {
               st=miConexion.createStatement();
               rs=st.executeQuery(consulta);
               modelo=new ResultSetModeloTabla(rs);
               JTable tabla=new JTable();
               tabla.setModel(modelo);
               
               add(new JScrollPane(tabla),BorderLayout.CENTER);
               validate();
               
            } catch (SQLException e1) {
               
               e1.printStackTrace();
            }
            
         }
         
      });
            
      superior.add(nombreTablas);
      
      //add(reiniciar,BorderLayout.SOUTH);
      add(superior,BorderLayout.NORTH);
   }
   
   
}

class ResultSetModeloTabla extends AbstractTableModel{

   private ResultSet rsRegistro;
   private ResultSetMetaData resmd;
   
   
   public ResultSetModeloTabla(ResultSet unResultset) {
      
      rsRegistro=unResultset;
      try {
         resmd=rsRegistro.getMetaData();
      } catch (SQLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }   
   }
   
   @Override
   public int getRowCount() {
      
      try {
         rsRegistro.last();
         return rsRegistro.getRow();
      } catch (SQLException e) {
         
         e.printStackTrace();
         return 0;
      }
         
   }

   @Override
   public int getColumnCount() {
      
      try {
         return resmd.getColumnCount();
      } catch (SQLException e) {
         
         e.printStackTrace();
         return 0;
      }
   }

   @Override
   public Object getValueAt(int rowIndex, int columnIndex) {
      
      try {
         rsRegistro.absolute(rowIndex+1);
         return rsRegistro.getObject(columnIndex+1);
      } catch (SQLException e) {
         
         e.printStackTrace();
         return null;
      }
      
   }
   public String getColumnName(int c) {
      
      try {
         return resmd.getColumnName(c+1);
      } catch (SQLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
         return null;
      }
   
   }
      
}

srWhiteSkull

El problema seguramente no lo tienes en la tabla, pues se instancia cada vez que se produce la acción. Pienso que te falta limpiar el JComboBox que es donde contienes la tabla. Tendrías que limpiarla en el mismo actionPerformed(). Creo que tiene un método denominado *removeAll() o similar, consulta la documentación de Oracle.

https://docs.oracle.com/javase/7/docs/api/javax/swing/JComboBox.html#removeAllItems()

PD removeAllItems()

CartosP

Muchas gracias por tu respuesta srWhiteSkull, el problema es la superposición de las tablas, cuando invoco la primera, esta se queda se cimiento para todas las otras y al hacer un clip sobre la tabla lo que sucede es que en lugar de darme la información del elemento superior no me da ninguna, ya que no puede encontrar el elemento que estoy pulsando. Pero igualmente probé lo que me recomendaste y no dio un resultado adecuado. Cuelgo lo que hice.

      //------------------------------------------------------------------------>>Action
      
      nombreTablas.addActionListener(new ActionListener() {
         
         
         public void actionPerformed(ActionEvent e) {
            
            
            
            String tablaSeleccionada=(String) nombreTablas.getSelectedItem();
            String consulta="SELECT * FROM "+tablaSeleccionada;
            Connection con=null;
            ResultSet rs2;
            ResultSet rsJCombo;
            Statement st;
            DatabaseMetaData datosJCombo;
            nombreTablas.removeAllItems();
            try {

               con=DriverManager.getConnection("jdbc:mysql://localhost:8889/possling", "root", "root");
               datosJCombo=con.getMetaData();
               rsJCombo=datosJCombo.getTables(null, null, null, null);
               while(rsJCombo.next()) {
                  nombreTablas.addItem(rsJCombo.getString("TABLE_NAME"));
               }
               
               
               
               st=con.createStatement();
               rs2=st.executeQuery(consulta);
               modelo=new ResultSetModeloTabla(rs2);
               JTable tabla=new JTable();
               tabla.setModel(modelo);
               
               add(new JScrollPane(tabla),BorderLayout.CENTER);
               validate();
               
            } catch (SQLException e1) {
               
               e1.printStackTrace();
            }
            
         }
         
      });
         
En cada llamada refresco los datos del JComboBox.

srWhiteSkull

#3
Bueno, pues olvídate del removeAllItems() y te propongo que lo hagas de otra manera.

Primero en el constructor mete la tabla en un panel, por ejemplo al que denominas superior (no lo metas en el ComboBox). Agrégalo al final, después de haber agregado otros componentes como el ComboBox.

Luego, una vez que se produzca la acción, que en tú caso lo has puesto cuando despliegues el ComboBox, podrías tomar la tabla rebuscando en la jerarquía. Por ejemplo, en tú caso el ComboBox es el objeto de la acción e.getSource(), y su padre es el panel, superior, (JPanel)((JComboBox)e.getSource()).getParent(), y a su vez coges el último componente que se añadió al panel que fue la tabla, getComponent(superior.getComponentsCount()-1). Una vez que tienes la tabla simplemente bien podrías modificar celda por celda cogiendo previamente su modelo, tabla.getModel(), o bien podrías no complicarte la vida y eliminas la tabla del panel, y luego la vuelves a añadir (instanciando new JTable(modelo)), y al final invocas el método updateUI() de la tabla. Basicamente es trabajar con las referencias de los objetos.

Eso sería lo sencillo, ahora si quieres complicarte lo ideal es que definieras un modelo personalizado con un método para modificar el contenido del modelo, en el cual tendrías uqe usar bucles y tomar los array.

Suerte

CartosP

#4
Buenas noches muchas gracias por tu respuesta srWhiteSkull, al final estoy empezando a ver la luz al final del túnel. E optado por la segunda opción y creo que será la correcta porque ya no se solapan las capas. Pero soy novato programando y no se como continuar, me podrías echar una ayuda para que se limpie la tabla del todo y poder cargar los nuevos elementos? en la parte que tengo el modelo.removeRow(i); peta y creo que es porque tengo que limpiarlo como si fuera una matriz. Muchas gracias nuevamente. Por cierto como elimino una tabla de un panel, para poder crear una nueva instancia?


class Marco3 extends JFrame{
   
   ArrayList<Empleado> listaEmpleado=new ArrayList<Empleado>();
   private  Connection con;
   private  ResultSet rs;
   private  Statement st;
   JPanel panel1=new JPanel();
   JButton boton1=new JButton("Tabla 1");
   JButton boton2=new JButton("Tabla 2");
   JLabel titulo=new JLabel("Tablas descargadas");
   
   private String [] nombreColumnas= {"Nif","Nombre","Apellido","Edad"};
   DefaultTableModel modelo=new DefaultTableModel(null,nombreColumnas);
   JTable tabla=new JTable(modelo);
   JScrollPane scroll=new JScrollPane(tabla);

   
   public Marco3() {
      
      setTitle("Los Planetas");
      setBounds(300,300,700,450);
      panel1.setLayout(null);
      boton1.setBounds(150, 10, 150, 30);
      boton2.setBounds(350, 10, 150, 30);
      scroll.setBounds(5, 40,690, 300);
      
      try {
         
         con=DriverManager.getConnection("jdbc:mysql://localhost:8889/prueba", "root", "root");
         st=con.createStatement();
         rs=st.executeQuery("SELECT * FROM DATOS");
         while(rs.next()) {
            
            Object[] datos= {rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4)};
            modelo.addRow(datos);
         }
         con.close();
         rs.close();
      } catch (SQLException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      

      tabla.setModel(modelo);
      panel1.add(scroll);
      //System.out.println(tabla.getModel().getValueAt(1, 1));
      
      
      //-----------------------------------------------------------------Evento Boton
      boton1.addActionListener(new ActionListener() {
         

         public void actionPerformed(ActionEvent e) {
               
            
            int tamano=modelo.getRowCount();
      
            for(int i=0;i<tamano;i++) {
               
               modelo.removeRow(i);
               
            }
            //tabla.removeAll();
            //System.out.println(modelo.getRowCount());
            
            try {
                  
               con=DriverManager.getConnection("jdbc:mysql://localhost:8889/prueba", "root", "root");
               st=con.createStatement();
               rs=st.executeQuery("SELECT * FROM datos2");
                  
               while(rs.next()) {
                     
                     Object[] datos= {rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4)};
                     modelo.addRow(datos);
                  }   
               con.close();
               rs.close();
               } catch (SQLException e2) {
                  // TODO Auto-generated catch block
                  e2.printStackTrace();
               }
               
               
               tabla.setModel(modelo);
               panel1.add(scroll);
               validate();
               
            }
      
      });
      
      
      
      panel1.add(boton1);
      panel1.add(boton2);
      
      add(panel1);
      
   }   
   
}

//---------------------------------------------------------------------------->>Clase Empleado
class Empleado{
   
   private String nif;
   private String nombre;
   private String apellido;
   private String edad;
   
   public Empleado(String nif,String nombre,String apellido,String edad) {
      this.nif=nif;
      this.nombre=nombre;
      this.apellido=apellido;
      this.edad=edad;
      
   }
   
   public String dameNif() {
      
      return nif;
   }
   public String dameNombre() {
      
      return nombre;
   }
   public String dameApellido() {
      
      return apellido;
   }
   public String dameEdad() {
      
      return edad;
   }
   
}

srWhiteSkull

#5
No hombre yo te decía así :

...
...
   
       nombreTablas.addActionListener(new ActionListener() {
...
...

               JPanel superior=(JPanel) ((JComboBox)e.getSource()).getParent(); // tomamos la referencia del panel (el padre del combobox)
               JTable tabla=new JTable(modelo); // creamos nueva tabla con el modelo de la consulta                
               superior.remove(superior.getComponentCount()-1); // eliminamos la anterior tabla, que fue el ultimo elemento en agregarse                
               superior.add(tabla,BorderLayout.CENTER); // agregamos nuestra recien creada tabla
               tabla.updateUI(); // actualizamos la tabla
...
...                
       });


...
...
       superior.add(nombreTablas);
       add(superior,BorderLayout.NORTH);

       JTable tabla=new JTable(modelo); // definido mas arriba al comienzo del constructor
       tabla.setName("tabla");
       tabla.setPreferredSize(new Dimension(800, 400)); // es bueno definir la dimension de los componentes
       superior.add(tabla,BorderLayout.CENTER);
       nombreTablas.validate();


Otra forma más sencilla implicaría recorrer la tabla celda por celda usando el método setValueAt() de la tabla o modelo. Pero tendrías que tomar la referencia de alguno de los dos, el modelo o la tabla ya creados.

https://docs.oracle.com/javase/tutorial/uiswing/components/table.html

CartosP

Muchísimas gracias, problema soluciona. Ya podré dormir al fin y ahora también se eliminar un objeto de un panel. Tenia tres días sin dormir bien, muchas gracias enserio srWhiteSkull.