Jtable不刷新/更新数据

时间:2012-09-28 19:32:58

标签: java swing jtable jscrollpane defaulttablemodel

我对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(con​​tructor)的声明:

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

  }

2 个答案:

答案 0 :(得分:6)

您的第一个代码段显示了这一点:

JTable table = new JTable(model);

但您的gui()构造函数显示:

JTable table = new JTable(data, columnNames);

你启动表两次。使用TableModelJTable(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。