5

Let us assume we have a simple Java MVC Application with the classes Model, View and Controller. The View class directly inherits from JFrame. As in a classic MVC setup, the view has a reference to the model and the controller has a reference to the view and to the model. As I just learnt, all GUI-related stuff should be wrapped in a SwingUtilities.invokeLater or something similar. Now what is the right way to initialise/start this application? I think the creation of the model and the controller should not be inside of the EDT, right? So I would come up with something like this:

final Model model = new Model();
SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        final View view = new View(model);
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Controller(model, view);
            }
        }).start();
    }
});

Is this the correct way and a good idea or are there better possibilities?

EDIT: As correctly stated by @trashgod, a related example is examined here. Then I extend my question: What is basically done there is the following:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
});

But isn't it wrong to run the whole application in the EDT?

Community
  • 1
  • 1
Simon
  • 4,103
  • 7
  • 28
  • 53
  • 1
    I would "guess" the controller will need some way to "start" or "show" the view...Also, you should NOT use a second `Thread` for this, simply execute the update within the context of the `run` method of the `Runnable` you pasted to `SwingUtilities.invokeLater`, so that all your UI interactions are taking place within the context of the EDT... – MadProgrammer Nov 20 '13 at 22:33
  • 1
    A related example is examined [here](http://stackoverflow.com/a/3072979/230513). – trashgod Nov 20 '13 at 23:29
  • See the updated question. @MadProgrammer: The view is set up and becomes visible in it's constructor call. It is then updated via events of the model (model extends Observable and the view observes the model). – Simon Nov 21 '13 at 06:43
  • 1
    *"But isn't it wrong to run the whole application in the EDT?"* That's contextual. So long as the model/view/controller are not block the EDT, this is where the belong. If any part needs to perform some long running process, then it should off load that task to another thread so as not to block the EDT – MadProgrammer Nov 21 '13 at 06:45
  • 1
    Until a JComponent is "realized", i.e. visible, you can setup on whatever thread you want. Do all the setup, then call `pack()` and `setVisible()`. Many apps spawn threads to setup complex GUIs. – user949300 Nov 21 '13 at 06:58

1 Answers1

3

All the code that creates or interacts with Swing components must run on the event dispatch thread. So the second form of your code, that is the bellow code is correct.

`SwingUtilities.invokeLater(new Runnable() {
        @Override
    public void run() {
        Model model = new Model();
        View view = new View(model);
        new Controller(model, view);
    }
});`

The reason for all UI code that must run through EDT or worker thread is to avoid Multithreaded problem. You may see many swing programs may not init code in EDT. This is perfectly ok. But when your swing gets complecated, then there is probability for error. my self in simple swing apps lanching from main thread, i did not face dead locks are race conditions. Quick tasks uses EDT and long running tasks uses worker threads. Here is link on multithreaded problem on ui

Please let me know if i went wrong

cJ_
  • 486
  • 1
  • 4
  • 19