My project is built upon Java's Swing library. It spawns the EDT which displays my GUI (which works correctly).
The entrance to the program, which initializes the EDT:
public final class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Start());
}
class Start implements Runnable {
private Model model = new Model();
private Controller controller = new Controller(model);
private View view = new View(controller);
@Override
public void run() {
// Initialize the view and display its JFrame...
}
}
}
}
However, when a button / radio box / etc. is clicked within my GUI, the Controller class must perform an action on the model.
My questions are the following:
For example:
public class Controller {
public void updateModel() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
model.somethingSomethingSomething();
}
}.execute();
}
}
public class Model {
public void somethingSomethingSomething() {
notifyListeners(); // This is going to notify whichever GUI
// is listening to the model.
// Does it have to be wrapped with Swing.invokeLater?
}
}
public class View {
// This function is called when the model notifies its listeners.
public void modelChangedNotifier() {
button.setText("THE MODEL HAS CHANGED"); // Does this occur on the EDT?
}
}
Instead of updating your model from doInBackground(), publish() interim results and update your model from process(), which executes on the EDT. In this example, JTable corresponds to your View and TableModel corresponds to your Model. Note that JTable listens to its own TableModel.
You can read about it here: Improve Application Performance With SwingWorker in Java SE 6. In short: all time consuming operations, which are not affected UI must be done in another thread. To show results of operation you must go back to EDT. For example, if you make database search, you should show a progress bar (usually infinite) and start the search using SwingWorker. To show search results in a table, you must be in EDT. Alternatively you can use foxtrot lib (it allows to make your code more Swing convenient without to redesign it). If your controller code permanently updates the swing widgets you should execute it in EDT or at least perform these updates of UI in EDT (using SwingUtilities.invokeLater, chunk processing in SwingWorker or swing.Timer). So your sample is wrong: model update should be up-to-date in EDT.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With