I'm looking for a good Swing application architecture. One pattern is see mentioned is separating your Swing UI from model (the core of your application), and then listening to model property changes with propertychangelisteners. There might be additional controller-type layer between or beansbinding in use, but the main idea is:
This is a popular pattern, right? Isn't it also fundamentally broken?
- you start up with binding a number of your model beans to Swing components with
1) firing PropertyChangeEvents from the relevant model beans
2) creating PropertyChangeListeners (either in Swing view or controller) that listen to those events and update Swing components accordingly
- your model beans are now glazed with property firing. There's n properties that fire PropertyChangeEvents when they are updated. No one can really practically tell when they call SomeModelService.foo(), which property events will fire as a result (this will also change in time when foo() and other model internals get updated.....and caller of SomeModelService.foo() cant and shouldnt be aware of the internals)
- all is well as long as SomeModelService.foo(), .bar(), .baz() etc are all called in EDT
- at a later point someone adds a feature which takes a long time to run. A new thread is created and SomeModelService.dodo() is called in that thread, outside of EDT
- as a result some PropertyChangeEvents are fired and listeners update the Swing components - still outside of EDT - and your code is broken and can for example lockup
a) am I understanding this correctly?
b) isn't this kind of a big deal? As in, probably majority of code which uses this popular pattern, is broken or ready to be broken by updates very easily?
c) how to manage this problem?
For c) I am think about not using binding to model at all, or firing my model PropertyChangeEvents using SwingUtilities.invokeLater() - not too pretty but if I can add firing code with aspects (http://www.damnhandy.com/javabean-aspect/) this should not pollute my model too much...
When most people talk about Swing apps they often refer to the MVC design pattern - separating the model and view and controller. Yet Swing API is kinda designed using MVC pattern called delegate-view. Delegate here means model+controller.
Using a JTable as example. Say you have a view class and a table model class. Now the table model class clearly represents the model. But is it also the controller? Sure. When you trigger those fireXXX methods from the table model class, you are controlling the view output.
Also once you have a Swing component open your app is inside the event dispatching thread (EDT). And this means single threaded or the EDT can only run one thread at a time.
Now I'm not sure if the MVC is broken or any other pattern is broken. But most of the time by the time you are done, some form of the MVC pattern is used directly or indirectly.
When I did my SCJD assignment, I could have said I used MVC but even myself am not sure.