GWT: Menus in UiBinder
Asked Answered
E

6

6

I would like to implement menus (MenuBar, MenuItem) using the declarative approach via UiBinder in GWT 2.0.

I have run into two problems:

  1. Is there a way to add MenuItemSeparators in the .ui.xml file? So far, I have only managed to put MenuBar- and MenuItem-tags into the file.

  2. Using @UiHandler, GWT writes the boilerplate code for event handlers for me. For menus, I need to write commands. How am I supposed to do this using the UiBinder approach? Is there a command tag to put in the .ui.xml file? Do I have to write the boilerplate code for the command handlers myself?

Thanks for thinking about these questions!

Edmee answered 21/1, 2010 at 8:9 Comment(0)
P
7

I agree, if you try to put a MenuItemSeparator in, it will complain stating only a MenuItem can be a child when GWT tries to create the widget . Since this is not currently supported, I suggest that you request this as a future enhancement to the GWT team.

In the meantime, you can add a separator programmatically and add a command in the following manner: The XML file:

<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
    <g:MenuBar ui:field="menuBar">
        <g:MenuItem ui:field="helpMenuItem">Help</g:MenuItem>
        <g:MenuItem ui:field="aboutMenuItem">About</g:MenuItem>
        <g:MenuItem ui:field="siteMapMenuItem">Site Map</g:MenuItem>
    </g:MenuBar>
</g:HTMLPanel>

The Java file(s):

public class Menu extends Composite {
...
@UiField MenuBar menuBar;
@UiField MenuItem helpMenuItem;
...
public Menu() {
    initWidget(uiBinder.createAndBindUi(this));
    // insert a separator
    menuBar.insertSeparator(1);
    // attach commands to a menu item
    helpMenuItem.setCommand(new MenuCommand(HistoryToken.Help));
    ...
}  

public class MenuCommand implements Command {
    final HistoryToken historyToken;

    public MenuCommand(HistoryToken historyToken) {
        this.historyToken = historyToken;
    }

    @Override
    public void execute() {
        historyToken.fire();
    }
}  

public enum HistoryToken {
    Help,About,SiteMap;

    public void fire(){
        History.newItem(this.toString());
    }
}


Elsewhere in my code, I implemented a HistoryListener to catch any changes, i.e.

class HistoryManager implements ValueChangeHandler<String> {
    // 1. get token
    // 2. change it into a HistoryToken
    // 3. perform switch statement 
    // 4. change contents based upon HistoryToken found
...
}  
Pyridoxine answered 15/2, 2010 at 19:29 Comment(0)
G
2

For (1) JavaDoc says:

Use in UiBinder Templates MenuBar elements in UiBinder template files can have a vertical boolean attribute (which defaults to false), and may have only MenuItem elements as children. MenuItems may contain HTML and MenuBars.

For example:

