2012-09-29 59 views
0

我在更新/刷新表格中的数据时遇到问题。我正在使用DefaultTableModel。这里是代码,请分享您的知识和建议。最好的祝福。JTable和DefaultTableModel不能刷新表格数据

* 编辑1:* 原代码有被更新表数据的功能,但由于构造函数是创建一遍又一遍新的JTable和新JScrollPane的的,证明是错误的。这就是为什么我创建了新的构造函数并修复了该错误。在我实现新的构造函数之后,表数据仍然没有刷新。接下来,我尝试调试构造函数接收的其他类(passDatatoTable类)的数据。在使用函数setValueAt()和System.out.println(getValueAt(i,1))之后,输出为空。这就是它 首先这里是一个创建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); 
    } 
}); 
} 

} 

其次这里是类,将数据发送到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); 

} 
} 
} 

这里是GUI类。按钮“添加数据”用于填充数据。这里是代码:

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

这里是ActionListeners。 Next按钮和prev用于寻呼和按钮“添加数据”被用来创建类“passDatatoTable”,这是用来填充表的数据变量

这里是代码:

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

} 
+0

您不妨花费一些精力来描述问题的细节。究竟发生了什么?应该发生什么?您采取了哪些措施来尝试调试此问题? –

+0

好吧我会更新我的问题,我会对我的问题做什么 – ZhiZha

+1

可能重复的[Jtable不刷新/更新数据](http://stackoverflow.com/questions/12646240/jtable-doesnt-refresh-更新数据) – kleopatra

回答

2

你的问题可能在这里:

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

你似乎对线(A)要创建一个新的GUI对象和数据传递到它。请注意,这个gui对象与正在显示的gui对象完全无关,所以以这种方式传递数据将不会导致显示的数据发生可观察的变化。

一种可能的解决方案是通过一个构造参数来传递到GUI对象的引用,然后使用(构造),该GUI对象的公共方法来设定或改变的数据。

这里是什么,我的意思是一个简单的例子:

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

} 
3

你出现这是不符合相关的新Gui对象被设置表模型数据的当前显示Gui所以没有什么是出现在JTabletable

具有模型更新方法将允许您根据需要更新模型数据:

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

您需要将您的Gui对象的引用传递给PassDatatoTable对象。后一个对象目前的功能很少,因此将这个功能带入Gui类可能会更好。

也没有必要呼吁:

model.fireTableDataChanged(); 

这将自动发生。

+0

谢谢你们的帮助。我确实使用过你的建议,而不是很好。感谢帮助。 – ZhiZha

+0

+1这将自动发生。 – mKorbel

0

谢谢你们。最后我解决了这个问题。最重要的事情是发送一个对象到正在填充表中的数据的类。换句话说,这就是我所做的:

还记得那些传递数据到表的类吗?修改它就像我在这里:

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

现在我们回到gui类。只需删除构造函数(只需将其重命名为任何你喜欢的东西,然后在main函数中调用它)。这里是例子。注意:所有2个构造函数都不见了,因为你不需要它们。

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

现在重要面值来了。 Remmember按钮“添加数据”?并不是所有你需要做的就是把这个GUI的引用发送到填充数据到表(passDatatoTable类)的类,它会起作用。

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

} 

编辑

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

    } 

忘了补充主类。就这个。 如果您有任何问题/疑问,请提问。感谢@Hovercraft Full Of Eels和@Reimeus为他们的时间提供了极大的帮助。

+0

你需要接受这里和你的其他问题在stackoverflow最好的答案。 –