在下面的代码中,我在类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));
}
}
答案 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