Navigator and MenuBar Problem

Hi everybody,

i need your help. i´m trying to add a menubar to my application to switch the single views.
therefor i´m using the navigator api.
my plan was to add the menubar to a view and only change the following layout deppending which button in the menubar is pressed.

the menubar is shown but there is no button (“do something”)

here my code:

protected void init(VaadinRequest vaadinRequest) {
...  
        //Navigator
        // Create a navigator to control the views    
        navigator = new Navigator(UI.getCurrent(), new VerticalLayout());
      
        // Create and register the views
        navigator.addView("View3", new View3());
        navigator.addView("View4", new View4());
 ...       
public class View3 extends VerticalLayout implements View {
   public View3() {
   setSizeFull();

   Button button = new Button("do something",
                new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                System.out.println("blabla");
            }
        });
        addComponent(button);
        setComponentAlignment(button, Alignment.MIDDLE_CENTER);
    }        
        
    @Override
    public void enter(ViewChangeEvent event) {
        Notification.show("View3 entered");
    }
}

Your problem starts here:

navigator = new Navigator(UI.getCurrent(), new VerticalLayout()); Navigator controls a component container such as a UI, Panel, or a layout like VerticalLayout. But you need to add the layout to the UI.

Moreover, as you want to use the menu made from buttons that you use to display something in the view area, they should not be part of the view area, as you have in your view class.

You seem to have taken your view class from the LoginView in the Navigator section in the book. Notice that in that example, the navigator controls the entire UI content, not a view area in the UI, as would probably be in your case.

The MainView class in the example is one way to do what you are looking for, although there the view fills the entire UI and the view area is controlled manually within the view by using view parameters.

ahh ok, i think i got i now.

here´s my code: OK?!


public static enum VIEWS {
        View1, View2, View3, View4, View5
    }; 
....
         //Navigator
        // Create a navigator to control the views    
        navigator = new Navigator(this, this);
        
        // Create and register the views
        navigator.addView(VIEWS.Main.toString(), new MainView());
        navigator.navigateTo(VIEWS.Main.toString());       
...
    }

public class MainView extends VerticalLayout implements View {

    private MenuBar menu;
    VerticalLayout vl = new VerticalLayout();

    public MainView() {
        
        //Menubar
        MenuBar.Command mycommand = new MenuBar.Command() {
            public void menuSelected(MenuItem selectedItem) {
                getUI().getNavigator().navigateTo(MAIN + "/" +selectedItem.getText());
            }
        };
            
        menu = new MenuBar();
        menu.setWidth("100%");
        for(VIEWS v :VIEWS.values()){
            menu.addItem(v.toString(), null, mycommand);
        }
        addComponent(menu);
        addComponent(vl);       
    }       
    
    @Override
    public void enter(ViewChangeEvent event) {
        System.out.println(event.getParameters());
        if(event.getParameters() == null ||
                event.getParameters().isEmpty()){
            // Throw Exception
        } else if (event.getParameters().equals(VIEWS.View1.toString())){
           vl.addComponent(new View1());
        } else if (event.getParameters().equals(VIEWS.View2.toString())){
            vl.addComponent(new View2());
        } else if (event.getParameters().equals(VIEWS.View3.toString())){
            vl.addComponent(new View3());
        } else if (event.getParameters().equals(VIEWS.View4.toString())){
            vl.addComponent(new View4());
        } else if (event.getParameters().equals(VIEWS.View5.toString())){
            vl.addComponent(new View5());
        } else {
            //Throw Exception
        }
    }

I can’t say if all the details work, but roughly yes, that’s one way to do it.

As I noted earlier, if you have just one top-level view there, the MainView, you might want to organize the navigation differently. In the other approach, you would have the menu in the UI’s content, and have the navigator control a layout to insert different views into it. Unfortunately, I don’t have a ready example of this approach.


Sampler’s navigation example
demonstrates yet another approach, but unfortunately its source code may be a bit difficult to grasp, as there’s no UI class in the example code.

You may also gain some insight for your menu application from this:


https://vaadin.com/blog/-/blogs/a-recipe-for-a-data-centric-rich-internet-application

I use similar approach to write the jdal sample. However, the views and button bar are defined in Spring application context definition file instead code:

<!-- Top button menu -->
   <vaadin:button-bar id="buttonBar" scope="prototype">
           <vaadin:actions>
               <vaadin:navigator-action caption="Books" view-name="bookMainView" 
                   icon="classpath:/org/freedesktop/tango/22x22/mimetypes/x-office-address-book.png"/>
               <vaadin:navigator-action caption="Authors" view-name="authorMainView" 
                   icon="classpath:/org/freedesktop/tango/22x22/apps/preferences-desktop-theme.png"/>
               <vaadin:navigator-action caption="Categories"  view-name="categoryMainView"
                   icon="classpath:/org/freedesktop/tango/22x22/places/folder.png" />
               <vaadin:navigator-action caption="Users" view-name="userMainView" 
                   icon="classpath:/org/freedesktop/tango/22x22/apps/system-users.png"/>
               <vaadin:navigator-action caption="About" view-name="aboutMainView" 
                   icon="classpath:/org/freedesktop/tango/22x22/apps/help-browser.png"/>
               <bean class="org.jdal.vaadin.ui.action.ExitAction" p:caption="Exit" 
                   p:icon="classpath:/org/freedesktop/tango/22x22/actions/system-shutdown.png" />
           </vaadin:actions>
   </vaadin:button-bar>

But should be no problem in defining them directly in code using the class ButtonBar.


http://www.jdal.org/vaadin-sample-2.0.M2/
(log with admin/admin)

this is exactly what i was looking for. i´ll try to change my code tomorrow. thank you for the link.

hmm, it´s really a little bit difficult to grasp :confused:

i´m not sure where to cut the code an which part i had to put in the init method of my ui class.