通过线程访问父类对象

时间:2011-07-21 06:51:41

标签: java

我的问题是,在我的代码中,我在主类中创建了一个JTable。现在我正在创建一个线程做一些任务并收集一些我希望在线程收集它时填写JTable的数据。这个帖子应该运行一段时间。所以我可以通过创建的Thread访问主类的JTable。

编辑:我在这里提供我的代码。

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

}

我真正想要的是JTable显示屏上0,0的值应该从“a”变为“新值”。

请提供帮助。

2 个答案:

答案 0 :(得分:2)

创建线程时,实际上是通过扩展Thread或实现Runnable来创建Runnable类。所以你将有自己的类,比如这个

 MyClass implements Runnable {
     public void run() { ... your work here ... }
 }

只需将您喜欢的任何对象传递给此类的构造函数

即可
 MyClass implements Runnable {


     JTable m_jtable;

     public MyClass( JTable theTable ) { m_jtable = theTable; }

     public void run() { do things with m_jtable }
 }

答案 1 :(得分:0)

我已经做了一段时间的Swing编程,但你可能想要使用你的线程更新表的模型而不是搞乱JTable本身。无论如何,它都会有一个模型,无论你是否创建它。

因此,您应该让收集数据的线程具有对模型的引用,并且一旦完成收集,就会触发一些事件以使表更新(例如{{3 }}())。

您应该避免使用对应用程序内部的公共引用来乱丢您的代码,即不要将您的表/模型作为公共变量提供给某个地方。知道你的对象住在哪里,它可以保持整洁。

编辑:

所以你会得到你的模型:

public class MyModel extends AbstractTableModel {
    private ClassDescribingYourData data;

    public void update(ClassDescribingYourData data) {
        this.data = data;
        fireTableDataChanged();
    }
}

您的数据收集者:

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

然后,你要么使用一些Executor,要么只是:

 DataCollector collector = new DataCollector(referenceToYourModel);
 new Thread(collector).start();

上面不是一个完整的实现,但我希望它能解释这个想法。