【问题标题】:UIBinder with Widget带有小部件的 UIBinder
【发布时间】:2013-05-14 08:26:28
【问题描述】:

我正在尝试使用 UIBinder 将小部件添加到面板,但复合组件根本无法加载,这是我的 xml:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
         xmlns:g='urn:import:com.google.gwt.user.client.ui'
         xmlns:my='urn:import:com.abc.client.test.ui'>
 <g:HTMLPanel ui:field="mainLayoutPanel">

  <g:SimplePanel ui:field="menuPanel" >
    <my:MainMenuViewImpl ui:field="mainMenu"/>
  </g:SimplePanel>

  <!-- the widget causing the issue -->
  <my:FinancialsNav ui:field="nav"/>

  <g:SimplePanel ui:field="mainPanel" />

 </g:HTMLPanel>
</ui:UiBinder>

对应的java类:

public class AppLayoutImpl extends Composite implements AppLayout{

@UiField
HTMLPanel mainLayoutPanel;

interface AppLayoutUiBinder extends UiBinder<Widget,AppLayoutImpl>{}

private static AppLayoutUiBinder binder=GWT.create(AppLayoutUiBinder.class);

@UiField
SimplePanel menuPanel;// nav at the top

@UiField(provided=true)
FinancialsNav nav;// nav on the side

@UiField
SimplePanel mainPanel;// center

@UiField(provided=true)
MainMenuViewImpl mainMenu;

public AppLayoutImpl(ClientFactory clientFactory){
    mainMenu=clientFactory.getMainMenuView();
    nav=clientFactory.getNav();
    initWidget(binder.createAndBindUi(this));
}



@Override
public Widget asWidget(){
    return this;
}
}

以及导致问题的小部件:

public class FinancialsNav extends Composite implements ClickHandler{

private VerticalPanel nav=new VerticalPanel();
// Operations
private DisclosurePanel operationsWrapper=new DisclosurePanel(Proto2.constants.financials_navigation_operations());
private NavButton product=new NavButton(Proto2.constants.financials_navigation_products(),
        SharedUtilities.PRODUCT_TOKEN);


private NavButton generalOptions=new NavButton(Proto2.constants.financials_navigation_generalOptions(),"");

private ArrayList<NavButton[]> buttons;
private NavButton[] operationsButtons={product,vc,fc,emp,others};
//...
private NavButton[] optionsButtons={generalOptions};

private final EventBus bus;

public FinancialsNav(EventBus bus){
    this.bus=bus;
    buildNav();
    initWidget(nav);
}

private void buildNav(){
    buttons=new ArrayList<NavButton[]>();
    buttons.add(operationsButtons);
    //...
    buttons.add(optionsButtons);

    int n=buttons.size();
    int nn;
    for(int i=0;i<n;i++){
        nn=buttons.get(i).length;
        for(int j=0;j<nn;j++){
            (buttons.get(i)[j]).addClickHandler(this);
            (buttons.get(i)[j]).setStylePrimaryName(NAV_BUTTON_STYLE);
            if(i==0){
                operationsWrapper.add(buttons.get(i)[j]);
            //...
            }else if(i==4){
                optionsWrapper.add(buttons.get(i)[j]);
            }
        }
    }

    nav.add(operationsWrapper);
    // ...
    nav.add(optionsWrapper);

}

FinancialsNav 小部件在不与 UIBinder 一起使用时工作正常,而 AppLayout 的其余部分在 FinancialsNav 不存在时按预期工作。

我花了几个小时查看各种教程和示例,但根本找不到代码有什么问题。我还尝试了各种解决方法,例如在 UIBinder 中声明一个面板而不是 FinancialsNav 并将导航添加到面板中。

而且所有东西都在同一个包中,所以这不应该是导入问题。

任何帮助将不胜感激......

这里是客户端工厂

public class ClientFactoryImpl implements ClientFactory{
private static final EventBus eventBus=new SimpleEventBus();
private static final PlaceController placeController=new PlaceController(eventBus);

private static final CreatePlanServiceAsync createPlanService=GWT.create(CreatePlanService.class);

private static final FinancialsNav navView=new FinancialsNav(eventBus);
private static final MainMenuViewImpl mainMenuView=new MainMenuViewImpl();

@Override
public EventBus getEventBus(){
    return eventBus;
}

@Override
public PlaceController getPlaceController(){
    return placeController;
}

@Override
public FinancialsNav getNav(){
    return navView;
}

@Override
public MainMenuViewImpl getMainMenuView(){
    return mainMenuView;
}

@Override
public CreatePlanServiceAsync getCreatePlanService(){
    return createPlanService;
} 
}

【问题讨论】:

    标签: gwt widget uibinder


    【解决方案1】:

    FinancialsNav 小部件具有带参数的构造函数。所以不要创建参数构造函数。

    条目&lt;my:FinancialsNav ui:field="nav"/&gt; 等于new FinancialsNav()

    在大多数情况下,这意味着它们必须是默认可实例化的;也就是说,它们必须提供一个零参数的构造函数。你必须传递参数

     /** Used by MyUiBinder to instantiate FinancialsNav */
      @UiFactory FinancialsNav makeFinancialsNav() { // method name is insignificant. do start with make
        return new FinancialsNav(eventBus);
      }
    

    参考Using a widget that requires constructor args

    你能显示clientFactory的代码吗!!

    【讨论】:

    • 我试过没有效果。我认为 UIField(provided=true) 负责告诉 UIBinder 该字段接受参数(如下所示:developers.google.com/web-toolkit/doc/2.4/DevGuideUiBinder#Lazy
    • 不,他将 nav 设置为“provided = true”,因此他的 FinancialsNav 使用他在构造函数中放入的行进行初始化:clientFactory.getNav()
    • 您可以尝试将@Inject 放在您的 FinancialsNav 构造函数上吗?我也希望能看到 clientFactory 的代码。
    • 我没有使用 GIN/GUICE,因此 @Inject 会触发错误。添加客户端工厂代码
    • 否,使用 @UiField(provided = true) 将提供新的实例化对象。它不负责讲述论点。正如@adenoyelle 所说,我还想查看clientFactory 代码。另请参阅回答如何在构造函数中传递参数!
    【解决方案2】:

    好的,我发现了错误,实际上与 UIBinder 没有直接关系。

    在实现 UIBinder 的同时,我试图减少应用中面板使用的表格数量。

    当我注意到披露面板基于表格时,我删除了我在 FinancialsNav 中的一个中间垂直面板。 因此有 DisclosurePanel --> Buttons 而不是 DisclosurePanel --> VerticalPanel --> Buttons。这导致整个区块不显示。

    @adenoyelle 和@bumika:感谢您的帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多