Solved

I can't refresh the contents of a JTable

Posted on 2009-04-01
48
309 Views
Last Modified: 2012-06-21
Hello:

I'm working on a little database aplication in Java, I have a JTable that gets the data from a MySQL database, the table loads the data OK, but when I try to refresh it if a row is inserted or updated the results are not updated
Here is the code I made:

The method refrescarGrilla is the method that fills the data when the table is displayed, the secon method is used to refresh the data
What am I doing wrong?
0
Comment
Question by:imarquez
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 21
  • 20
  • 5
  • +1
48 Comments
 
LVL 20

Expert Comment

by:Venabili
ID: 24038385
It will help if you actually post the code... :)
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24038388
where is the code?
btw, you will need to call fireTableDataChanged() or fireTableRowsInserted(int, int) after updating the data in the model!
0
 

Author Comment

by:imarquez
ID: 24038449
I attached a code snippet but didn't show

Here it is:


public void refrescarGrilla(){
        headVector.addElement("Nro Ped");
        headVector.addElement("Fecha Pedido");
        headVector.addElement("Cliente");
        headVector.addElement("Direccion");
        headVector.addElement("Articulo");
        headVector.addElement("Movil");
        headVector.addElement("Movil prox");
        headVector.addElement("Cantidad");
        headVector.addElement("Flete");
        headVector.addElement("Total");
        List lista;
        lista = Persistir.getInstancia().listarPedidos();
        DefaultTableModel modelo = new DefaultTableModel();
        modelo.setDataVector((Vector) lista, headVector);
        jTable1.setModel(modelo);
        modelo.addTableModelListener(jTable1);
        jTable1 = tblRes.autoResizeColWidth(jTable1, modelo);
        modelo.fireTableDataChanged();
    }

    public void actualizarGrilla(){

        List lista;
        lista = Persistir.getInstancia().listarPedidos();
        DefaultTableModel modelo = new DefaultTableModel();
        modelo.addTableModelListener(jTable1);
        modelo.setDataVector((Vector) lista, headVector);
        jTable1 = tblRes.autoResizeColWidth(jTable1, modelo);
        modelo.fireTableDataChanged();
       
    }
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 86

Expert Comment

by:CEHJ
ID: 24038509
refrescarGrilla should be called in the EventDispatchThread. Run the update in another thread.

Use the (execellently documented) SwingWorker to do this
0
 

Author Comment

by:imarquez
ID: 24038535
could you provide an example? I never used it before
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24038596
There are examples in the docs
0
 

Author Comment

by:imarquez
ID: 24038678
Do I need to create another class that extends SwingWorker or I should make the JTable extend it so I can call the method to refresh the table?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24039264
Create a subclass of SwingWorker. Call it TableRefresher of something
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24039426
try this and let me know,

public void refrescarGrilla(){
        headVector.addElement("Nro Ped");
        headVector.addElement("Fecha Pedido");
        headVector.addElement("Cliente");
        headVector.addElement("Direccion");
        headVector.addElement("Articulo");
        headVector.addElement("Movil");
        headVector.addElement("Movil prox");
        headVector.addElement("Cantidad");
        headVector.addElement("Flete");
        headVector.addElement("Total");
        List lista;
        lista = Persistir.getInstancia().listarPedidos();
        DefaultTableModel modelo = ( DefaultTableModel )jTable1.getModel();
        modelo.setDataVector((Vector) lista, headVector);
    }

SwingWorker is needed if you want to do the operations in separate threads!
0
 

Author Comment

by:imarquez
ID: 24039507
ksivananth, it didn't work, the table still doesn't show the update, I'll try using SwingWorker, but i still have no clue of how to do it, how can I run these methos in the eventDispatcher Thread using SwingWorker?
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24039636
>>it didn't work, the table still doesn't show the update

it should work, are you sure the reference of jTable1 is same?
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24039643
this simple example works,

class TableGUI extends JFrame implements ActionListener
{
      JTable tb;
      JButton bt;
      
      public TableGUI()
      {
            setTitle("This is a table GUI");
            setSize(300,300);
            setLayout(new BorderLayout());
            
          Object[][] studentDetails = {{new String("Mary"), new String("A101"), new Double(22.1)},{new String("John"), new String("A102"), new Double(25.1)}};
          String[] title = {"Name", "ID", "Score"};
          DefaultTableModel model = new DefaultTableModel( studentDetails, title ) ;
          tb = new JTable( model );            
          bt = new JButton("Score");
          bt.addActionListener(this);
          add(new JScrollPane(tb), BorderLayout.CENTER);
          add(bt, BorderLayout.SOUTH);
      }
      
      public void actionPerformed(ActionEvent ae)
      {
            int[] row = tb.getSelectedRows();
            if(row.length == 0)
            {
                Object[][] studentDetails = {{new String("Mary - 1"), new String("A101"), new Double(22.1)},{new String("John - 1"), new String("A102"), new Double(25.1)}};
                String[] title = {"Name", "ID", "Score"};
                DefaultTableModel model = ( DefaultTableModel )tb.getModel() ;
                model.setDataVector( studentDetails, title ) ;
            }
      }

