通过线程访问

时间:2011-07-22 06:09:49

标签: java multithreading swing jtable

在下面的代码中,我在类main中创建了一个JTable,并且我开始一个线程来收集一些值。我希望在窗口中显示的JTable中更新该值(即类main的JTable)。实际上,我希望在运行此代码后,以下代码中的at(0,0)中的“a”在(0,0)处更改为“new value”。

请帮助。

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

3 个答案:

答案 0 :(得分:2)

请将右MyTableModel传递给您的主题,而不是新主题

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

否则,您将在完全其他对象中设置您的值。

它看起来不像是一个线程问题。如果这不起作用,请尝试在调用

时这样做
t.run();

而不是

t.start()

顺便说一下:为你的班级找一个更好的名字,让它以Java Coding Conventions

建议的大写字母开头

答案 1 :(得分: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 :(得分:1)

您不希望从另一个线程访问该模型,因为swing不是线程安全的。见this