gpt4 book ai didi

java - 使用参数创建新线程 - 线程已创建但不显示数据

转载 作者:行者123 更新时间:2023-12-01 18:44:19 26 4
gpt4 key购买 nike

我有一个类 OutputTable,它负责显示包含先前计算结果的表 (jtable)。结果在另一个类(Smooth 类)中计算,并将结果作为参数发送到 OutputTable 类。

我需要计算数据两次,对于这两次数据,我需要显示一个包含结果的 jtable。计算结果时没有多线程。

由于我需要显示 2 个不同的表,并且一旦计算出一个数据,我就想显示该表,因此我决定为每个表创建一个新线程。因此,我在第一次数据处理完成后立即启动第一个线程,当第二轮数据处理完成后,我启动第二个线程。

两个要处理的数据是不同的数据结构,一个是ArrayList<Station>而另一个是 TreeMap<Integer, ArrayList<Station>>

问题是,只有在第二次数据处理完成时才会填充表(进程再次空闲),这使我得出结论,线程有问题。当第一个线程启动时,它只显示窗口布局,内部没有其他内容。当第二个线程启动时,两个表都会填充结果。

我正在使用 GUI,当用户按下开始按钮时,它就会开始数据处理。 GUI 带有

javax.swing.JFrame implements ActionListener, ItemListener

所以我的代码是:

public class OutputTable extends JFrame implements Runnable{

TreeMap<Integer, ArrayList<Station>> map;
ArrayList<Station> arrayStation;

public OutputTable(TreeMap<Integer, ArrayList<Station>> map, ArrayList<Station> arrayStation) {
this.map = map;
this.arrayStation = arrayStation;
}

public void run()
{
DefaultTableModel model = new DefaultTableModel() {
String[] columnsName = { /* my column names go here*/ };

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

@Override
public String getColumnName(int index) {
return columnsName[index];
}
};

JTable table = new JTable(model);
add(new JScrollPane(table));
setSize(1300, 700);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setVisible(true);

if(map != null)
{
for (ArrayList<Station> arrayAux : map.values())
{
for(int a = 0; a<arrayAux.size(); a++)
{
model.addRow(new Object[] { /* here I populate the table with my get methods*/ });
}
}
}

if(arrayStation != null)
{
for(int a = 0; a<arrayStation.size(); a++)
{
model.addRow(new Object[] { /* here I populate the table with my get methods*/ });
}
}
}

}

这是来 self 启动线程的 GUI 代码

/* (where I start processing the data for the first time) */
Runnable r = new OutputTable(null, processme);

new Thread(r).start();

/* (I start processing data for a second time) */
Runnable r2 = new OutputTable(xpto, null);
new Thread(r2).start();

编辑:

如果我不清楚,我假装是在创建 jtable 后立即显示 jtable 中的数据,而不是在所有处理结束时显示,因为现在由于某些我不知道的原因正在发生这种情况了解。

最佳答案

Swing 是单线程环境,UI 的所有更新和交互都应在事件调度线程的上下文中执行。

这也意味着任何阻止 EDT 的操作都将阻止 UI 开始更新/重新绘制或处理可能发生的任何新事件。

参见Concurrency in Swing了解更多详情。

您可能应该使用 SwingWorker,而不是使用 ThreadRunnable。它提供了一种在后台线程中进行处理的方法,而且还提供了简单易用的方法来允许您在 EDT 中处理结果。

例如...

public class StationListWorker extends SwingWorker<Void, Object[]> {
// The data to be processed...
private List<Station> stations;
// The model the results are to be published to...
private DefaultTableModel model;
public StationListWorker(List<Station> stations, DefaultTabelModel model) {
this.stations = stations;
this.model = model;
}

protected Void doInBackground() throws Exception {
// Process the data in the background thread...
for (Station station : stations) {
// Process the data...
publish(new Object[]{...});
}
return null;
}

protected void publish(List<Object[]> rows) {
// Published in the EDT
for (Object[] row : rows) {
model.addRow(row);
}
}
}

然后在你的“框架”类中......

StationListWorker stationListWorker = new StationListWorker(stations, model);
stationListWorker.execute();

就我个人而言,我会建立两个工作人员,每个工作人员负责处理一组数据。这将使修改处理和简化逻辑变得更容易 - 恕我直言

我还想看看The Use of Multiple JFrames, Good/Bad Practice?

关于java - 使用参数创建新线程 - 线程已创建但不显示数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18498251/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com