0

I am trying to understand how the UI components should be wired in Java. As far as regular "server" classes are concerned, I am trying to use interfaces and inject everything using Spring. In case of the UI, should similar approach be used?

To be more precise, let's consider the following:

class Panel1 extends JPanel{

    public Panel1(Service service, DBConnector db);
}

class Panel2 extends JPanel{

    public Panel1(Delegate delegate, Executor exec);
}

class MainFrame{

    public MainFrame(Service service, DBConnector db, Delegate delegate, Executor exec){
        Panel1 p = new Panel1(service, db);
        Panel1 p = new Panel1(delegate, exec);
    }
}

vs

class MainFrame{

    public MainFrame(Panel1 panel1, Panel2 panel2){
    }
}

I just wanted to get a general feeling what is more appropriate in the UI world, if it at all differs from the regular classes (possibly with the fact that there could be many panels involved in the main frame)

Bober02
  • 15,034
  • 31
  • 92
  • 178
  • Using constructors is one way to pass references. But I'd personally avoid mixing layers. One approach is to have a controller class (part of an MVC) and wire that with references to underlying Service and Database layers. Btw, what does Delegate do ? – James P. Dec 04 '12 at 17:00
  • Btw, have you been succesful at calling Spring's application context within Swing ? Because up until now I've had to pass to store a reference in a static variable to make it accessible. – James P. Dec 04 '12 at 17:02
  • This is a random example - so which approach would you prefer? At some point i need to instantiate a JFrame with a lot of panels in it, which either needs to take in as parameters everything it requires, or take each panel, or take a factory, but factorry would then have to take all services etc. What is the right way :) ? – Bober02 Dec 04 '12 at 17:02
  • A few Swing programmers seem to come up with their own recipes. What I'd do is something similar to the MVC with mediator strategy as on this [link](http://www.emilmont.net/doku.php?id=java:design_patterns:model_view_controller). Then let the controller play the middle man between the UI and service layer interfaces. That way things are better decoupled and one or more views (can be JPanels) can be hooked into the same model. – James P. Dec 04 '12 at 17:06
  • Can you provide an example, as I do not see how the JPanel would use the service via a mediator – Bober02 Dec 04 '12 at 17:09
  • You could click a button in a JPanel, this would call the Controller, perhaps just using a String parameter, which in turn would call a Service method and possibly catch any return information. Then the Controller would update the Model and forward/trigger changes to the JPanel through Observer/Observable or Listener pattern. The Mediator pattern just allows one to decouple the Model and View so they don't need to know about each other. – James P. Dec 04 '12 at 17:15
  • And if that's as clear as mud, here's some related links :) . http://stackoverflow.com/a/3217753/225899 http://stackoverflow.com/questions/3066590/gui-not-working-after-rewriting-to-mvc/3072979#3072979 http://stackoverflow.com/questions/2330385/up-to-date-swing-mvc-example-question http://stackoverflow.com/questions/3370413/decoupling-the-model-and-input-checking http://stackoverflow.com/questions/2824495/applying-mvc-to-domain-driven-design – James P. Dec 04 '12 at 17:28
  • I don't see how that would fit into my problem. I do not have any model as such, just a couple of JcomboBoxes which have their model set directly in the view. I could extract that logic out to the controller but then rather than calling a private method on the UI class, I need to call the controller with some set of parameters, and then that controller has to generate some data, and has to send it back to the UI. The problem is, when I click one combobox, I want to potentially generate data for all other combobxes/ui controls – Bober02 Dec 04 '12 at 17:38
  • and one final thing - if you have multiple panels, then potentially each one has a view, model and controller of their own, if they are very different panels i.e. load data panel, adjust settings panel etc\/ – Bober02 Dec 04 '12 at 18:01
  • @Bober2 It's just a suggestion and may not suit your purposes. About the model, it can be a Swing one (JTable => TableModel). Also, the idea with MVC is that multiple views can be updated from the same data through Listener or Observer. As for the controller, a single instance could be used. – James P. Dec 05 '12 at 21:08

1 Answers1

3

I haven't seen anyone using DI in for UIs; this might be because DI is a pretty new concept (compared to building UIs) or that most people fled to MVC after living in UI hell for a while and MVC solves all the problems.

Also, most UIs are static in the sense that you can open and close windows/dialogs with buttons but you can't replace one dialog with another. It would be handy but only if I, as a user/consumer, could do that. There is little point to write two dialogs that do the same thing and then use DI to wire one or the other; you either need two different dialogs or only one.

When UIs support to be extended (like Eclipse), they use a plugin system to load UI elements at runtime and the code in there discover menus, toolbars, etc. and add elements.

e4 (the latest code base for Eclipse) uses DI for many things but not for building the UI. Again, the UI is usually static in the sense that you never have two or more services in a certain place from which the user could chose from.

So using DI might make sense but it's probably ground breaking work (i.e. you'll have to explore the possibility space and find the low complexity valleys yourself).

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 1
    `JHotDraw`, cited [here](http://stackoverflow.com/q/13312223/230513), is a useful study of GUI design patterns. – trashgod Dec 04 '12 at 17:54