侦听器的代码执行顺序

时间:2015-12-17 13:51:01

标签: java gwt listener vaadin onclicklistener

我已将问题缩小到这个简单的代码段:

    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);

        }

    });

它的作用是创建一个加载指示器并相应地替换单击的按钮:

  1. Button
  2. 点击 =)
  3. Spinning
  4. 好的,让我们(再次,当然简化)通过添加行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();
    
            }
    
        });
    

    " 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. Button
    2. 点击 =)
    3. Spinning
    4. "支持1"
    5. "等待"
    6. " YES2"
    7. 问题在于它会执行" saveClick"在旋转器之前的东西

      1. Button
      2. 点击 =)
      3. "支持1"
      4. "等待"
      5. " YES2"
      6. Spinning
      7. 为什么" SaveListener" (.saveClick())在" ClickListener"之前执行。 (.buttonClick())?我怎么能纠正这个?

        附加测试:

                @Override
                public void buttonClick(ClickEvent event) {
        
                    Label spinner = new Label();
                    spinner.addStyleName("spinner");
        
                    System.out.println("SPINNER!");
                    ((HorizontalLayout) event.getButton().getParent()).replaceComponent(event.getButton(), spinner);
                    System.out.println("Yes?");
        
                    getSaveListener().saveClick();
        
                }
        

        结果:

        1. Button
        2. 点击 =)
        3. &#34; SPINNER&#34; <!/ LI>
        4. &#34;?是&#34;
        5. &#34;支持1&#34;
        6. &#34;等待&#34;
        7. &#34; YES2&#34;
        8. Spinning
        9. 替换组件

          .replaceComponent()看起来像这样:

          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();
              }
          }
          

          来自API

            

          replaceComponent

               
              
          • public void replaceComponent(Component oldComponent,                            组件newComponent)
          •   
               

          用另一个组件替换容器中的组件而不改变位置。

               

          此方法用另一个方法替换组件,使得新组件超过旧组件的位置。如果   旧组件不在容器中,新组件被添加到   容器。如果两个组件已经在容器中,   他们的职位被交换了。组件附加和分离事件应该   与添加和删除一样要小心。

               
              
          • 指定人:

                 

            在ComponentContainer接口中的replaceComponent

          •   
               

          参数:

               
              
          • oldComponent:将被替换的旧组件。
          •   
          • newComponent:要替换的新组件。
          •   

1 个答案:

答案 0 :(得分:1)

正如cfrick指出的那样,一旦监听器执行完成,客户端UI将被更新是正常的Vaadin行为。在您的示例中,侦听器执行长时间运行的操作(休眠)。完成后,将更新UI,以便显示最后一个状态。

Vaadin文档涵盖了这个主题:https://vaadin.com/docs/-/part/framework/components/components-progressbar.html

有一个很好的例子。我们的想法是在一个单独的线程中运行该操作,并通过轮询或Vaadin推送来更新UI。

P.S。:由于这个问题已经被cfrick作为评论回答,我将把它作为社区维基提供。