2011-07-22 103 views
0

在下面的代碼中,我在類main中創建了一個JTable,我開始一個線程來收集一些值。我希望在窗口中顯示的JTable中更新該值(即類main的JTable)。其實我想要在下面的代碼中的(0,0)「a」在我運行此代碼後更改爲(0,0)處的「新值」。通過線程訪問

請幫忙。

Test.java

package test; 

import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.table.AbstractTableModel; 
import java.awt.*; 


public class Test implements ActionListener { 
Thread t; 
JTable table; 
JScrollPane scrollPane; 
JButton b; 
JFrame frame; 
public void body() { 
    frame = new JFrame("TableDemo"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setLayout(new FlowLayout()); 
    table = new JTable(new MyTableModel()); 
    table.setPreferredScrollableViewportSize(new Dimension(500, 70)); 
    table.setFillsViewportHeight(true); 
    scrollPane = new JScrollPane(table); 
    frame.add(scrollPane); 
    b = new JButton("OK"); 
    frame.add(b); 
    thread a = new thread(new MyTableModel()); 
    t = new Thread(a); 
    frame.pack(); 
    frame.setVisible(true); 
    b.addActionListener(this); 
} 

public static void main(String[] args) { 
    new Test().body(); 
} 

@Override 
public void actionPerformed(ActionEvent e) { 
    t.start(); 
} 
} 

class MyTableModel extends AbstractTableModel 
{ 
    private String[] columnNames = {"First Name", 
            "Last Name", 
            "Sport"}; 
    private Object[][] data = { 
    {"a", "a","a"} 
    }; 

    @Override 
    public int getColumnCount() { 
     return columnNames.length; 
    } 

    public int getRowCount() { 
     return data.length; 
    } 

    public String getColumnName(int col) { 
     return columnNames[col]; 
    } 

    public Object getValueAt(int row, int col) { 
     return data[row][col]; 
    } 
    public Class getColumnClass(int c) { 
     return getValueAt(0, c).getClass(); 
    } 
    public boolean isCellEditable(int row, int col) { 
     if (col < 3) { 
      return false; 
     } else { 
      return true; 
     } 
    } 
    public void setValueAt(Object value, int row, int col) { 

     data[row][col] = value; 
     fireTableCellUpdated(row, col); 
    } 
} 

thread.java

package test; 

public class thread implements Runnable { 
    MyTableModel model; 
    thread(MyTableModel model) 
    { 
     this.model = model; 

    } 

    @Override 
    public void run() { 
    Object aa = "new value"; 
    this.model.setValueAt(aa, 0, 0); 
    System.out.println(this.model.getValueAt(0, 0)); 
    }  
} 

回答

2

首先的建議,你應該傳遞給線程構造函數,連接到電網的TableModel的,而不是一個新問題:

MyTableModel model = new MyTableModel(); 
table = new JTable(model); 
... 
thread a = new thread(model); 
t = new Thread(a); 

而Swing組件不是線程安全的,所以它們的使用必須始終由事件分派線程完成。要更新單元,線程必須做這樣的事情:

final Object aa = "new value"; 
SwingUtilites.invokeLater(new Runnable() { 
    public void run() { 
     model.setValueAt(aa, 0, 0); 
     System.out.println(model.getValueAt(0, 0)); 
    } 
}); 
2

請傳遞正確MyTableModel到你的線程,而不是一個新的

MyTableModel model = new MyTableModel(); 
... 
table = new JTable(model); 
... 
thread a = new thread(model); 

否則你無線將您的價值設置在一個完全的其他對象中。

它看起來不像一個線程問題。如果這樣做不行,請嘗試,如果這樣做的工作,當你調用

t.run(); 

代替

t.start() 

順便說一句:找到你的班級一個更好的名字,讓它以大寫字母開始信由Java Coding Conventions

+0

對不起。那是錯誤的。 我糾正了這一點。但是,我不能按照我的要求工作。 –

+0

什麼'System.out.println(this.model.getValueAt(0,0));'告訴你? – powerMicha

+0

新值。 ,但這並不反映在實際JTable已經顯示給用戶。它只是改變傳遞給它的數據模型的值。而不是在類main的數據模型中。 –

1

你不想從另一個線程訪問模型Swing不是線程安全的。見this