2

我有JTable/的问题JScrollPane。我的数据表没有刷新/更新。我正在使用DefultTableModel,根据代码一切都很好,我没有任何错误。另外我有一个带有分页的表格,这就是为什么我使用动作监听器和按钮“prev”和“next”。我正在从其他函数传递到在 where is 类中编码的函数 JTable。问题是我填充了包含表格数据的数组,但表格不会更新/刷新它。这是我的代码。提前谢谢。

大编辑旧代码已删除。我添加了新代码,可以帮助你们了解我遇到的问题。希望这会有所帮助。问候。

首先是显示 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(构造函数)的声明:

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

这是动作监听器:

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

  }
4

2 回答 2

6

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

JTable table = new JTable(model);

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

JTable table = new JTable(data, columnNames);

您启动表两次。一旦使用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);
}

更新:

这是一个示例,该线程将在 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));
    }
}
于 2012-09-28T19:40:58.110 回答
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。

于 2012-09-28T21:05:50.707 回答