简体   繁体   中英

Java SwingWorker Concurrency Issue

I have a java program that does file manipulation and I have a GUI class that has a JTextArea that has console output redirected to it. I am trying to get the SwingWorker in a different class to publish to that JTextArea but I can't seem to get it to work properly. In my GUI class, I have the following methods:

public ShopUpdaterGUI() {
    initComponents();
    redirectSystemStreams();
}

private void updateTextArea(final String text) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            consoleTextAreaInner.append(text);
          }
        });
}


private void redirectSystemStreams() {
      OutputStream out = new OutputStream() {
        @Override
        public void write(int b) throws IOException {
          updateTextArea(String.valueOf((char) b));
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
          updateTextArea(new String(b, off, len));
        }

        @Override
        public void write(byte[] b) throws IOException {
          write(b, 0, b.length);
        }
      };

      System.setOut(new PrintStream(out, true));
      System.setErr(new PrintStream(out, true));
    }    

And then in my other class that does the work I have this:

public void update(){
    (updateTask = new UpdateTask()).execute();
}

private class UpdateTask extends SwingWorker<Void, String>{

        @Override
        protected Void doInBackground() {
            try{
                publish("Creating backup...");
                mainBackup.createBackup();
                publish("Setting restore point...");
                setRestorePoint();
                publish("Applying update...");
                UPDHandler.unZipUpdate();
                saveModifiedFilesList();

            }catch(IOException ex){
                ex.printStackTrace();
            }catch(ClassNotFoundException ex){
                ex.printStackTrace();
            }finally{
                publish("Update Complete!");
            }

            return null;
        }


}

Edit: here my process method:

    protected void process(List<String> updates){
        String update = updates.get(updates.size() - 1);
        System.out.println(update);
    }

This works sometimes but other times it completely skips over one of the publish() calls. For example, when it reaches publish("Setting restore point...") that would never actually show up on the JTextArea, and instead it would just skip over to "Applying Update..."

How do I get this to publish and update the JTextArea exactly when I tell it to?

publish(V... chunks) is used inside doInBackground() to send data to process(List<V> chunks) to process them in the GUI thread. What you missed is overriding the process method:

@Override
 protected void process(List<String> chunks) {
     for (String s : chunks) {
         textArea.append(s + "\n");
     }
 }

Don't publish or process anything. In your situation since your JTextArea is receiving output redirected from System.out, it appears that all you have to do is call System.out.println(...) on the text that needs to be shown in the JTextArea.

private class UpdateTask extends SwingWorker<Void, String>{

    @Override
    protected Void doInBackground() {
        try{
            publish("Creating backup...");
            mainBackup.createBackup();

            // publish("Setting restore point...");
            System.out.println("Setting restore point...");

            setRestorePoint();

            // publish("Applying update...");
            System.out.println("Applying update...");

            UPDHandler.unZipUpdate();
            saveModifiedFilesList();

        }catch(IOException ex){
            ex.printStackTrace();
        }catch(ClassNotFoundException ex){
            ex.printStackTrace();
        }finally{
            publish("Update Complete!");
        }

        return null;
    }
}

See code in this answer for a more complete example that includes use of a background thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM