Search code examples
javaswingjtablerefreshdefaulttablemodel

Java - Method changes value of variable in JTable (refresh not working)


I have a JTable with a variable inside one of the cells. When Button is clicked the variable changes but nothing changes in JTable. Here is my simple example code:

public class Test extends JPanel {
static String var = "One";
Object rowData[][] = { { var, "Two", "Three" },
    { "Four", "Five", "Six" } };
Object columnNames[] = { "Column One", "Column Two", "Column Three" };
static JTable table;

static DefaultTableModel tableModel;
JButton button = new JButton("Refresh");
public Test(){
    tableModel = new DefaultTableModel(rowData, columnNames);
    table = new JTable(tableModel);
    add(table);
    button.addActionListener(new Action());
    add(button);
}
private static class Action implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        var = "ONE";
        System.out.println(var);
        String[] data = {"ciao"};
        tableModel.fireTableStructureChanged();
    }
}
}

Can someone help me please? Thank you!


Solution

  • You never change your tableModel's data at all, so it makes sense that the JTable never changes. Perhaps you want to call setValueAt(...) on the model to change the value held by one of its cells. After you do that, there's no need to call fireXxxx(...) on the model since this is (and should be) called internally by the model itself.

    Ah, I see what you've done. You are thinking that by changing the String that var refers to, the JTable's data will magically change, but that's magical thinking as all you're doing is changing the object that the var variable refers to and you're having absolutely no effect on the String object that it referred to previously and that is being displayed in the JTable. This issue gets to a core concept of Java's OOP model, that of the difference between objects and reference variables. Changing a variable reference has no effect on the object it refers to. Again, call setValueAt(...) on your model and your problem is solved.


    For example:

    import java.awt.event.*;
    
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    
    public class Test extends JPanel {
       static String var = "One";
       Object rowData[][] = { { var, "Two", "Three" }, { "Four", "Five", "Six" } };
       Object columnNames[] = { "Column One", "Column Two", "Column Three" };
       JTable table;
    
       DefaultTableModel tableModel;
       JButton button = new JButton("Refresh");
    
       public Test() {
          tableModel = new DefaultTableModel(rowData, columnNames);
          table = new JTable(tableModel);
          add(table);
          button.addActionListener(new Action());
          add(button);
       }
    
       private class Action implements ActionListener {
    
          @Override
          public void actionPerformed(ActionEvent e) {
             String var2 = "ONE";
             System.out.println(var2);
             // String[] data = { "ciao" };
             // tableModel.fireTableStructureChanged();
    
             tableModel.setValueAt(var2, 0, 0);
          }
       }
    
       private static void createAndShowGui() {
          JFrame frame = new JFrame("Test");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(new Test());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }