Directory

← Back

Navigator7

API for more web-oriented Vaadin applications

Author

Rating

One of the goals of Vaadin 7 is (according to Joonas): "Window management should be completely revised to make supporting multi-window applications, tabbed navigation, bookmarking and web-style applications easy and logical."

I think that Navigator7 extactly addresses that.

API for more web-oriented applications.

  • Notion of application level window that includes a page
  • Easy navigation between pages
  • Templating around pages (as header/footer/...)
  • Support for fixed and fluid designs.
  • Better support for multi-tab browsing.
  • Rich URI analysis, with entry points for your persistency code (as JPA).
  • Parameter injection (in page object's fields).
  • SEO crawlable pages
  • "confirm/save before leave" support
  • general Interceptor (filter) mechanism
  • batch jobs (needing to build URLs, i.e. for mails)

This is used in production for BlackBeltFactory.com.

This is version 7 because ... Vaadin 7 should improve to the point this addon is useless ;-) May be used to support discussion around Vaadin 7 API? [http://vaadin.com/web/joonas/wiki/-/wiki/Main/Vaadin_7_API]

Sample code

/**
 * In your NavigableApplication class, you define the list of pages,
 * and your descendent of NavigableAppLevelWindow that the application must instantiate.
 * 
 * @author John Rizzo - BlackBeltFactory.com
 */
public class MyNavigableApplication extends NavigableApplication {

//    @Override
//    public void init() { ....
//      We don't override the init() method because we don't create the Window instance ourselves (the Navigator does that; and what is a Window by the way, don't wanna know about that notion: we have pages).
    
    public MyNavigableApplication() {
        // We need to do that in the constructor (and not later), to ensure that the init method in the ancestor has the PageTemplate and the pages.
        registerPages(new Class[] {Dashboard.class, Editor.class, Ticket.class, ParamTestPage.class});
        setTheme("navigator7");
    }

    @Override
    public NavigableAppLevelWindow createNewNavigableAppLevelWindow() {
        return new MyAppLevelWindow();
    }
    
}
/** Defines the template (header/footer/...) of our application level windows
 * 
 * Demo of: Header/Footer templating. Note the subtle overriding of createComponents to refine the layout apprearance.
 *          NavigationListener to get any page transition event.
 *          Navigator.navigateTo()
 * 
 * @author John Rizzo - BlackBeltFactory.com
 */
public class MyAppLevelWindow extends HeaderFooterFixedAppLevelWindow {

    @Override
    protected Component createHeader() {
        VerticalLayout header = new VerticalLayout();
        header.addStyleName("header");  // Application specific style.
        header.setWidth("100%");
        header.setHeight("100px");
        
        ////// Hello
        Label l = new Label("Hello, I'm a HEADER with a menu.");
        l.setWidth(null);
        header.addComponent(l);
        header.setComponentAlignment(l, Alignment.TOP_RIGHT);

        ///// NavigationListener label
        final Label navLabel = new Label();
        navLabel.setWidth(null);
        header.addComponent(navLabel);
        header.setComponentAlignment(navLabel, Alignment.TOP_RIGHT);
        getNavigator().addNavigationListener( new NavigationListener() {
            @Override  public void pageChanged(NavigationEvent event) {
                navLabel.setValue("NavigationListener: pageClass = "+ event.getPageClass() +
                                                  " -- params = " + event.getParams());
            }
        });

        ///// Menu
        MenuBar menuBar = new MenuBar();
        menuBar.setWidth("100%");
        header.addComponent(menuBar);
        header.setComponentAlignment(menuBar, Alignment.BOTTOM_LEFT);
        
        // Create one menu item with each page of the application
        // this is little bit artificial in the example. In a business application, you manually select (name) the pages to put in the menu, instead of having a loop.
        // something like: 
        //        menuBar.addItem("Manage Your Tickets", new MenuBar.Command() {
        //            public void menuSelected(MenuItem selectedItem) {
        //                getNavigator().navigateTo(Ticket.class);
        //            }
        //        });
        Collection<Class <? extends Component>> pageClassColl = MyNavigableApplication.getCurrent().getNavigatorConfig().getPagesClass();
        for (final Class<? extends Component> pageClass : pageClassColl) {
            menuBar.addItem(pageClass.getSimpleName(), new MenuBar.Command() {
                public void menuSelected(MenuItem selectedItem) {
                    getNavigator().navigateTo(pageClass);
                }
            });
        }

        return header;
    }

    @Override
    protected Component createFooter() {
        VerticalLayout vLayout = new VerticalLayout();
        vLayout.setWidth("100%");
        
        Label ll = new Label("Hello, I'm a footer!");
        ll.setWidth(null);
        vLayout.addComponent(ll);
        vLayout.setComponentAlignment(ll, Alignment.TOP_CENTER);
        
        
        Label l = new Label("Developped by John Rizzo in 2010 for Vaadin.");
        l.setWidth(null);
        vLayout.addComponent(l);
        vLayout.setComponentAlignment(l, Alignment.BOTTOM_CENTER);
        vLayout.setHeight("200px");
        return vLayout; 
    }

    @Override
    protected ComponentContainer createComponents() {
        ComponentContainer result = super.createComponents();
        this.getFooterBand().addStyleName("footer");   // We apply the footer to the whole outer band, not only to the fixed width inner band.
        return result;
    }

}
/**
 * Demo of @Page, 
 *         home page concept
 *         PageResource link
 * 
 * @author John Rizzo - BlackBeltFactory.com
 */
@Page(uriName="dash")
@SuppressWarnings("serial")
public class Dashboard extends CustomComponent {

    GridLayout gl = new GridLayout(3, 3);

    public Dashboard() {
//        setSizeFull();    Non sense in a fixed web design (FixedPageTemplagte).
        VerticalLayout mainLayout = new VerticalLayout();
        mainLayout.setSpacing(true);
        mainLayout.setSizeFull();
        setCompositionRoot(mainLayout);

        mainLayout.addComponent( new Label("Note the uri: '#dash' instead of 'Dashboard' (page class name)." +
        		" This is due to the @Page(uriName=\"dash\") annotation on the Dashboard class." ));

        mainLayout.addComponent( new Label("Dashboard is also the default home page. Try to remove the URI from the URL, e.g. http://localhost:8080/Navigator7 instead of http://localhost:8080/Navigator7#dash" ));

        VerticalLayout vLayout = new VerticalLayout();
        vLayout.addComponent(new Label("This home page is displayed (with a notification if you type a wrong URL. Try this:"));
        PageResource pageResource = new PageResource(Ticket.class, "ABC");
        vLayout.addComponent(new Link(pageResource.getURL(), pageResource));
        String wrongUrl = "#NonExistingPage";
        vLayout.addComponent(new Link(wrongUrl, new ExternalResource(wrongUrl)));
        mainLayout.addComponent( vLayout );

        mainLayout.addComponent(gl);
        gl.setSizeFull();
        gl.setSpacing(true);
        for (int i = 0; i < 9; i++) {
            Panel p = new Panel("Board " + i);
            gl.addComponent(p);
            p.setSizeFull();
        }
    }

}

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

Added parameter injection.

[code] public class ProductPage extends VerticalLayout implements ParamChangeListener {

@Param(pos=0, required=true) Product p;          // "34"
@Param(pos=1)                String value1;      // "AAAA"
@Param(pos=2)                String value2;      // "BBBB"

@Param                       String namedValue;  // "namedValue=CCCC"
....

[/code]

and SEO enabled pages: @Page(crawlable=true)

Released
2010-06-23
Maturity
BETA
License
Apache License 2.0

Compatibility

Framework
Vaadin 6.2+
Vaadin 6.0+ in 7.0
Browser
N/A

Vaadin Add-on Directory

Find open-source widgets, add-ons, themes, and integrations for your Vaadin application. Vaadin Add-on Directory
The channel for finding, promoting, and distributing Vaadin add-ons.
Online