开发者

GWT: Menus in UiBinder

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 f开发者_C百科or 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!


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
...
}  


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


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.


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.


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.


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!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