Accessing parent class object through thread
My question is, In my code I have made a JTable in main class. Now I am making a thread To do some task and to collect some data which i want to fill in the JTable as soon as the thread collects it. This thread should run for a while. So Can I access the JTable of main class through the Thread created.
EDIT: I'm providing my code here.
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));
}
}
What I actually want is The value at 0,0 on the display screen of the JTable should Change from "a" to "new value".
Please give some help.
When you create a thread you actually create a Runnable class, either by extending Thread or implementing Runnable. So you will have your own class such as this
MyClass implements Runnable {
public void run() { ... your work here ... }
}
Simply pass any objects you like to the constructor of this class
MyClass implements Runnable {
JTable m_jtable;
public MyClass( JTable theTable ) { m_jtable = theTable; }
public void run() { do things with m_jtable }
}
It's been a while I've been doing Swing programming, but you probably want to have your Thread updating table's model instead of messing with JTable itself. In any case it will have a model, whether you create it or not.
So you should have the Thread that is collecting the data have a reference to the model, and once collection is done, fire some events in order to have the table updated (for instance http://download.oracle.com/javase/7/docs/api/javax/swing/table/AbstractTableModel.html#fireTableDataChanged()).
You should avoid littering your code with public references to internals of your application, i.e. do not have your table/model available as a public variable somewhere. Know where your objects live, it keep things tidy.
EDIT:
So you would have your model:
public class MyModel extends AbstractTableModel {
private ClassDescribingYourData data;
public void update(ClassDescribingYourData data) {
this.data = data;
fireTableDataChanged();
}
}
And your data collector:
public class DataCollector implements Runnable {
private final MyModel model;
public DataCollector(MyModel model) {
this.model = model;
}
public void run() {
//1. collect data
collectedData = ..
//2. update model
this.model.update(collectedData);
}
}
Then, you'd either use some Executor or simply do:
DataCollector collector = new DataCollector(referenceToYourModel);
new Thread(collector).start();
Above is not a complete implementation but I hope it explains the idea.
精彩评论