
Asumiré que saben como hacer una ventana como la mostrada, aunque de todas maneras planeo hacer un post sobre como hacer esto, dado que no es nada dificil.
Vamos al asunto, en la ventana Categorias vamos a agregar en nuestro boton un evento.
Ahora tendremos en el Editor netbeans algo similiar a esto:
Vamos a codear!!!
Para este ejemplo vamos a poner todo el codigo en esta clase [ESTO NO ES LO OPTIMO]
Premisas :
- Se utilizará la Base de Datos de ejemplo que viene con Netbeans
- Para este ejemplo se cargará en realidad la tabla Products de dicha base
- Se asume que conocen un poco de JDBC
Creamos nuestro query y abrimos la conexion a la base de datos:
private void jbtnListarActionPerformed(java.awt.event.ActionEvent evt) { //Definimos nuestro Query final String query = "select * from APP.PRODUCT"; //vamos a crear nuestra conexion a la BD conectar();
Este es el codigo para la conexion
private void conectar() { try { Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance(); String dbUrl = "jdbc:derby://localhost:1527/sample";//URL DE CONEXION A LA DB con = DriverManager.getConnection(dbUrl,"app","app"); } catch (InstantiationException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } catch (SQLException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } }
Intanciamos un objeto de nuestra clase SwingWorker, al hacerlo nos exige implementar el metodo doInBackground, que es donde se ejecutan nuestras operaciones asincronas.
Bueno vamos a crear algunos campos que seran de uso global dentro de SwingWorker, de manera que nuestra implementacion quedará algo asi:
private void jbtnListarActionPerformed(java.awt.event.ActionEvent evt) { SwingWorker worker=new SwingWorker < Void , Void="">() { @Override protected Void doInBackground() throws Exception { throw new UnsupportedOperationException("Not supported yet."); } }; }
//donde almacenaremos los datos ArraylistTableModel model; ArrayList datos; String[] cols = new String[8];//son 8 columnasAhora vamos poner nuestro propio codigo dentro de doInBackground.
protected Void doInBackground() throws Exception { datos = new ArrayList();//instanciamos try { //Creamos un Statement para ejecutar el query java.sql.PreparedStatement pstmt = con.prepareStatement(query); //ejecutamos el query pstmt.executeQuery(); // asignamos el resutaldo a rs java.sql.ResultSet rs = pstmt.getResultSet(); //asignamos la metadata java.sql.ResultSetMetaData rm = rs.getMetaData(); //creamos un array donde pondremos los nombres de columnas for (int i = 0; i < rm.getColumnCount(); i++) { cols[i] = rm.getColumnName(i+1).toString(); } //recorremos el Resultset while (rs.next()) {//mientras halla datos ArrayList fila = new ArrayList();//instanciamos donde almacenaremos los datos de cada fila for (int i = 1; i <= rm.getColumnCount(); i++) { fila.add(rs.getObject(i).toString()); } datos.add(fila);//agregamos la fila cargada setProgress(datos.size());//actualizamos el progreso } } catch (SQLException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } return null; }
La Clase ArraylistTableModel es una implementacion de AbstractTableModel que en este caso yo he hecho. Su implementacion aqui.
ArraylistTableModel.java
Por ultimo implementaremos el metodo done() que es quien especifica que se debe hacer cuando acabe el procedimiento asincrono.
Este codigo es dentro de la implementacion de SwingWorker
Para ir actualizando la barra de progreso agregamos un escuchador
final javax.swing.SwingWorker worker = new javax.swing.SwingWorker() { /* implementacion de campos */ @Override protected Void doInBackground() throws Exception { /* codigo de doInBackground */ } @Override protected void done() { setProgress(100);// hacemos el progreso a 100 jtblProductos.setModel(new ArraylistTableModel(datos, cols)); } };
worker.addPropertyChangeListener(new PropertyChangeListener() {//agregarmos un escuchador de cambio de propiedad public void propertyChange(PropertyChangeEvent pce) { progressBar.setValue(worker.getProgress());//actualizamos el valor del progressBar } });
Codigo completo
private void jbtnListarActionPerformed(java.awt.event.ActionEvent evt) { //iniciamos nuestra barra de progreso progressBar.setValue(0); //Definimos nuestro Query final String query = "select * from APP.PRODUCT"; //vamos a crear nuestra conexion a la BD conectar(); final javax.swing.SwingWorker worker = new javax.swing.SwingWorker() { //donde almacenaremos los datos ArraylistTableModel model; ArrayList datos; String[] cols = new String[8];//son 8 columnas @Override protected Void doInBackground() throws Exception { datos = new ArrayList();//instanciamos try { //Creamos un Statement para ejecutar el query java.sql.PreparedStatement pstmt = con.prepareStatement(query); //ejecutamos el query pstmt.executeQuery(); // asignamos el resutaldo a rs java.sql.ResultSet rs = pstmt.getResultSet(); //asignamos la metadata java.sql.ResultSetMetaData rm = rs.getMetaData(); //creamos un array donde pondremos los nombres de columnas for (int i = 0; i < rm.getColumnCount(); i++) { cols[i] = rm.getColumnName(i+1).toString(); } //recorremos el Resultset while (rs.next()) {//mientras halla datos ArrayList fila = new ArrayList();//instanciamos donde almacenaremos los datos de cada fila for (int i = 1; i <= rm.getColumnCount(); i++) { fila.add(rs.getObject(i).toString()); } datos.add(fila);//agregamos la fila cargada setProgress(datos.size());//actualizamos el progreso } } catch (SQLException ex) { Logger.getLogger(FrmProductos.class.getName()).log(Level.SEVERE, null, ex); } return null; } @Override protected void done() { setProgress(100); jtblProductos.setModel(new ArraylistTableModel(datos, cols)); } }; //agregamos un escuchador de cambio de propiedad worker.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent pce) { progressBar.setValue(worker.getProgress());//actualizamos el valor del progressBar } }); worker.execute(); }
Codigo completo de la clase
Clase de ejemplo utilizando swingworker
Final mente nuestra aplicacion se vera asi
Descarga aplicacion ejemplo Swingworker
ResponderEliminarGracias!!!!
ResponderEliminarprobando!
ResponderEliminarHola, te cuento que probé tu ejemplo con Motor MySql 5, esquema mysql, tabal help_topic que trae 506 registros... y que crees? NO me funcionó como yo epseraba, pues, el worker solamente me devuelve 100 registros y se detiene; además, el jprogressbar no me refleja el progreso de obtencion de datos pues se pasa de 0% a 100% en cuestion de un segundo.
ResponderEliminarMIra, como estoy haciendo una aplicacion que maneja muchisimsos registros, debo obligadamente implementar SW y lo he logrado, para ello implementé 2 RS's, el primero es para contar los registros y el segundo es para recorrerlos, así, al JPB (jprogressbar) le asigno un setMaximum dependiendo del total de regs. y en el while le voy agregando +1, de esta manera me funcioan perfecto y el JPB me refleja bien lo que el worker realiza.
Si tienes una solucion más práctica, por que supongo que la mía no lo es del todo, por favor remitemela y si crees que la mia lo es... estaré gustoso en enviarte un miniproyecto de java + mysql + swingworker para que pueda ser posteado en tu blog.
De antemano muchas gracias.
Estaré visitando más seguido tu blog en busca de mas respuestas y soluciones por que creeme que ando en mi proyecto de la Universidad y apenas estoy empezandolo... bueno, saludos desde Ecuador.
Hola Hamilton, disculpa por la demora en responder y te agradezco la visita, bueno si tienes razon en que el ejemplo puede que no se adecue a todas las circunstancias, yo tb lo he padecido al implementarlo en algunas aplicaciones.
ResponderEliminarMi solucion fue la siguiente, utilizar la clase javax.swing.Timer.
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getProgress() < 99) {
setProgress(getProgress() + 1);
}
}});
timer.start();
//Haz tus procesos
timer.stop();
Espero te sirva
y el metodo publish??
ResponderEliminar