So, I have a Java application that uses Swing for building the GUI and implements the MVC design pattern, and because of that I am ending up with a lot of instances of SwingWorker
being used in the view to make calls to the controller and a lot of calls to EventQueue.invokeLater()
from the controller to the view. This seemed like the way to go because of the single-threaded nature of Swing and MVC best practices, but now I have code that duplicates the following pattern many, many times:
public class MainController{
private final View someView;
public void someMethod(Object data){
// Do stuff with the data; maybe change the model.
EventQueue.invokeLater( new Runnable(){
@Override
public void run() {
someView.updateView(Object someObject); //This is the code that I actually need to execute
}
});
}
}
public class View extends JPanel{ // or whatever
private final MainController controller;
public class someListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
new SwingWorker<Void,Void>(){
public Void doInBackground(){
controller.someMethod(object); // This is the code I actually want to execute
return null;
}
}.execute();
}
}
}
I am aware that I can write a method that passes a runnable to a call to EventQueue.invokeLater()
, but I would still have to duplicate all the code for implementing a runnable. Most of the pieces of code that I actually need to run, do not have much in common besides the fact that they need to run on the EDT or in a SwingWorker, so extending SwingWorker
or implementing Runnable
is not going to help. My question is, how do I avoid all this duplication? Is the problem with the design? Or is there a way to make my method calls without all this overhead code?
I finally resolved this issue. Instead of making calls to EventQueue.invokeLater()
everywhere in the controllers when updating GUI components, I now wrap the methods in the view that get called by the controllers inside calls to the same. This reduced the size of my controllers by hundreds of lines.