简体   繁体   中英

Swing with Guice

I'm already using Guice for the data model of my app, and so far I'm quite happy with it. However, the GUI part is about to become a Big Ball of Mud. I find it hard to use Guice here, because Swing components and models are tightly coupled, and often force a certain initialization order.

My application consists basically of a header with a lot of filters, a central and quite complex JTree component, and a lot of actions (eg from a JPopup), menus, dialogs, wizards etc. The main problem is that I have a lot of coupling between the components and actions (eg complicated validations, tree updates...). Could you give me some advice how to structure that GUI with Guice?

I'm aware of libs like GUTS, but the documentation is really thin, I'd rather avoid to add another dependency to my project and to learn another API (eg I don't know the Swing Application Framework).

I would advise to look at Guts-GUI . It is a Swing UI framework based on Guice dependency injection model.

I'd rather suggest a proper MVC, even better Presentation Model - View - Controller. Separate your code properly and Guice will fit in naturally. For example:

View classes should have a building part which draws the static content (labels, the tree, buttons, etc) and updating code which reacts to changes in the Presentation Model. All the action listeners should invoke some code on the controller. Both the Presentation Model and the controller should be injected by Guice, like all the other dependencies.

This organization would allow for easy testing with replacing the View with some testing code which will listen to changes in the Presentation Model and invoke actions on the controller.

I think the problem is probably the overall architecture. You probably want to see if you can refactor the application to be simpler and more modular. Like Boris recommended, I would also suggest using the Presentation Model pattern - search for Martin Fowler and Karsten Lentzsch - and the JGoodies library.

For the problem with Actions, see how the Swing Application Framework and Netbeans Plaform handle them. For example, if an Action is used in both a view and a menu, you might want to make it available through a global map.

We have recently started on GUICE with swing. Here's what we have done which may be of help to you.

a. When you want to inject a model into a table/tree you could inject a model provider instead and do a provider.get() to get the model in the contructor.

for example

public class Mytable extends JTable {
    public Mytable(Provider<MytableModel> modelProvider) {
        this.setModel(modelProvider.get());
    }
}

b. You could make a model generic and make use of the same model in different tables.

c. The model could have a handle to datasource which could be injected by a factory where necessary with assisted inject. Number of examples available in stack overflow.

d. Your model could be a flexible data structure which uses model to return the relevant cell/leaf/other value.

e. When you have actions, you inject actions in your component builders and attach them to relevant components.

f. Use @Singleton annotation where you have a shared object such as model injected in 2 different objects, such as action and the component.]

g. Use custom scope when you need to use number of instance sets of objects. Custom scopes are great for this as it keeps the code really clean.

Hope the above helps...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM