2012-09-28 110 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