将数组从SwingWorker线程返回到主线程

问题描述 投票:0回答:1

我有一个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); 
java multithreading swing swingworker java-threads
1个回答
1
投票

要获取所有接口名称的列表,请调用类getNetworkInterfaces()的[静态]方法java.net.NetworkInterface。我假设您想从SwingWorker内部调用该方法。另外,从您发布的代码中,我假定您想在类JComboBoxdone()方法中填充SwingWorker。并且由于所有工作都在SwingWorker类中完成,因此方法doInBackground()不需要返回任何内容。

[使用SwingWorker时,我更喜欢制作一个完全独立的类来扩展SwingWorker,而不是匿名内部类。

这里是Swing应用程序的代码。 JFrame显示JLabelJComboBoxJcomboBox包含所有网络接口名称的列表。

[请注意,在运行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));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.