Search code examples
javaswingjtablejscrollpanedefaulttablemodel

Jtable doesn't refresh/update data


I have a problem with JTable/JScrollPane. My data table is not refreshing/updating. I am using DefultTableModel and according to the code everything is fine and I don't have any errors. Also I have a table with paging and that's why I am using action listeners and buttons "prev" and "next". I am passing from other function to function that is coded in class where is JTable. Problem is that I fill arrays which contains data for table but table won't update/refresh it. Here is my code. Thanks advance.

BIG EDIT Old code was removed. I added new codes that will help you guys/girls to understand problem that I have. Hope that this will help. Regards.

First here is class that show gui:

import javax.swing.*;
public class Glavni {
public static void main(String[] args)  {
    // TODO Auto-generated method stub
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
                gui Scanner = new gui();
                Scanner.setVisible(true);
        }
    });
}

}

Second here is class that pass String to gui class that contains jtable

public class passDatatoTable {
public void passData(){
    String str1,str2,str3,str4;
    gui SendStringsToGUI = new gui();
    for (int i =0;i<=10;i++){
            str1="Column 1 of row: "+i;
            str2="Column 2 of row: "+i;
            str3="Column 3 of row: "+i;
            str4="Column 4 of row: "+i;
            SendStringsToGUI.WriteMonitorData(str1, str2, str3, str4);

    }
  }
}

Next here is declaration of gui (contructor):

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class gui extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
 String[][] data = new String[100][4];

 String[] columnNames = new String[]{
         "IP", "PC_NAME", "ttl", "db"
 };
 DefaultTableModel model = new DefaultTableModel(data,columnNames);


    JTable table =  new JTable(model);
    JScrollPane scrollPane = new JScrollPane(table);
    int i=0;
public void WriteMonitorData (String IP, String PC_NAME, String ttl, String gw)
{
    System.out.println(IP);//just for testing (check if data was passed)
    model.setValueAt(IP, i, 0);
    model.setValueAt(PC_NAME, i, 1);
    model.setValueAt(ttl, i, 2);
    model.setValueAt(gw, i, 3);

    i++;
    model.fireTableDataChanged();
    table.repaint();
    scrollPane.repaint();

}   
gui(){

JButton addData= new JButton("Add Data");
JButton next = new JButton("next");
JButton prev = new JButton("prev");
addData.addActionListener(this);
next.addActionListener(this);
prev.addActionListener(this);
JPanel panel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel();
buttonPanel.add(addData);
buttonPanel.add(prev);
buttonPanel.add(next);
panel.add(buttonPanel, BorderLayout.SOUTH);
panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
panel.add(scrollPane, BorderLayout.CENTER);
getContentPane().add(panel);
}

Here is actionListeners:

public void actionPerformed(ActionEvent e) {
if ("Add Data".equals(e.getActionCommand())){

        passDatatoTable passSomeData = new passDatatoTable();
        passSomeData.passData();
              }
 if ("next".equals(e.getActionCommand())) {
         Rectangle rect = scrollPane.getVisibleRect();
         JScrollBar  bar = scrollPane.getVerticalScrollBar();
         int blockIncr = scrollPane.getViewport().getViewRect().height;
             bar.setValue(bar.getValue() + blockIncr);
             scrollPane.scrollRectToVisible(rect);
     }
     if ("prev".equals(e.getActionCommand())) {
         Rectangle rect = scrollPane.getVisibleRect();
         JScrollBar  bar = scrollPane.getVerticalScrollBar();
         int blockIncr = scrollPane.getViewport().getViewRect().height;
             bar.setValue(bar.getValue() - blockIncr);
             scrollPane.scrollRectToVisible(rect);
     }

  }

Solution

  • Your first snippet shows this:

    JTable table = new JTable(model);

    but your gui() constructor shows:

    JTable table = new JTable(data, columnNames);

    You initiate the table twice. Once using the TableModel (JTable(TableModel tm)) the next using JTable(int rows,int cols) this is not good, initiate the JTable once in the constructor:

    gui() {
    DefaultTableModel model = new DefaultTableModel(data,columnNames);
    JTable table =  new JTable(model);
    JScrollPane scrollPane = new JScrollPane(table);
    
    JButton next = new JButton("next");
    JButton prev = new JButton("prev");
    next.addActionListener(this);
    prev.addActionListener(this);
    JPanel panel = new JPanel(new BorderLayout());
    JPanel buttonPanel = new JPanel();
    buttonPanel.add(prev);
    buttonPanel.add(next);
    panel.add(buttonPanel, BorderLayout.SOUTH);
    panel.add(table.getTableHeader(), BorderLayout.PAGE_START);
    panel.add(scrollPane, BorderLayout.CENTER);
    getContentPane().add(panel);
    }
    

    UPDATE:

    Here is an example that has a thread which will start 2.5 secinds after the UI is visible and change a value of the JTable:

    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    
    public class Test extends JFrame {
    
        public static void main(String[] args) throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new Test().createAndShowUI();
                }
            });
    
        }
    
        private void createAndShowUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            initComponents(frame);
            frame.pack();
            frame.setVisible(true);
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        Thread.sleep(2500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                    } 
                    SwingUtilities.invokeLater(new Runnable() {
    
                         @Override
                         public void run() {
                           model.setValueAt("hello", 0, 0);
                         }
                    });
                }
            }).start();
        }
        static DefaultTableModel model;
    
        private void initComponents(JFrame frame) {
    
            String data[][] = {
                {"1", "2", "3"},
                {"4", "5", "6"},
                {"7", "8", "9"},
                {"10", "11", "12"}
            };
    
            String col[] = {"Col 1", "Col 2", "Col 3"};
    
            model = new DefaultTableModel(data, col);
            JTable table = new JTable(model);
    
            frame.getContentPane().add(new JScrollPane(table));
        }
    }