 <g:MenuBar>
   <g:MenuItem>Higgledy
     <g:MenuBar vertical="true">
       <g:MenuItem>able</g:MenuItem>
       <g:MenuItem>baker</g:MenuItem>
       <g:MenuItem>charlie</g:MenuItem>
     </g:MenuBar>
   </g:MenuItem>
   <g:MenuItem>Piggledy
     <g:MenuBar vertical="true">
       <g:MenuItem>foo</g:MenuItem>
       <g:MenuItem>bar</g:MenuItem>
       <g:MenuItem>baz</g:MenuItem>
     </g:MenuBar>
   </g:MenuItem>
   <g:MenuItem><b>Pop!</b>
     <g:MenuBar vertical="true">
       <g:MenuItem>uno</g:MenuItem>
       <g:MenuItem>dos</g:MenuItem>
       <g:MenuItem>tres</g:MenuItem>
     </g:MenuBar>
   </g:MenuItem>
 </g:MenuBar>

Taking the hint from the words "only MenuItem elements as children", my guess is that MenuItemSeparators are not supported

Goldia answered 21/1, 2010 at 9:13 Comment(1)
I was wondering because the Eclipse plugin seems to recognise <g:MenuItemSeparator>...Edmee
S
2

Here's an example of my solution to this, which seems to work pretty well with GWT 2.4.0.

UiBinder:

<g:MenuBar vertical='true' ui:field='mainMenu'>
    <g:MenuItem ui:field='item1'>Item 1</g:MenuItem>
    <g:MenuItem ui:field='item2'>Item 2</g:MenuItem>
    <g:MenuItemSeparator />
    <g:MenuItem ui:field='sub' enabled='false'>
        Submenu
        <g:MenuBar vertical='true' ui:field='subMenu' />
    </g:MenuItem>
</g:MenuBar>

Java:

@UiField MenuItem item1;
@UiField MenuItem item2;
@UiField MenuBar subMenu;
@UiField MenuItem sub;

...

this.setWidget(uiBinder.createAndBindUi(this));
item1.setCommand(new Command() {
    public void execute() {
        History.newItem("item1");
    }
});

Overall not too bad.

Subcontract answered 29/3, 2012 at 20:55 Comment(0)
E
1

I know this question is OLD, but I keep running across this question in my google searches, so i thought it would be important to note that although i haven't seen it documented anywhere yet, i have been using:

<g:MenuItemSeparator/>

successfully in my uibinder template. The gwt eclipse plugin gives me a red error marker, but the MenuItemSeparator compiles and shows up ok. I'm using gwt 2.1.

Just thought someone might be interested to know.

Unfortunately I haven't seen a solution for #2 yet - but I hope they give us something soon.

Eterne answered 17/8, 2011 at 20:22 Comment(0)
H
0

It is possible to add a menuItemSeparator in the ui.xml file. Here is an example with separator and submenu from the official GWT-API page.

Haletky answered 13/3, 2012 at 9:56 Comment(1)
where is it? This link doesn't provide an answer.Kujawa
K
0

Well, i think i found a way to implement this. (This is a solution if you want to declare the separator inside the *.ui.xml file. )

HocusView.java

...
    @UiField MenuBar  menuBar;
    @UiField MenuItem item1;
    @UiField MenuItem item2; 
    @UiField MenuItem item3; 
    @UiField MenuItem item4;   
...

    private static HocusViewUiBinder uiBinder = GWT.create(HocusViewUiBinder.class);

    @UiTemplate("Hocus.ui.xml")
    interface HocusViewUiBinder extends UiBinder<Widget, HocusView>{}

    public HocusView() 
    {
        initWidget(uiBinder.createAndBindUi(this));   
         // Attach commands to menu items
        menuItem1.setScheduledCommand(cmd_menuItem1);
        menuItem2.setScheduledCommand(cmd_menuItem2);
        menuItem3.setScheduledCommand(cmd_menuItem3);
        menuItem4.setScheduledCommand(cmd_menuItem4); 

    }


    Command cmd_menuItem1= new Command(){ 
    @Override
    public void execute() { 
        Window.alert("  Gifts  ");
        }
    };
    Command cmd_menuItem2 = new Command(){ 
        @Override
        public void execute() { 
            Window.alert("  Gifts  ");
        }
    };
    Command cmd_menuItem3 = new Command(){ 
        @Override
        public void execute() { 
            Window.alert("  Gifts  ");
        }
    };  
    Command cmd_menuItem4 = new Command(){ 
        @Override
        public void execute() { 
            Window.alert("  Gifts  ");
        }
    };



    });

HocusView.ui.xml

  <gwt:MenuBar ui:field="menuBar" >  
    <gwt:MenuItem ui:field="menuItem1">Search</gwt:MenuItem> 
     <gwt:MenuItemSeparator></gwt:MenuItemSeparator>
    <gwt:MenuItem ui:field="menuItem2">Ingestion</gwt:MenuItem> 
     <gwt:MenuItemSeparator></gwt:MenuItemSeparator>
    <gwt:MenuItem ui:field="menuItem3">Analysis</gwt:MenuItem> 
     <gwt:MenuItemSeparator></gwt:MenuItemSeparator>
    <gwt:MenuItem ui:field="menuItem4">About</gwt:MenuItem> 
  </gwt:MenuBar>  

Its as simple as that.This will add a separator between the menu items.

Cheers!

Kujawa answered 21/2, 2014 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.