      public static void main(String[] args)
      {
            JFrame f = new TableGUI();
            f.setVisible(true);
      }
}
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24039649
Actually in this case you can just update the model and call fireTableDataChanged in the doInBackground method
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24039656
do you see any exception?
0
 
LVL 20

Expert Comment

by:Venabili
ID: 24039667
>>it didn't work, the table still doesn't show the update
posting the code that did not work might help someone spot something wrong :) Just a note.
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24039672
if it doesn't work, it won't work with SwingWorker too!
0
 

Author Comment

by:imarquez
ID: 24039735
this is the code that updates an object to the database and calls for the actualizarGrilla method, which does refresh the updated rows

private void btnActualizarPedidoActionPerformed(java.awt.event.ActionEvent evt) {
        Persistir p = Persistir.getInstancia();
        int row = jTable1.getSelectedRow();
        Integer val =(Integer) jTable1.getValueAt(row, 0);
        Pedidos ped = new Pedidos();
        Articulos art = new Articulos();
        art=(Articulos) cboArticulos.getSelectedItem();
        int id = val;
        ped = p.buscarPedidoPorId(id);
        ped.setMovilAsignado((Moviles) cboMoviles.getSelectedItem());
       
        ped.setCantidad(Integer.parseInt(txtCantidad.getText()));
        ped.setFlete(Integer.parseInt(txtFlete.getText()));
        ped.setIdArticulo(art);
        ped.setMovilAsignado((Moviles) cboMoviles.getSelectedItem());
        ped.setObservaciones(txtObservaciones.getText());


        p.actualizarPedido(ped);
        actualizarGrilla();
}
0
 

Author Comment

