Search code examples
javaswingswingworker

Using Swingworker publish method in another class


I have a swingworker so that my GUI can remain responsive whilst i do work in the background.

The problem is i need to update the gui at various points (e.g. update a label with program status/info), but i have a lot of processing to do which i can't do all in one huge doInBackground method.

So i instantiate other classes from the doInBackground method to do it, the problem is i can't update the gui except in this SW thread or the EDT.

Note: i have removed unnecessary code for brevity

I want to be able to update the gui from DoWork1 & DoWork2 etc. I have tried passing a reference to the SW swingworker object, but cannot access the publish method presumably because it is protected. I may be able to update the gui using reflection, but anyone using my code wouldn't like that. I did hear someone mention somewhere about using a reverse interface, but there was no example so i have no idea on that one..

Any help would be appreciated, thank you.

public class SW extends SwingWorker<Object, String> {

    private DoWork1 doWork1;
    private DoWork2 doWork2;
    private Iframe frame;

    public SW(Iframe frame, DoWork1 doWork1) {
        this.frame = frame;
        this.doWork1 = doWork1;
        this.doWork2 = new DoWork2();

    }

    @Override
    protected Object doInBackground() {
        doWork1.lotsOfWork("");
        publish("Can write to label from here");
        doWork2.lotsOfWork("", "");
        return null;
    }

    @Override
    public void process(List<String> chunks) {
        for (String s : chunks) {
            frame.getLabel().setText(s);
        }
    }

    @Override
    protected final void done() {
    }
}


public class DoWork1 {
    public DoWork1() {
    }
    private lotsOfWork(String s) {
        //Do lots of work in here
        //But need to update the gui with information!
        //would like to be able to do something like:
        publish("somehow write to label from here!?");
    }
}


public class DoWork2 {
    public DoWork2() {
    }
    private lotsOfWork(String s, String s) {
        //Do lots more work in here
        //But need to update the gui with information!
        //would like to be able to do something like:
        publish("somehow write to label from here!?");
    }
}

Solution

  • In the swingworker create a public method called say publishData that then calls the protected publish method, and access publishData from the other classes DoWork1 via a variable or an interface.

    This way all the classes instantiated in the dobackground work method can publish data to the EDT/GUI too.