Java 侦听器的代码执行顺序
我已将问题缩小到以下简单的代码片段:Java 侦听器的代码执行顺序,java,gwt,listener,vaadin,onclicklistener,Java,Gwt,Listener,Vaadin,Onclicklistener,我已将问题缩小到以下简单的代码片段: this.addClickListener(new ClickListener(){ @Override public void buttonClick(ClickEvent event) { Label spinner = new Label(); spinner.addStyleName("spinner"); ((HorizontalL
this.addClickListener(new ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
Label spinner = new Label();
spinner.addStyleName("spinner");
((HorizontalLayout) event.getButton().getParent()).replaceComponent(event.getButton(), spinner);
}
});
它所做的是创建一个加载指示器,并相应地用它替换单击的按钮:
getSaveListener().saveClick()来执行另一个侦听器代码>。总体而言,代码如下所示:
this.addClickListener(new ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
Label spinner = new Label();
spinner.addStyleName("spinner");
((HorizontalLayout) event.getButton().getParent()).replaceComponent(event.getButton(), spinner);
getSaveListener().saveClick();
}
});
public void replaceComponent(Component oldComponent, Component newComponent) {
// Gets the locations
int oldLocation = -1;
int newLocation = -1;
int location = 0;
for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
final Component component = i.next();
if (component == oldComponent) {
oldLocation = location;
}
if (component == newComponent) {
newLocation = location;
}
location++;
}
if (oldLocation == -1) {
addComponent(newComponent);
} else if (newLocation == -1) {
Alignment alignment = getComponentAlignment(oldComponent);
float expandRatio = getExpandRatio(oldComponent);
removeComponent(oldComponent);
addComponent(newComponent, oldLocation);
applyLayoutSettings(newComponent, alignment, expandRatio);
} else {
// Both old and new are in the layout
if (oldLocation > newLocation) {
components.remove(oldComponent);
components.add(newLocation, oldComponent);
components.remove(newComponent);
components.add(oldLocation, newComponent);
} else {
components.remove(newComponent);
components.add(oldLocation, newComponent);
components.remove(oldComponent);
components.add(newLocation, oldComponent);
}
markAsDirty();
}
}
“SaveListener”的设置如下:
bu.addSaveClickListener(new SaveClickListener() {
@Override
public void saveClick() {
System.out.println("Yes1");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Yes2");
}
});
所需的行为是按钮变为微调器,写入“Yes1”,等待4秒,最后写入“Yes2”
单击=)
“是的1”
“等待”
“是的”
问题是它在微调器之前先执行“saveClick”操作:
单击=)
“是的1”
“等待”
“是的”
为什么在“ClickListener”(.buttonClick()
)之前执行“SaveListener”(.saveClick()
)?我怎样才能纠正这个问题
附加测试:
结果分为:
单击=)
“纺纱工!”
“是吗?”
“是的1”
“等待”
“是的”
更换部件
.replaceComponent()
如下所示:
this.addClickListener(new ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
Label spinner = new Label();
spinner.addStyleName("spinner");
((HorizontalLayout) event.getButton().getParent()).replaceComponent(event.getButton(), spinner);
getSaveListener().saveClick();
}
});
public void replaceComponent(Component oldComponent, Component newComponent) {
// Gets the locations
int oldLocation = -1;
int newLocation = -1;
int location = 0;
for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
final Component component = i.next();
if (component == oldComponent) {
oldLocation = location;
}
if (component == newComponent) {
newLocation = location;
}
location++;
}
if (oldLocation == -1) {
addComponent(newComponent);
} else if (newLocation == -1) {
Alignment alignment = getComponentAlignment(oldComponent);
float expandRatio = getExpandRatio(oldComponent);
removeComponent(oldComponent);
addComponent(newComponent, oldLocation);
applyLayoutSettings(newComponent, alignment, expandRatio);
} else {
// Both old and new are in the layout
if (oldLocation > newLocation) {
components.remove(oldComponent);
components.add(newLocation, oldComponent);
components.remove(newComponent);
components.add(oldLocation, newComponent);
} else {
components.remove(newComponent);
components.add(oldLocation, newComponent);
components.remove(oldComponent);
components.add(newLocation, oldComponent);
}
markAsDirty();
}
}
public void replaceComponent(组件旧组件、组件新组件){
//获取位置
int oldLocation=-1;
int newLocation=-1;
int位置=0;
for(final Iterator i=components.Iterator();i.hasNext();){
最终组件=i.下一个();
如果(组件==旧组件){
oldLocation=位置;
}
如果(组件==新组件){
新地点=地点;
}
位置++;
}
如果(oldLocation==-1){
添加组件(新组件);
}else if(newLocation==-1){
对齐对齐=getComponentAlignment(旧组件);
浮动expandRatio=getExpandRatio(oldComponent);
移除组件(旧组件);
添加组件(新组件、旧位置);
applyLayoutSettings(新组件、对齐、扩展比率);
}否则{
//布局中既有旧的也有新的
如果(旧位置>新位置){
组件。移除(旧组件);
组件。添加(新位置、旧组件);
组件。移除(新组件);
组件。添加(旧位置、新组件);
}否则{
组件。移除(新组件);
组件。添加(旧位置、新组件);
组件。移除(旧组件);
组件。添加(新位置、旧组件);
}
markAsDirty();
}
}
从:
替换组件
- 公共void替换组件(组件oldComponent,
组件(新组件)
在不改变位置的情况下,将容器中的零部件替换为另一个零部件
此方法将零部件替换为另一个零部件,以使新零部件取代旧零部件的位置。如果
旧组件不在容器中,新组件将添加到
集装箱。如果两个组件都已在容器中,
他们的位置互换了。组件附加和分离事件应
注意添加和删除
- 指定人:
接口组件容器中的replaceComponent
参数:
- oldComponent:将被替换的旧组件
- 新组件:要更换的新组件
正如cfrick指出的,侦听器执行完成后,客户端UI将被更新,这是正常的Vaadin行为。在您的示例中,侦听器执行长时间运行的操作(睡眠)。完成后,将更新UI,以便显示最后一个状态
Vaadin文件涵盖了以下主题:
这里有一个很好的例子。其思想是在单独的线程中运行该操作,并通过轮询或Vaadin推送更新UI
备注:由于这个问题已经由cfrick以评论的形式回答,我将以社区维基的形式提供。保存按钮看起来很酷。。。。你从哪里得到的?@tharindu_DG几乎就是VAADIN valo facebook的“友好”按钮,带有一个令人敬畏的图标。另外,spinner是原始的VAADIN valo facebook spinner:什么是HorizontalLayout?你知道关于replaceComponent函数的详细信息吗?在我看来,你似乎忽视了vaadin在那里的工作方式。单击按钮将被发送到服务器。然后,服务器在所有单击处理程序中执行您要求的所有操作,但它只是在完成所有操作后返回客户端稍后呈现的绝对最后状态。如果希望具有这种异步行为,您可能希望在计算完成时启用轮询(客户机每隔n毫秒轮询服务器一次以查看状态更改),或者您可能希望调查vaadin-push@cfrick同样,你的评论是正确的答案。你能把它寄出去吗?很明显,一旦Vaadin处理完请求,UI就会在浏览器中重新绘制。他需要启用推送或轮询。