by:imarquez
ID: 24039861
This is the full code for the class, it´s an  internal frame form generated with netbeans.
intFrmPedidos.zip
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24039909
>>private void btnActualizarPedidoActionPerformed(java.awt.event.ActionEvent evt) {

An intensive code that run in there must be moved into a background thread or it will block your GUI
0
 

Author Comment

by:imarquez
ID: 24039981
Ok, how do I move it to a background thread? I never did "thread management" before
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040046
>>how do I move it to a background thread

I would suggest you to resolve the problem in hand first and then move to thread as that would take some time for you to understand!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040081
>>this is the code that updates an object to the database and calls for the actualizarGrilla method, which does refresh the updated rows

I was under the impression that you are calling refrescarGrilla on button click!
0
 

Author Comment

by:imarquez
ID: 24040098
but, the problem in hand wouldn't be the refreshing of the table? wich would be solved moving those methods to another thread? excuse me if i'm lost, but this problem is driving me nuts and i haven't found a working solution in any other place
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040101
try this then,

public void actualizarGrilla(){

        List lista;
        lista = Persistir.getInstancia().listarPedidos();
        DefaultTableModel modelo = ( DefaultTableModel )jTable1.getModel();
        modelo.setDataVector((Vector) lista, headVector);
    }
0
 

Author Comment

by:imarquez
ID: 24040112
Yes, the button takes the selected object from the row, updates the object with new values and saves it back to de database, and refrescarGrilla is called at the end to reflect those changes
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040161
sorry I am lost with the method names! let me take the look at your complete code!
0
 

Author Comment

by:imarquez
ID: 24040202
refrescarGrilla would be "refreshGrid" and actualizarGrilla "updateGrid", the names are very similar so the confusion is understandable
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040206
the refrescarGrilla is called no where in the actionperformed method!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040221
all the places you are just calling actualizarGrilla!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040233
did you try my comment #24040101?
0
 

Author Comment

by:imarquez
ID: 24040397
ksivananth: I did try. The same thing, it's not refreshing the table. I don't have the slightest idea where the problem is. I'm starting to feel defeated because I did everithing I'm supposed to do (except the "thread thing") but nothing worked out
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040477
"thread thing" is just for efficience and won't fix the problem!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040517
can you check if
lista = Persistir.getInstancia().listarPedidos();
returns updated list?
0
 

Author Comment

by:imarquez
ID: 24040553
Sorry, my mistake. But I need to find where the problem is, I tried all the solutions people gave me but still nothing. You guys are my last hope

I'm starting to sound pathetic, sorry
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24040598
it would be lot easier for you to locate the problematic area if you debug the code line by line!
0
 

Author Comment

by:imarquez
ID: 24040807
I ran a debug line by line many times but there is not a single problem in the execution
0
 

Author Comment

by:imarquez
ID: 24042446
didn't anyone found a solution?
0
 

Author Comment

by:imarquez
ID: 24043066
Ok, I added a button that calls for the refreshing of the table.
Thing is if I update a record the table don't show the updates, if I hit the new button nothing happens.... After waiting a few seconds if I hit it again calling for actualizarGrilla() THE TABLE REFRESHES!!!!!! why is that?
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24046941
>>After waiting a few seconds if I hit it again calling for actualizarGrilla() THE TABLE REFRESHES!!!!!! why is that?

could be that it takes some time to save the data to DB table. so if you press the button before the data get saved to DB, you won't see the update in JTable but if wait for the data to be updated in DB and then hit that button you see the update!
0
 

Author Comment

by:imarquez
ID: 24048426
But the funny thing is that the List that gets the updated data is loaded normally and in time, so the delay has no sense, and I don't really know why is that.
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24048636
>>List that gets the updated data is loaded normally and in time

how do you say this?
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24048643
you can have some SOPs to know what happens when you click the button!
0
 

Author Comment

by:imarquez
ID: 24048748
After running a debug in Netbeans I added a watch to the List object that gets the result from the DB, the List gets de data updated, the model takes the new list but the changes are not shown in the table
0
 

Author Comment

by:imarquez
ID: 24048805
I tried to run the model and table updating processes in the background, it didn't throw any exception but the results are the same, no data updated in the table. Maybe I'm not doing it right.

public void actualizarGrilla(){
        SwingWorker<DefaultTableModel, Object> worker = new SwingWorker<DefaultTableModel, Object>(){

            @Override
            protected DefaultTableModel doInBackground(){
                Vector lista;
                lista = Persistir.getInstancia().listarPedidos();
                DefaultTableModel modelo = new DefaultTableModel();
                modelo.addTableModelListener(jTable1);
                modelo.setDataVector(lista, headVector);
                return modelo;
            }
            @Override
            protected void done(){
                try {
                    DefaultTableModel modelo = get();
                    jTable1 = tblRes.autoResizeColWidth(jTable1, modelo);
                    modelo.fireTableDataChanged();
                } catch (InterruptedException ex) {
                    Logger.getLogger(intFrmPedidos.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ExecutionException ex) {
                    Logger.getLogger(intFrmPedidos.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        };
        worker.execute();
     }
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24049008
if you use SwingWorker, in the doInBackground method you would do the DB update operation and in the done method you would get the updated list and set it to model!

>>Vector lista;
                lista = Persistir.getInstancia().listarPedidos();
                DefaultTableModel modelo = new DefaultTableModel();
                modelo.addTableModelListener(jTable1);
                modelo.setDataVector(lista, headVector);
>>

btw, the above code is not correct, refer my earlier comments where have taken the model from the table itself instead of creating it!
0
 
LVL 26

Expert Comment

by:ksivananth
ID: 24049018
and as I sadi earlier, SwingWorker won't solve the issue you have but its an efficient way of doing it!
0
 

Author Comment

by:imarquez
ID: 24049120
Ok, thanks for the advice, your patienece is admirable, I'm feeling like pain in the a.... sorry.  I already did take the model from the table in previous tryouts but the result is the same, that delay in the updating table process seems inexplicable
0
 

Accepted Solution

by:
imarquez earned 0 total points
ID: 24049573
I did a workaround to mimic the update to the table, instead of calling actualizarGrilla I changed the data directly in the cells of the table. It's like cheating but since we found no solution....

private void btnActualizarPedActionPerformed(java.awt.event.ActionEvent evt) {
        Persistir p = Persistir.getInstancia();
        int row = jTable1.getSelectedRow();
        Integer val =(Integer) jTable1.getValueAt(row, 0);
        Pedidos ped = new Pedidos();
        Articulos art = new Articulos();
        art=(Articulos) cboArticulos.getSelectedItem();
        int id = val;
        ped = p.buscarPedidoPorId(id);
        ped.setMovilAsignado((Moviles) cboMoviles.getSelectedItem());
       
        ped.setCantidad(Integer.parseInt(txtCantidad.getText()));
        ped.setFlete(Integer.parseInt(txtFlete.getText()));
        ped.setIdArticulo(art);
        ped.setMovilAsignado((Moviles) cboMoviles.getSelectedItem());
        ped.setObservaciones(txtObservaciones.getText());
        Cliente cli = ped.getIdcliente();

        p.actualizarPedido(ped);
        jTable1.setValueAt(ped.getId(), row, 0);
        jTable1.setValueAt(ped.getFechaPedido(), row, 1);
        jTable1.setValueAt(cli.getApellidonombre(), row, 2);
        jTable1.setValueAt(cli.getDireccion(), row, 3);
        jTable1.setValueAt(art.getNombre(), row, 4);
        jTable1.setValueAt(ped.getIdMovil(), row, 5);
        jTable1.setValueAt(ped.getIdMovil2(), row, 6);
        jTable1.setValueAt(ped.getCantidad(), row, 7);
        jTable1.setValueAt(ped.getFlete(), row, 8);
        jTable1.setValueAt(ped.getTotal(), row, 9);
//        actualizarGrilla();
}
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to get all the API from website? 11 161
numbers ascending pyramid 101 265
Html split(text) 2 49
using executorService 3 22
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question