Search code examples
javamultithreadingswingswingworker

What class do I use to extend SwingWorker?


I have a Java Swing application. I want to upload information to a web endpoint, and that process will take enough time to justify spinning off the work onto another thread. I'd like to use the Swing SwingWorker paradigm to do that. I'm confused on where I should be extending the SwingWorker.

Right now I have a single class for each web endpoint, and that class stores all the data destined for that endpoint, as well as the code necessary to interface with the endpoint (housed under a method called upload()). Should these classes implement SwingWorker since all the data is there that it needs to perform its task? Or should I have a secondary class FooWorker implement SwingWorker, that will call Upload() off of an internal Site object?

If I make a secondary FooWorker class, then it seems like I have to go to some trouble to stuff references to the Site into each FooWorker object that I instantiate (one thread/worker for each web endpoint), but that the Site won't be polluted by a bunch of SwingWorker methods and code.

If I extend SwingWorker with the Site class, then I can just call .execute() directly from the EDT for each Site which is much cleaner, to me, than creating a worker for each site, and then having that worker call upload() off the site.

Just looking for opinions and ideas about which approach is better. The Site class is already fairly complicated, and I'm afraid of putting a bunch of domain unrelated stuff into it if I extend the SwingWorker class. But the FooWorker class, if I go that route, will basically just be a thin wrapper around the Site class. Is that wrapper worth the trouble of keeping the Site class focused only on its own domain methods/data?


Solution

  • It is always a good idea to introduce abstractions where it makes sense. In this case, I'd say it makes sense because you might end up creating several SwingWorker classes.

    What you could consider is to create a single SwingWorker class called, say, SiteWorker. Then, I'd create Site interface which implements the method upload(). Each class representing a connection to a site endpoint would implement this Site interface. You could then simply have SiteWorker to deal with the Site interface instead of you having to deal with all different sorts of Site classes implementing SwingWorker.

    Remember, program to interfaces and not implementations. It makes your life easier if you can just create a single SiteWorker and then concentrate on the various site implementations.

    Thus, you could pass the Site instance (which would be any class implementing Site) as an argument to the SiteWorker class, which would then, in its doInBackground() method simply call the upload() method of the instance implementing Site.