2012-09-29 82 views
0

我在更新/刷新表格中的數據時遇到問題。我正在使用DefaultTableModel。這裏是代碼,請分享您的知識和建議。最好的祝福。JTable和DefaultTableModel不能刷新表格數據

* 編輯1:* 原代碼有被更新表數據的功能,但由於構造函數是創建一遍又一遍新的JTable和新JScrollPane的的,證明是錯誤的。這就是爲什麼我創建了新的構造函數並修復了該錯誤。在我實現新的構造函數之後,表數據仍然沒有刷新。接下來,我嘗試調試構造函數接收的其他類(passDatatoTable類)的數據。在使用函數setValueAt()和System.out.println(getValueAt(i,1))之後,輸出爲空。這就是它 首先這裏是一個創建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); 
    } 
}); 
} 

} 

其次這裏是類,將數據發送到GUI

public class passDatatoTable { 
public void passData(){ 
String str1,str2,str3,str4; 
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; 
     gui SendStringsToGUI = new gui(str1, str2, str3, str4); 

} 
} 
} 

這裏是GUI類。按鈕「添加數據」用於填充數據。這裏是代碼:

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 gui(String IP, String PC_NAME, String ttl, String gw) { 
//Used this constructor to avoid creating new gui in other classes 
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。 Next按鈕和prev用於尋呼和按鈕「添加數據」被用來創建類「passDatatoTable」,這是用來填充表的數據變量

這裏是代碼:

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

您不妨花費一些精力來描述問題的細節。究竟發生了什麼?應該發生什麼?您採取了哪些措施來嘗試調試此問題? –

+0

好吧我會更新我的問題,我會對我的問題做什麼 – ZhiZha

+1

可能重複的[Jtable不刷新/更新數據](http://stackoverflow.com/questions/12646240/jtable-doesnt-refresh-更新數據) – kleopatra

回答

2

你的問題可能在這裏:

class passDatatoTable { 
    public void passData() { 
     String str1, str2, str3, str4; 
     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; 
     gui SendStringsToGUI = new gui(str1, str2, str3, str4); // **** line (A) 
     } 
    } 
} 

你似乎對線(A)要創建一個新的GUI對象和數據傳遞到它。請注意,這個gui對象與正在顯示的gui對象完全無關,所以以這種方式傳遞數據將不會導致顯示的數據發生可觀察的變化。

一種可能的解決方案是通過一個構造參數來傳遞到GUI對象的引用,然後使用(構造),該GUI對象的公共方法來設定或改變的數據。

這裏是什麼,我的意思是一個簡單的例子:

import java.awt.event.ActionEvent; 

import javax.swing.*; 

public class GuiTest2 { 
    private static void createAndShowGui() { 
     Gui2 mainPanel = new Gui2(); 

     JFrame frame = new JFrame("Gui2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class Gui2 extends JPanel { 
    private JTextField field = new JTextField(10); 

    // pass a reference to the GUI object into the controller via 
    // its constructor 
    private JButton nextBtn = new JButton(new NextController(this, "Next")); 

    public Gui2() { 
     field.setEditable(false); 
     field.setFocusable(false); 

     add(field); 
     add(nextBtn); 
    } 

    public void setTextFieldText(String text) { 
     field.setText(text); 
    } 
} 

class NextController extends AbstractAction { 
    private static final String[] TEXTS = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}; 
    private Gui2 gui; 
    private int index = 0; 

    // pass the Gui2 object into the controller's constructor 
    public NextController(Gui2 gui, String name) { 
     super(name); 
     this.gui = gui; // set the Gui2 field with the parameter 
    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     // use the Gui2 object here 
     gui.setTextFieldText(TEXTS[index]); 
     index++; 
     index %= TEXTS.length; 
    } 

} 
3

你出現這是不符合相關的新Gui對象被設置表模型數據的當前顯示Gui所以沒有什麼是出現在JTabletable

具有模型更新方法將允許您根據需要更新模型數據:

public void updateModel(String IP, String PC_NAME, String ttl, String gw) { 
    model.setValueAt(IP, i, 0); 
    model.setValueAt(PC_NAME, i, 1); 
    model.setValueAt(ttl, i, 2); 
    model.setValueAt(gw, i, 3); 
    i++; 
} 

您需要將您的Gui對象的引用傳遞給PassDatatoTable對象。後一個對象目前的功能很少,因此將這個功能帶入Gui類可能會更好。

也沒有必要呼籲:

model.fireTableDataChanged(); 

這將自動發生。

+0

謝謝你們的幫助。我確實使用過你的建議,而不是很好。感謝幫助。 – ZhiZha

+0

+1這將自動發生。 – mKorbel

0

謝謝你們。最後我解決了這個問題。最重要的事情是發送一個對象到正在填充表中的數據的類。換句話說,這就是我所做的:

還記得那些傳遞數據到表的類嗎?修改它就像我在這裏:

public class passDatatoTable { 
passDatatoTable(ScanFrame gui){ 
    String str1,str2,str3; 

    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; 
      gui.model.setValueAt(str1, gui.i, 0); 
      gui.model.setValueAt(str2, gui.i, 2); 
      gui.model.setValueAt(str3, gui.i, 3); 
      gui.i++; 
    } 
}} 

現在我們回到gui類。只需刪除構造函數(只需將其重命名爲任何你喜歡的東西,然後在main函數中調用它)。這裏是例子。注意:所有2個構造函數都不見了,因爲你不需要它們。

CODE:

public void CreateAndShowGUI(){ 
setVisible(true);//add this line to show 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); 
} 

現在重要面值來了。 Remmember按鈕「添加數據」?並不是所有你需要做的就是把這個GUI的引用發送到填充數據到表(passDatatoTable類)的類,它會起作用。

public void actionPerformed(ActionEvent e) { 
if ("Add Data".equals(e.getActionCommand())){ 

passDatatoTable passSomeData = new passDatatoTable(); 
passSomeData.passData(this);//here!! just add this and it will work!! 
     } 
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); 
} 

} 

編輯

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.CreateAndShowGUI(); 
     } 
    }); 
} 

    } 

忘了補充主類。就這個。 如果您有任何問題/疑問,請提問。感謝@Hovercraft Full Of Eels和@Reimeus爲他們的時間提供了極大的幫助。

+0

你需要接受這裏和你的其他問題在stackoverflow最好的答案。 –