Question

I have a problem with updating/refreshing data in table. I am using DefaultTableModel. Here is code so please share your knowledge and advises. Best regards.

*EDIT 1: * Original code has a function that was updating table data but that proves wrong because of constructor which is creating over and over new JTable and new JScrollPane. That's why I created new constructor and that bug was repaired. After I implement new constructor, table data still didn't refresh. Next I was try to debug data that constructor received thought other class (passDatatoTable class). After I used function setValueAt() and then System.out.println(getValueAt(i,1)), output was null. And that's it First here is main class that creates 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 send data to gui

public class passDatatoTable {
public void passData(){
String str1,str2,str3,str4;
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;
        gui SendStringsToGUI = new gui(str1, str2, str3, str4);

}
}
}

And here is gui class. Button "Add Data" is used to fill data. Here is code:

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 gui(String IP, String PC_NAME, String ttl, String gw) {
//Used this constructor to avoid creating new gui in other classes  
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. Buttons next and prev are used for paging and button "Add Data" is used to create variable of class "passDatatoTable" which is used to fill data of table

here is code:

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);
 }

 }
Was it helpful?

Solution

Your problem may be here:

class passDatatoTable {
   public void passData() {
      String str1, str2, str3, str4;
      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;
         gui SendStringsToGUI = new gui(str1, str2, str3, str4); // **** line (A)
      }
   }
}

You seem to be creating a new gui object on line (A) and passing data into it. Please realize that this gui object has absolutely nothing to do with the gui object that is being displayed, and so passing data in this way will cause no observable change in the displayed data.

A possible solution is to pass a reference to the gui object via a constructor parameter and then using public methods of that gui object (not a constructor) to set or change data.

Here's a simple example of what I mean:

import java.awt.event.ActionEvent;

import javax.swing.*;

public class GuiTest2 {
   private static void createAndShowGui() {
      Gui2 mainPanel = new Gui2();

      JFrame frame = new JFrame("Gui2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class Gui2 extends JPanel {
   private JTextField field = new JTextField(10);

   // pass a reference to the GUI object into the controller via
   // its constructor
   private JButton nextBtn = new JButton(new NextController(this, "Next"));

   public Gui2() {
      field.setEditable(false);
      field.setFocusable(false);

      add(field);
      add(nextBtn);
   }

   public void setTextFieldText(String text) {
      field.setText(text);
   }
}

class NextController extends AbstractAction {
   private static final String[] TEXTS = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
   private Gui2 gui;
   private int index = 0;

   // pass the Gui2 object into the controller's constructor
   public NextController(Gui2 gui, String name) {
      super(name);
      this.gui = gui; // set the Gui2 field with the parameter
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
      // use the Gui2 object here
      gui.setTextFieldText(TEXTS[index]);
      index++;
      index %= TEXTS.length;
   }

}

OTHER TIPS

You appear to be setting table model data for a new Gui object which is not associated with your currently displayed Gui so nothing is appearing in the JTable table.

Having an model update method would allow you to update the model data as needed:

public void updateModel(String IP, String PC_NAME, String ttl, String gw) {
   model.setValueAt(IP, i, 0);
   model.setValueAt(PC_NAME, i, 1);
   model.setValueAt(ttl, i, 2);
   model.setValueAt(gw, i, 3);
   i++;
}

You will need to pass a reference of your Gui object to PassDatatoTable object. The latter object has very little functionality in its current form so perhaps better to bring this functionality into the Gui class.

Also there's no need to call:

model.fireTableDataChanged();

This will happen automatically.

Thanks guys for helo. Finally i fix this problem. The big deal was to send a object to class that was filling data in table. In other words here is what I did:

Remember class that was passing data to table? Well modify it like I did here:

public class passDatatoTable {
passDatatoTable(ScanFrame gui){
    String str1,str2,str3;

    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;
            gui.model.setValueAt(str1, gui.i, 0);
            gui.model.setValueAt(str2, gui.i, 2);
            gui.model.setValueAt(str3, gui.i, 3);
            gui.i++;
    }
}}

Now let's go back to gui class. Simply remove constructor (just rename it to anything you like and call that in main function). Here is example. NOTICE: All 2 constructor are gone because you don't need them.

CODE:

public void CreateAndShowGUI(){
setVisible(true);//add this line to show 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);
}

Now the important par is coming. Remmember button "Add Data"? Not all you need to do is to send refrence of this gui to class that fill data to table (passDatatoTable class) and it will work.

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

passDatatoTable passSomeData = new passDatatoTable();
passSomeData.passData(this);//here!! just add this and it will work!!
      }
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);
}

}

EDIT

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.CreateAndShowGUI();
        }
    });
}

    }

Forgot to add main class. Here is it. If you have any problems/question please ask it. Thanks to @Hovercraft Full Of Eels and to @Reimeus for great help for their time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top