我有一个Swing GUI,当它打开时,它会在后台执行一个线程。为此,我使用了SwingWorker
线程。问题是我在主线程中有一个String数组声明,该声明应从swing工作者线程收集信息并返回该信息,但是在线程完成后,该数组仍为空。我想一旦线程完成,即使在主线程中声明了数组,数组也会失去其值。
如何将数组的值返回到主线程?
ArrayList<String> allnets = new ArrayList();
new SwingWorker<Object, Void>() {
@Override
public Object doInBackground() throws SocketException, UnknownHostException {
System.out.println("interfaces");
netAdapter = new NetInterface();
System.out.println(Thread.currentThread().getName());
for(int i = 0; i < allnets.length; i++) {
allnets.add("interface number");
}
return null;
}
@Override
public void done() {
}
}.execute();
System.out.println(Thread.currentThread().getName());
// String[] inetfaces = {"eth0", "eth1", "wlan1", "wlan2", "wlan3"};
JComboBox comboBox = new JComboBox(allnets);
comboBox.setToolTipText("Interfaces");
comboBox.setBounds(444, 51, 137, 22);
frame.getContentPane().add(comboBox);
要获取所有接口名称的列表,请调用类getNetworkInterfaces()
的[静态]方法java.net.NetworkInterface
。我假设您想从SwingWorker
内部调用该方法。另外,从您发布的代码中,我假定您想在类JComboBox
的done()
方法中填充SwingWorker
。并且由于所有工作都在SwingWorker
类中完成,因此方法doInBackground()
不需要返回任何内容。
[使用SwingWorker
时,我更喜欢制作一个完全独立的类来扩展SwingWorker
,而不是匿名内部类。
这里是Swing应用程序的代码。 JFrame
显示JLabel
和JComboBox
。 JcomboBox
包含所有网络接口名称的列表。
[请注意,在运行JDK 13的Windows 10(64位)计算机上,几乎不需要花费任何时间来填充JComboBox
,因此实际上并不需要SwingWorker
。我想您只是想练习使用SwingWorker
,对吗?
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
public class SwngWrkr implements Runnable {
private JComboBox<Object> combo;
private JFrame frame;
public void run() {
showGui();
}
private JPanel createMainPanel() {
JPanel mainPanel = new JPanel();
mainPanel.add(new JLabel("Interfaces"));
DefaultComboBoxModel<Object> model = new DefaultComboBoxModel<Object>();
model.addElement("Loading...");
combo = new JComboBox<Object>(model);
mainPanel.add(combo);
return mainPanel;
}
private void showGui() {
frame = new JFrame("SW");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
new GetIfTsk(combo).execute();
}
public static void main(String[] args) {
SwngWrkr instance = new SwngWrkr();
EventQueue.invokeLater(instance);
}
}
class GetIfTsk extends SwingWorker<Void, Void> {
private JComboBox<Object> combo;
private List<Object> netIfNames;
public GetIfTsk(JComboBox<Object> combo) {
this.combo = combo;
netIfNames = new ArrayList<>();
}
protected Void doInBackground() throws Exception {
Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces();
int ndx = 0;
while (ifs.hasMoreElements()) {
NetworkInterface ni = ifs.nextElement();
String name = ni.getName();
System.out.printf("%2d. %s%n", ++ndx, name);
netIfNames.add(name);
}
return null;
}
protected void done() {
DefaultComboBoxModel<Object> model = (DefaultComboBoxModel<Object>) combo.getModel();
model.removeAllElements();
model.addAll(netIfNames);
model.setSelectedItem(netIfNames.get(0));
}
}