编辑:注意,这个问题与我在这里的另一个问题有关:SwingWorker - Passing parameters and return an ArrayList<Object>
在挖掘了 SwingWorker 之后,为了尝试解决这个问题,我想出了这个 SSCCE 代码。
笔记结束
编辑结束
给定以下 SSCCE 代码:
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class MainFrame extends JFrame {
private JLabel countLabel1 = new JLabel("0");
private JLabel statusLabel1 = new JLabel("Task not completed.");
private JLabel statusLabel2 = new JLabel("Task not completed.");
private JLabel statusLabel3 = new JLabel("Task not completed.");
private JButton startButton = new JButton("Start");
private ArrayList<Train> trainList = new ArrayList<>();
private ArrayList<Train> processedTrains = new ArrayList<>();
public MainFrame(String title) {
super(title);
setLayout(new GridBagLayout());
countLabel1.setFont(new Font("serif", Font.BOLD, 28));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE;
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 1;
add(countLabel1, gc);
gc.gridx = 0;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel1, gc);
gc.gridx = 0;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel2, gc);
gc.gridx = 0;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 1;
add(statusLabel3, gc);
gc.gridx = 0;
gc.gridy = 4;
gc.weightx = 1;
gc.weighty = 1;
add(startButton, gc);
Train t1 = new Train();
t1.setId(1);
t1.setName("John");
Train t2 = new Train();
t2.setId(2);
t2.setName("Mark");
Train t3 = new Train();
t3.setId(3);
t3.setName("Lewis");
trainList.add(t1);
trainList.add(t2);
trainList.add(t3);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
TrainMethods tm = new TrainMethods();
// How can the swing worker return the array from the
// processTrains method to this processedTrains array
processedTrains = tm.processTrains(trainList);
for (int i = 0; i < processedTrains.size(); i++) {
System.out.println("Train id: " + processedTrains.get(i).getId()
+ " Train Name: " + processedTrains.get(i).getName());
}
}
});
setSize(200, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
// Notice that it kicks it off on the event-dispatching thread, not the main thread.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MainFrame mf = new MainFrame("Yo");
}
});
}
private class Train {
String name;
int id;
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
}
private class TrainMethods {
public ArrayList processTrains(final ArrayList<Train> trainList) {
// Add here a SwingWorker to create a new thread
// and execute the following code and update later on
// a progress bar
SwingWorker<ArrayList, Integer> worker = new SwingWorker<ArrayList, Integer>() {
@Override
protected ArrayList doInBackground() throws Exception {
for(int i = 0; i<trainList.size(); i++)
{
trainList.get(i).setName("No name");
publish(i);
}
return trainList;
}
@Override
protected void process(List<Integer> chunks) {
int mostRecentValue = chunks.get(chunks.size() - 1);
countLabel1.setText(Integer.toString(mostRecentValue));
}
@Override
protected void done() {
ArrayList<Train> status;
try {
// Retrieve the return value of doInBackground.
status = get();
statusLabel1.setText("Completed Train 1 with name: " + status.get(0).getName());
statusLabel2.setText("\nCompleted Train 2 with name: " + status.get(1).getName());
statusLabel3.setText("\nCompleted Train 3 with name: " + status.get(2).getName());
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
worker.execute();
return trainList;
// for (int i = 0; i < trainList.size(); i++) {
// trainList.get(i).setName("No name");
// }
// return trainList;
}
}
}
为什么要System.Out.Println()
打印:
Train id: 1 Train Name: John
Train id: 2 Train Name: Mark
Train id: 3 Train Name: Lewis
用户界面打印时:No Name
? 就我个人而言,我希望No Name
在两者上都被打印出来。
问题1:为什么不同的输出?
问题 2:如何让它No Name
在两个地方(Sysout 和 GUI)都输出?
_________________________ 编辑 _______________________________
问题3:为什么我第二次按下开始按钮时都会打印No Name
?