Steps to Make Multi-View Page
Amad,
I will do my best to describe what I have done which seems to work - Keith/Team, feel free to correct me anywhere I speak incorrectly.
Also, most of my guidance came from the post I mentioned earlier - http://forum.springframework.org/showthread.php?t=11737 which implements what you and I have been looking for, but rather than using splitpanes it uses internal frames.
To create a multi-view page, you have to create custom implementations of PageDescriptor, ApplicationPage, and ApplicationWindow.
1.)
First, extend DefaultApplicationWindow (mine is DualViewWindow) and override the 'createPage(PageDescriptor)' method - this method in the default implementation creates a DefaultApplicationPage instance - you want to override it to provide your custom application page object.
2.)
Create an implementation of the PageDescriptor interface that supports multiple views (mine supports two -DualViewPageDescriptor), and then implement the 'buildInitialLayout' method to work with the 'PageLayoutBuilder' instance to 'install' the views in a logical order.
Code:
public void buildInitialLayout(PageLayoutBuilder builder) {
builder.addView(view1Id);
builder.addView(view2Id);
}
3.)
Extend AbstractApplicationPage - implement 'addView' to just say 'showView' with the same arguments (the same as DefaultApplicationPage). E.G.:
Code:
public void addView(String id) {
showView(id);
}
Set up your control objects in this class (e.g. split pane) as variables:
private JSplitPane splitPane;
and override three methods (at least):
giveFocusTo - implement this method to target each element under the split pane as neccessary - here is my implementation:
Code:
PageComponentPane pane = pageComponent.getContext().getPane();
pane.requestFocusInWindow();
fireFocusGained(pageComponent);
createPageComponent - This method wants you to produce the control for a page component (downstream from a showView request), and wire it up to the control. Think of this method as being in mid process of preparing the control for a particular view, and putting it into the control for the page. Here is my implementation:
Code:
PageComponent pageComponent = descriptor.createPageComponent();
pageComponent.setContext(new DefaultViewContext(this, new PageComponentPane(pageComponent))); splitPane.add(pageComponent.getContext().getPane().getControl());
return pageComponent;
getControl - this is the start of the entire process for an ApplicationPage (the method which eventually causes createPageComponent to be called for each view) - this is where you want to set up your page's control, and prepare it for the subsequent 'createPageComponent' calls:
Code:
if(splitPane == null) {
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
// this method causes createPageComponent to be invoked
// for each view... which puts the views into the split pane.
this.getPageDescriptor().buildInitialLayout(this);
// sets the last component as the active one... you can set anyone you
//want...
setActiveComponent();
}
return splitPane;
Finally, you want to ensure that focus requests on the view are sent through the infrastructure of spring rich, and you do so by utilizing the showView method...
If one of your views (extending AbstractView) has a certain jcomponent in it, you can notify spring of focus changes by saying:
Code:
public class FocusNotifier implements FocusListener {
public void focusGained(FocusEvent e) {
getContext().getPage().showView(this.getId());
}
public void focusLost(FocusEvent e) { }
}
attach this listener to anything in the view of significance that can gain focus - this will ensure that the commands will be updated when focus is gained implicitly (e.g. outside the invocation of a show view command).