java Jtable 不刷新/更新数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12646240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jtable doesn't refresh/update data
提问by ZhiZha
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.
我有问题JTable
/ JScrollPane
。我的数据表没有刷新/更新。我正在使用DefultTableModel
,根据代码一切都很好,我没有任何错误。此外,我有一个带分页的表格,这就是为什么我使用动作侦听器和按钮“上一个”和“下一个”。我正在从其他函数传递到在类中编码的函数 where is JTable
。问题是我填充了包含表数据的数组,但表不会更新/刷新它。这是我的代码。先谢谢了。
BIG EDITOld 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:
首先是显示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
第二个是将字符串传递给包含 jtable 的 gui 类的类
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):
接下来是gui(构造函数)的声明:
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:
这是 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);
}
}
回答by David Kroukamp
Your first snippet shows this:
您的第一个片段显示了这一点:
JTable table = new JTable(model);
JTable table = new JTable(model);
but your gui()
constructor shows:
但你的gui()
构造函数显示:
JTable table = new JTable(data, columnNames);
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:
您启动该表两次。一旦使用TableModel
( JTable(TableModel tm)
) 下一次使用JTable(int rows,int cols)
this 不好,JTable
在构造函数中启动一次:
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
:
这是一个示例,它有一个线程,该线程将在 UI 可见后 2.5 秒启动并更改 的值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));
}
}
回答by Robin
From what I understand from the comments and the question, you have first created a DefaultTableModel
by passing the data as arrays in the constructor
根据我从评论和问题中的理解,您首先DefaultTableModel
通过在构造函数中将数据作为数组传递来创建一个
String[][] data = new String[100][4];
String[] columnNames = new String[]{
"IP", "PC_NAME", "ttl", "db"};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
and you try to modify the table afterwards by adjusting those arrays. That will never ever have any effect, as the DefaultTableModel
does not use those arrays. This can be seen in the source code of that class
然后您尝试通过调整这些数组来修改表。这永远不会有任何影响,因为DefaultTableModel
不使用这些数组。这可以在那个类的源代码中看到
public DefaultTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
which in the end comes down to
最终归结为
protected static Vector convertToVector(Object[][] anArray) {
if (anArray == null) {
return null;
}
Vector<Vector> v = new Vector<Vector>(anArray.length);
for (Object[] o : anArray) {
v.addElement(convertToVector(o));
}
return v;
}
So all the elements of the array are copied into an internal Vector
and the array is no longer used.
因此数组的所有元素都被复制到内部Vector
并且不再使用该数组。
Solution: do not update the arrays but update the DefaultTableModel
. That class provides all the API you need to add/remove data to/from it.
解决方案:不要更新数组,而是更新DefaultTableModel
. 该类提供了向其中添加/从中删除数据所需的所有 API。