2012-09-28 112 views
2

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

BIG EDIT旧代码已删除。我添加了新的代码,可以帮助你们/女孩理解我的问题。希望这会有所帮助。问候。

首先这里是一流的,显示图形用户界面:

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,这里包含的JTable

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

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

    } 
+1

a)请学习java命名约定并坚持使用它们。 b)永远不要调用模型外的任何fireXX方法(模型_must_句柄本身)c)永远不要调用repaint(这不需要) – kleopatra

回答

6

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

JTable table = new JTable(model);

但你gui()构造显示:

JTable table = new JTable(data, columnNames);

您启动表的两倍。一旦使用JTable(int rows,int cols)这是不好的使用TableModelJTable(TableModel tm))接下来,在构造函数初始化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:

这里是有一个线程,将启动一个实例2.5 secinds之后的UI是可见的,改变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)); 
    } 
} 
+0

感谢您的重播。我删除了JTable table = new JTable(data,columnNames);从构造函数,它仍然不会刷新/更新。 – ZhiZha

+0

@智斋请看我的更新。一切正常。您可能想要创建一个简短的[sscce](http://sscce.org) –

+0

感谢您的代码。正如我所看到的,你并没有从其他更新表的类传递过来。问题是,当你将新数据存储到数组中时,该数据永远不会更新。这是我的问题....当我扫描看到你创建数据的数据与其中的数据。我的代码适用于在gui类中声明数据。问题是,当你添加新的数据到数组“数据”。这些数据可能会在桌面上显示...对我来说,它不显示... – ZhiZha

2

从我从评论的理解第二问题,您首先通过将数据作为数组构造函数

String[][] data = new String[100][4]; 
String[] columnNames = new String[]{ 
    "IP", "PC_NAME", "ttl", "db"}; 
DefaultTableModel model = new DefaultTableModel(data,columnNames); 

创建DefaultTableModel并尝试通过调整这些阵列事后修改表。这永远不会有任何效果,因为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。

+0

谢谢罗宾。我会尽力实施你的建议和代码。非常感谢。 – ZhiZha

+0

Hi @Robin。再次感谢您的帮助。看看我更新的代码。有一个完整的代码被使用。你可以简单地复制/粘贴在Eclipse中......正如你所看到的,我不再使用数组。我正在使用DefaultTableModel函数setValueAt(),它用于向模型添加新值。仍然没有数据显示... – ZhiZha

+0

@ZhiZha你的'passDatatoTable'类仍然创建一个新的UI('gui SendStringsToGUI = new gui();')而不是更新现有的一个 – Robin