For the sake of simplicity, imagine an application that downloads a file. There is a simple GUI with one label that displays progress. To avoid EDT violations, like every lawful citizen I download the file in one thread (main), and update GUI in another (EDT). So, here's the relevant chunk of pseudcode:
class Downloader {
download() {
progress.startDownload();
while(hasMoreChunks()) {
downloadChunk();
progress.downloadedBytes(n);
}
progress.finishDownload();
}
}
class ProgressDisplay extends JPanel {
JLabel label;
startDownload() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText("Download started");
}
});
}
downloadedBytes(int n) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText("Downloaded bytes: " + n);
}
});
}
finishDownload() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
label.setText("Download finished");
}
});
}
}
I love the fact that Java does not support closures and the code is crystal clear to me. Jokes aside, I'm wondering... Am I doing it wrong? Is it possible to eliminate all this ugly boilerplate with SwingUtilities
, anonymous implementation of Runnable
in every method etc.?
My case is slightly more complicated than this, but I'm trying not to overengineer by implementing proxies or something like that.
There is not much you can do to avoid the boilerplate code without introducing a lot of redundant code elsewhere. But you can make it a little bit nicer with a small abstract helper class and some unusual formatting.
public abstract static class SwingTask implements Runnable
{
public void start()
{
SwingUtilities.invokeLater( this );
}
}
startDownload() {
new SwingTask() { public void run() {
label.setText("Download started");
} }.start();
}
The code formatting is meant to emphasize that all the code in this single line is basically uninteresting boilerplate code that can easily and safely be copied to other places where it is needed. We have been using this formatting style now for a while and it turned out quite useful.