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