Section 9.3. Building the Bike Navigator View

team bbl


9.3. Building the Bike Navigator View

Now, you're ready to take the generic application shell you just built and customize the central page area so it displays an interactive "Bike Navigator" component. You'll see how to build the Bike Navigator, which is an implementation of a view in Spring Rich terminology. The Spring view is similar to Eclipse RCP's concept of a view.

When you're done, you'll have a interactive view into your bike store's inventory. You'll also have local handlers for the various controller actions (or commands) supported by this view. Specifically, you'll code a local handler for the shared Properties command, which will display the properties of the selected Bike when executed.

9.3.1. How do I do that?

As you build your BikeNavigator, the first thing you need to do is define a ViewDescriptor for it in configuration code. Each view defined in Spring Rich has a corresponding descriptor. The descriptor, a singleton, provides metadata about the view, including its name, icon, and implementation class. It also acts as a factory for creating view instances of a specific implementation class, as many view instances of the same class can exist on different windows. Note that views are not singletons.

    <bean       >         <lookup-method             name="createView"             bean="bikeNavigatorViewPrototype"/>     </bean>

Notice the <lookup-method> element. It will override this ViewDescriptor implementation's createView method at runtime with a implementation that will return a new bikeNavigatorViewPrototype on each invocation. This lets Spring configure and manage your custom BikeNavigator view instanceswhich you'll define a specification for next.


Note: You don't see descriptor properties like "name", "image", or "caption" because they are all configured automatically.

Once the ViewDescriptor is defined, you'll create the bean definition and implementation for the BikeNavigator view. This prototype encapsulates the creation of a graphical view control we select (any Swing JComponent). It also encapsulates the controller logic to coordinate between that control and our RentABike business interface in response to user events. Below is the BikeNavigator bean definition:

    <bean        singleton="false">         <property name="rentABike">             <ref bean="rentABike"/>         </property>     </bean> </beans>

BikeNavigator is a prototype because the same type of view may be active in several application windows at the same time. You cannot share the same view instance because a Swing component can only be a contained within a single Container.


Note: Views are NOT singletons. Because they're managed by Spring, they can fully leverage dependency injection. You inject the façade here.

That's it for view configuration code. Now it's time to code the BikeNavigator view implementation and controller logic. You'll inherit from AbstractView, which gives you basic behavior common to all view implementations. For now, you'll only be able to view a list of bikes, and view properties on an existing bike:

public class BikeNavigator extends AbstractView implements ApplicationListener {     private JTree bikesTree;     private PropertiesCommandExecutor propertiesExecutor =         new PropertiesCommandExecutor( );     private RentABike rentABike;


Note: The setter allows configuration of a RentABike reference using standard setter dependency injection.
    public void setRentABike(RentABike rentABike) {         this.rentABike = rentABike;     }


Note: The registerLocalCommand-Executors method attaches local executors to commands.
        protected void registerLocalCommandExecutors(         PageComponentContext context) {         context.register(GlobalCommandIds.PROPERTIES, propertiesExecutor);     }


Note: The create-Control method returns the root Swing control realizing this view's UI.
    protected JComponent createControl( ) {         initBikesTree( );         return new JScrollPane(bikesTree);     }     private void initBikesTree( ) {         DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode( );                  // get the Bikes from store inventory         Collection bikes = rentABike.getBikes( );         // Add tree nodes for each Bike         for (Iterator it = bikes.iterator( ); it.hasNext( );) {             rootNode.add(new DefaultMutableTreeNode(it.next( )));         }         // Create the Tree Model and JTree implementation         bikesTreeModel = new DefaultTreeModel(rootNode);         bikesTree = new JTree(bikesTreeModel);         bikesTree.setRootVisible(false);     }


Note: The PropertiesCommand-Executor encapsulates controller logic for handling a request to view.
    private class PropertiesCommandExecutor     extends AbstractActionCommandExecutor {         private BikeForm bikeForm;         public PropertiesCommandExecutor( ) {             // The command should only be enabled when a single object is             // selected in the Bike Tree.             addGuard(new SingleSelectionGuard(bikesTree));         }         public void execute( ) {             // Create a new Bike Form for editing the selected Bike         bikeForm = new BikeForm(getSelectedBike( ));


Note: The Bike Form will let us edit the selected Bike's properties when the Properties command is executed.
            // Display the form in a Titled Dialog             TitledPageApplicationDialog dialog =                 new TitledPageApplicationDialog(bikeForm, getWindow( )) {                 protected boolean onFinish( ) {                     bikeForm.commit( );                     getRentABike( ).saveBike((Bike)bikeForm.getFormObject( ));


Note: Save or update the bike in inventory, using the RentABike façade.
                    bikesTreeModel.nodeChanged(getSelectedTreeNode( ));                     return true;                 }             };             // Display the dialog on the screen             dialog.showDialog( );         }     } }

That's it! You now have a Bike Navigator view defined providing a hierarchical view into current store inventory, realized by a Swing JTree. You also have a local command executor for the Properties command defined that will allow the user to edit an existing Bike in inventory using a BikeForm. In the next lab, you'll implement the BikeForm. You're not quite ready to execute it, because you don't have the full implementation of the property editor yet.

9.3.2. What just happened?

You just defined the first domain-specific component of the RentABike application, the Bike Navigator View. You saw how views act as control factories for an underlying Swing widget that realizes a navigation function. You also saw how local command executors provide targeted controller logic that is only enabled when certain conditions are satisfied.

It's time to put it all together. Let's walk through the big picture of what "just happens" now when our rich client application starts up:

  1. The RentABikeLauncher bootstrapper kicks everything off. It delegates to the ApplicationLauncher framework class, parameterizing the launcher with our startup and root application context definitions.

  2. The ApplicationLauncher loads the startup context from the classpath and displays the application splash screen.

  3. The ApplicationLauncher creates the root application context from the classpath. It retrieves the "application" singleton from the context to initiate the lifecycle of your RentABike Rich Client.

  4. The first major step in the app's lifecycle is to create the main application window displaying the page identified by the startingPageId property. This "starting page" is the bikeNavigator. For your application, you only have a single page with a single view defined.

  5. Once the framework creates the window, the ApplicationLifecycleAdvisor loads the windowCommandBarDefinitions configuration. The window creates and populates its menu bar, tool bar, page area, and status bar.

  6. The window is opened and displayed. The window's command bars and the central page area containing your new Bike Navigator View are displayed (Figure 9-2).

Figure 9-2. The Bike Store application main page has amenities, such as a menu bar


The properties command is bound to the execute( ) method that we added to the PropertiesCommandExecutor inner class in the BikeNavigator controller. When you select a bike and hit the ALT-ENTER key, Spring Rich looks for the command executor that's bound to targetable Properties command and executes it.

    team bbl



    Spring. A developer's Notebook
    Spring: A Developers Notebook
    ISBN: 0596009100
    EAN: 2147483647
    Year: 2005
    Pages: 90

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net