Возврат массива из потока SwinWorker в основную тему - PullRequest
0 голосов
/ 03 октября 2019

У меня есть свинг-интерфейс, который при открытии выполняет поток в фоновом режиме. Для этого я использовал поток SwingWorker. проблема в том, что у меня есть массив массивов объявлений в основном потоке, который, как ожидается, будет собирать информацию из потока Swingworker и возвращать ее, но после завершения потока массив все еще будет пустым. Я предполагаю, что как только поток закончен, массив теряет свои значения, даже если массив объявлен в основном потоке. В любом случае, как я могу вернуть значения массива в основной поток? спасибо

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); 

1 Ответ

1 голос
/ 03 октября 2019

Чтобы получить список всех имен интерфейсов, вызовите метод [static] getNetworkInterfaces() класса java.net.NetworkInterface. И я предполагаю, что вы хотите вызвать этот метод из SwingWorker. Кроме того, из кода, который вы разместили, я предполагаю, что вы хотите заполнить JComboBox в done() методе класса SwingWorker. И поскольку вся работа выполняется в классе SwingWorker, метод doInBackground() не должен ничего возвращать.

Когда дело доходит до использования SwingWorker, я предпочитаю создать совершенно отдельный класскоторый расширяет SwingWorker, а не анонимный внутренний класс.

Вот код для Swing приложения. JFrame отображает JLabel и JComboBox. JcomboBox содержит список имен всех сетевых интерфейсов.

Обратите внимание, что на моей Windows 10 (64-битной) машине с JDK 13 заполнение 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));
    }
}
...