SwingWorker: метод process() не вызывается

У меня есть поток SwingWorker, который я использую для обновления пользовательского интерфейса JLabel, и помимо методов publish()/process() программа работает (в том смысле, что JLabel успешно публикуется с соответствующим текстом/фоном/границей и т. д. .). Однако я хочу использовать метод process(), чтобы установить для текста JLabel значение «Connecting...», в то время как doInBackground() выполняет свою работу, но метод process() в моей программе никогда не вызывается (я, очевидно, с помощью метода публикации()). Предложения?

Вот SwingWorker:

public class PcclientBackgroundWork extends SwingWorker < String, String> {

    public JLabel connectionStatus2;
    String msg;

    /* Constructor */
    public PcclientBackgroundWork(JLabel label){
        connectionStatus2 = label;
    }

    /*Background work to determine Application connection status
      and pass corresponding message (String msg) to done() */
    @Override
    public String doInBackground() throws Exception {

        String serverName = "localhost";                         //UDP is sent within same machine
        int port = 6789;

        try {
            Socket client = new Socket(serverName, port);
            BufferedReader in = new BufferedReader
                    (new InputStreamReader(client.getInputStream()));
            while(!in.ready()){
                publish("Connecting");                           //Want this method called until the bufferedReader is ready.
            }                                                    //Loops until ready
            msg = in.readLine();                                 //Incoming text is only one line
            if(msg.equals("Connection Unsuccessful"))
            {
                msg = "Application Connection Failed";
            } else {
                msg = "App Connected " + msg;
            }
            System.out.println("msg = " + msg);
            in.close();                                          //Close reader
            client.close();                                      //Close client socket   

        } catch (IOException e) {
            e.printStackTrace();
            msg = "Application Connection Failed";               //JLabel text set the same as 
        }                                                        //if connection is unsuccessful (lines 66-68)

        return msg;
    }


    public void process(String msg){
        System.out.println("process method called...");
        connectionStatus2.setText(msg);
    }
    /*Method to set JLabel information when doInBackground() is complete */

    @Override
    public void done() {
        try {
            connectionStatus2.setText(get());                    //get() is the return value of doInBackground (String msg)
            connectionStatus2.setBorder(BorderFactory.createLineBorder(Color.black));
            connectionStatus2.setVisible(true);
            connectionStatus2.setOpaque(true);
            if(get().equals("Application Connection Failed")){
                connectionStatus2.setBackground(Color.PINK);
            } else {
                connectionStatus2.setBackground(Color.GREEN);
            }
        } catch (InterruptedException ex) {
        } catch (ExecutionException ex) {
            Logger.getLogger(PcclientUI.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

Я не публиковал поток пользовательского интерфейса, потому что функции SwingWorker мне нравятся, кроме методов публикации/обработки. Заранее спасибо!


person aherbets    schedule 12.06.2014    source источник


Ответы (1)


Подпись для processprocess(List<V>), а не process(V). Измените метод обработки на process(List<String> list); вы можете получить более одного элемента в списке, в зависимости от того, как часто вызывалась публикация перед запуском процесса.

person arcy    schedule 12.06.2014
comment
Я сделал это редактирование, и теперь метод действительно вызывается - оператор печати выводится, но JLabel не может успешно опубликовать текст. Имеет ли значение, что я пытаюсь изменить ту же метку, что и в методе done()? - person aherbets; 12.06.2014
comment
что, вероятно, имеет значение, так это то, находитесь ли вы в потоке отправки событий. Убедитесь, что вы установили его с помощью SwingUtilities.invokeNow(). Я не знаю, что это ваша проблема, но это первое, что нужно проверить, когда ваш код обновления пользовательского интерфейса не обновляет пользовательский интерфейс. - person arcy; 12.06.2014
comment
Я думаю, проблема заключалась в том, что метод doInBackground() вызывался слишком быстро, чтобы заметить изменения в методе process(). Прямо сейчас я только моделирую соединение, которое будет установлено, поэтому оно будет работать быстро, но если я заставлю метод doInBackground() спать, чтобы имитировать время, необходимое для установления реального соединения, оно сработает. Спасибо за вашу помощь. - person aherbets; 12.06.2014
comment
Хорошо, но будьте уверены в потоке, в котором вы выполняете вызовы обновления пользовательского интерфейса. Выполнение их за пределами EDT может привести к непредсказуемому поведению, а вставка sleep() может скрыть тот факт, что вы звоните из неправильного потока. Использование invokeWait() никогда не помешает; если он вызывается ИЗ EDT, он обнаруживает это и обрабатывает. - person arcy; 13.06.2014