@UiHandler方法中的GWT Null对象

@UiHandler方法中的GWT Null对象,gwt,mvp,uibinder,Gwt,Mvp,Uibinder,我将GWT2.4与MVP一起使用。 这是我的视图对象: public class LoginWidget extends Composite implements LoginWidgetView { interface Binder extends UiBinder<Widget, LoginWidget> { } private static final Binder BINDER = GWT.create(Binder.class); @UiField Anchor set

我将GWT2.4与MVP一起使用。 这是我的视图对象:

public class LoginWidget extends Composite implements LoginWidgetView {

interface Binder extends UiBinder<Widget, LoginWidget> {
}

private static final Binder BINDER = GWT.create(Binder.class);

@UiField Anchor settings;

public LoginWidget() {
    initWidget(BINDER.createAndBindUi(this));
}

@UiHandler("settings")
void handleSettingsClick(ClickEvent e) {
    presenter.showSettings();
}

private Presenter presenter;

@Override
public void setPresenter(Presenter presenter) {
    this.presenter = presenter;
}
LoginWidgetPresenter当然实现视图的Presenter接口。但是,当我单击设置锚点时,presenter引用仍然为null,因此presenter.showSettings()抛出一个NullPointerException。 我假设在调用LoginWidget的构造函数并通过

initWidget(BINDER.createAndBindUi(this));
my@UiHandler(“设置”)方法中的单击处理代码忽略对所用对象(如my presenter对象)的更改?? 调用initWidget()方法后,是否有方法设置presenter对象? 或者是否可以自定义@UiHandler/initWidget()-行为,我可以在之后设置演示者


谢谢,Manuel,我用另一种方式实现MVP,UIBinder为我的客户服务。如果在LoginWidget构造函数中传递LoginWidgetPresenter,它可能会工作

public LoginWidget(Presenter presenter) {
    this.presenter = presenter;
    initWidget(BINDER.createAndBindUi(this));
}
...
getLoginWidget(new LoginWidgetPresenter(placeController));

有很多事情可能出了差错。最简单的方法是尝试调试代码,方法是放置断点
handleSettings
和“setPresenter”方法。 我的猜测是发生了以下情况之一:

  • setPresenter
    从未实际调用过

  • getLoginWidget()
    始终返回小部件的新实例,很可能您正在登录小部件的一个实例上设置presenter,但显示的是完全不同的小部件实例

  • 您的代码中有
    getLoginWidget().setPresenter(null)

或者其他任何猜测。调试和查看presenter实例的传递位置和方式要容易得多。无论如何,
UiBinder
不会删除您的字段值(除非被其他人修改以取笑您)

谢谢您的回答。但是在您的方法中,您必须了解在创建小部件时将其传递到构造函数中的placeController(或者可选的请求工厂)。如果我想在另一个视图组件中创建小部件,我必须使请求工厂和放置控制器在那里可用,我想这不是MVP推荐的吗?或者我错过了什么…你调试过了吗?在
setPresenter
handleSettingsClick
中都有断点,并确保在相同的
LoginWidget
实例上以正确的顺序调用断点?谢谢您的回答。我已经调试过了<代码>setPresenter()通过真实的presenter实例调用。但是在
handleSettingsClick()
中,组件的
presenter
类变量为空。因此,我认为它必须是一个不同的
LoginWidget
实例,我在其上设置了
presenter
。但这正是我要寻找的。我只是想确保它正常工作,我已经实现了。谢谢你的回答。正如我在上面的评论中提到的,我已经调试过了<在通过延迟绑定创建
LoginWidget
后,调用code>setPresenter。
getLoginWidget
只是父UI组件上的一个简单的get方法(
LoginWidget
只是父组件上的一个
@UiField
),因此实际上不能再有
LoginWidget
的实例了。父组件实现为单例。但是在上面的评论中,很高兴知道
@UiHandler
应该支持在调用
initWidget(…)
之后设置presenter对象。@TonySkulk好吧,我只能说一件事。从您提供的代码中,我看不出有任何问题。标准的普通UiBinder无法对私有字段执行任何操作。顺便问一下,你是怎么调试的?您是否将断点同时设置为
setPresenter
handleSettingsClick
并验证了它们都是以正确的顺序调用的,并且“setPresenter是以正确的值调用的?”是的,我正在使用Eclipse/STS并在这两种方法中设置断点<使用正确的
Presenter
实例调用code>setPresenter。在
handleSettingsClick
中,private
presenter
字段为空。@TonySkulk您是否可以创建一个小的工作示例项目来演示这个问题?因为它肯定是由某些东西引起的,在你的问题中它没有被证明。唯一的情况(假设您没有忽略某些内容)是,实际上有一些JSNI代码可以直接删除presenter字段。我在我的
EntryPoint
类中找到了一个调用
setPresenter
的解决方法。虽然将演示者注入组件可能应该在相应活动的构造函数中完成,但我无法理解为什么它在那里不起作用。即使我添加了一个只调用
LoginWidget
setPresenter
方法的按钮,presenter仍将为空。
public LoginWidget(Presenter presenter) {
    this.presenter = presenter;
    initWidget(BINDER.createAndBindUi(this));
}
...
getLoginWidget(new LoginWidgetPresenter(placeController));