- Simple POJO model.
- Layout out the Swing components.
- Responds to user action by sending request to Control.
- Responds to Controller responds.
- Receives request from the View.
- Do logic.
- Sends Responds to View(s).
In my previous blog we have seen that each View is only responsible of its Swing component and what happens in other view is it totally unaware of. Try to think of separation of concern. It is the responsibility of the Controller to call the Response methods in each Views that should be updated.
And the corresponding Controller code:
The Toolbar is yet Another View
So now lets start with looking how to add a JToolBar to our Swing client. If you think of it for a while you will realize that the toolbar is yet another view. So lets write a new class that extends from our AbstractView.
I have here used javax.swing.Action for base class, since they contain all graphical properties such icon, label and tooltip. But also javax.swing.Action can be used for JButton and in JPopupMenu and JMenuItem.
And I have also deliberately not created a abstract class for our action, which could have loaded our images, since I do not believe that such extra abstraction class will not bring any extra to our code nor reduce the number of lines. It will only make our client code more less understandable. But what would justify an extra abstraction layer is if abstract action class called the Controller in thread safe ways and change cursor to busy and in case of failure show a generic exception dialog. That would really bring something to our code, but not loading icons, using Action is quite straightforward and I like to see directly what my code does.
Handling Context Sensitive Global Actions
So after realized that the toolbar is just another view, lets move onto how to make the toolbar context sensitive, i.e. when switching active panel/window the save actions is replaced with the active panel/window save action. But before we must first decide where the concrete Swing save action should be located. It clearly belong to the concrete view. Think again of separation of concern. But what we must do is to expose the global actions so we can send them to the toolbar view. And lastly where do we wire the views together? In the Controller of course.
Let first add an extra method in our abstract view:
Then in our controller we wire the global actions from the view to the toolbar view.
And in our toolbar view:
The last thing we need is to do is to switch back to the default when changing to other views. Here it can be justified to introduce some kind of View lifecycle mechanism, so the programmer does not have to concern about setting the correct toolbar action each time a new View is retrieved.
Managing a Statusbar
After thinking the GUI as a composition of different views, it should not be surprising to think of the statusbar as yet another view as well. And where is the respond sent to update this view. In the Controller of course. Here is a simple example how to implement a statusbar with swinglabs JXStatusBar.
Managing Modular Popup Windows
The modular popup windows is also yet another view. The only difference it needs a parent JFrame to show from. And the solution to that is simple. Each View has a reference to the AbstractFrame that holds the JFrame via getFrame().