我对JTable
/ JScrollPane
有疑问。我的数据表没有刷新/更新。我正在使用DefultTableModel
并根据代码一切正常,我没有任何错误。此外,我有一个分页表,这就是为什么我使用动作监听器和按钮“prev”和“next”。我从其他函数传递到函数,该函数在类JTable
中编码。问题是我填充了包含表数据的数组,但表不会更新/刷新它。这是我的代码。谢谢你。
BIG EDIT 旧代码已删除。我添加了新的代码,可以帮助你们/女孩了解我的问题。希望这会有所帮助。问候。
这里首先是显示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);
}
});
}
}
第二个是将String传递给包含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);
}
}
}
接下来是gui(contructor)的声明:
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);
}
这是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);
}
}
答案 0 :(得分:6)
您的第一个代码段显示了这一点:
JTable table = new JTable(model);
但您的gui()
构造函数显示:
JTable table = new JTable(data, columnNames);
你启动表两次。使用TableModel
(JTable(TableModel tm)
)后使用JTable(int rows,int cols)
,这不好,在构造函数中启动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);
}
<强>更新强>
这是一个示例,其中有一个线程,在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));
}
}
答案 1 :(得分:2)
根据我对评论和问题的理解,您首先通过在构造函数中将数据作为数组传递来创建DefaultTableModel
String[][] data = new String[100][4];
String[] columnNames = new String[]{
"IP", "PC_NAME", "ttl", "db"};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
然后您尝试通过调整这些数组来修改表。这永远不会有任何影响,因为DefaultTableModel
不使用那些数组。这可以在该类的源代码中看到
public DefaultTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
最终归结为
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;
}
因此,数组的所有元素都被复制到内部Vector
中,并且不再使用该数组。
解决方案:不要更新阵列,而是更新DefaultTableModel
。该类提供了向/从中添加/删除数据所需的所有API。