无法在GWT应用程序中设置文本框的焦点
这不应该给我带来这么多痛苦,但确实如此。这是一个非常奇怪的问题。在GWT应用程序中,我有两个.java文件,login.java和application.java。 在login.java中,我创建了一个用户登录页面,如果验证了用户名和密码,那么用户将登录到应用程序,application.java将从此处开始 目前正在申请中。java的onModuleLoad()这是我如何开始登录页面的无法在GWT应用程序中设置文本框的焦点,gwt,textbox,Gwt,Textbox,这不应该给我带来这么多痛苦,但确实如此。这是一个非常奇怪的问题。在GWT应用程序中,我有两个.java文件,login.java和application.java。 在login.java中,我创建了一个用户登录页面,如果验证了用户名和密码,那么用户将登录到应用程序,application.java将从此处开始 目前正在申请中。java的onModuleLoad()这是我如何开始登录页面的 public void onModuleLoad() { Login login = new Logi
public void onModuleLoad() {
Login login = new Login();
login.textBoxUsername.setFocus(true);
RootLayoutPanel.get().add(login);}
这非常有效,除了页面加载时无法将焦点设置在用户名文本框上的小问题。我想得到的任何东西我都试过了。但是焦点并没有放在文本框上。如果有人能提出解决方案,请提出。非常感谢你的帮助
解决方案:(以防对面临相同问题的人有所帮助)
尝试使用:
更新:答案更新为使用
Scheduler.get().schedulederferred()
而不是,后者已被弃用。为什么要使用DefferedCommand
,我认为最好使用someWidget.getElement().focus()
这是一种本机Javascript。我在任何地方都在使用它,我没有发现任何问题。如果您的小部件扩展了Composite,您可以:
@Override
protected void onAttach() {
super.onAttach();
textBoxUsername.setFocus(true);
}
对于GWT来说,在内部状态下存储“WantFocus”并在连接小部件后调用focus是非常容易的。我们仍然在等待多年后的功能,但 尽管如此,即使在调用attach处理程序之后,setFocus也不总是有效的 因此,与此同时,我们的GwtUtil库使用了以下代码。它是其他几种解决方案的组合,并被包装在一个实用函数中:
static public void setFocus(final FocusWidget focusWidget) {
if (focusWidget.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
focusWidget.setFocus(true);
}
});
} else {
focusWidget.addAttachHandler(new AttachEvent.Handler() {
@Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
focusWidget.setFocus(true);
}
});
}
}
});
}
}
这样称呼它:
setFocus(myTextBox);
使用效用函数是有意义的;如果GWT最终使setFocus工作,您将不必在多个位置更改源代码。在登录小部件添加到
RootLayoutPanel
之后,您可能需要调用setFocus()
——您尝试过吗?是的,当我在RootLayoutPanel.get()之后调用setFocus()时,添加(登录);登录屏幕未加载。如果在RootLayoutPanel.get()之后调用setFocus(),是否会出现脚本错误。添加(登录)?我认为浏览器需要一些时间来加载您的登录小部件。您可以在gwt计时器块内以5秒的间隔尝试setFocus调用吗?然后,我们可以准确地找出问题发生的地方。@Din如果创建登录小部件或将其添加到RootLayoutPanel需要一些时间,那么在完成之前不会发生下一个调用@sherry您是否在开发模式下运行,以便查看任何GWT错误?@Din:您是对的,浏览器确实需要时间加载登录小部件,尽管用户看不到此延迟。我无法确定登录小部件的加载何时完成。按照这个概念,我在下面使用了@Peter的建议。使用DeferredCommand工作!它等待登录小部件加载,然后调用setFocus()。虽然DeferredCommand已被弃用,但我必须找到可以替代它的方法。但至少我现在要去某个地方。。谢谢你的回复!谢谢你,彼得!你的解决方案奏效了。虽然这已被弃用,但我必须在当前版本的GWT中找到执行此操作的类。至少你已经建议了一个开始的地方,谢谢。事实上,你应该使用调度程序.schedulederferred()
它不应该是调度程序.get().schedulederferred()
?只需一个问题,所有内容都包含在onModuleLoaded
函数中,对吗?类似于jQuery的document.ready()
。那么,这难道不能解决仅在小部件加载之后设置焦点的问题吗?为什么我们需要通过这个hack单独处理这个问题?@Cupidvogel-No,onModuleLoad()
可以在DOM准备就绪之前调用,并调用body.onload()
:我也在很多地方使用过它。嗯,在这种情况下它不起作用。正如上面所解释的,为了使用someWidget.getElement().focus()
,不可能知道登录小部件加载何时完成。因此,我们需要使用DeferedCommand
或schedulederferred
来实现这一点<代码>延迟命令在浏览器事件循环返回后执行。
static public void setFocus(final FocusWidget focusWidget) {
if (focusWidget.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
focusWidget.setFocus(true);
}
});
} else {
focusWidget.addAttachHandler(new AttachEvent.Handler() {
@Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
focusWidget.setFocus(true);
}
});
}
}
});
}
}
setFocus(myTextBox);