【问题标题】:Vaadin 7 fire custom events between componentsVaadin 7 在组件之间触发自定义事件
【发布时间】:2013-08-24 05:58:39
【问题描述】:

我想创建自定义事件并在视图的某些部分触发它们,以便更新/删除/刷新视图的其他部分。

我尝试过扩展 Component.Event 和 Component.Listener 但它不起作用。我认为事件和监听器必须限制在同一个组件实例中。

这可以用 Vaadin 7 完成吗?

基本上我想解耦我的视图并提供组件之间的轻松通信。我也在使用 Spring 和 Vaadin。如果您在观察者模式之外有更好的想法,我也将不胜感激。

谢谢

【问题讨论】:

    标签: java events vaadin observer-pattern vaadin7


    【解决方案1】:

    您需要什么:
    1. 触发事件的组件
    2.自定义事件类
    3.监听接口
    4. 和一个监听器实现

    来自 1 的组件需要有一个事件监听器列表,方法是:addListener; removeListener;和dispatchEvent。 dispatchEvent-方法将遍历事件监听器列表并执行一些方法(参见 4:监听器实现)。该方法有一个事件对象作为参数(参见 2:自定义事件类)。

    1的基本代码:

    protected List<MyListener> listeners; 
    
    protected synchronized void dispatchEvent(MyEvent event) {
       if (listeners != null) {
          for (MyListener listener : listeners) {
             listener.myMethod(event);
          }
       }
    }
    
    public synchronized void addListener(MyListener listener) {
       if (listeners == null) {
          listeners = new ArrayList<MenuListener>();
       }
       listeners.add(listener);
    }
    
    public synchronized void removeListener(MyListener listener) {
       if (listeners == null) {
           listeners = new ArrayList<MyListener>();
           return;
       }
       listeners.remove(listener);
    }
    

    2的基本代码:

    public class MyEvent {
       protected String eventType;
    
       public MyEvent(String eventType) {
          this.eventType = eventType;
       }
    
       //getters and setters
    }
    

    3的基本部分:

    public interface MyListener {
        public void doSomething(MyEvent event);
    }
    

    4 的代码(监听器实现)

    public class MyImplementation implements MyListener {
    
        @Override
        public void doSomething(myEvent event) {
            //do something concretes here
        }
    }
    

    代码流的工作原理:
    在一些交互之后,调度程序类将“通知”每个事件侦听器发生了某事。

    dispatchEvent(new MyEvent("ADD_USER"));
    

    在你想接收事件的类中你需要实例化dispatcher类和listener实现类,并将listener添加到dispatcher的列表中:

    MyDispatcher disp = new MyDispatcher();
    MyImplementation myImpl = new MyImplementation();
    // Then add the event-listener to the dispatcher:
    disp.addListener(myImpl);
    

    当然,其中一些类可以是内部类,代码可以简化或扩展,但这是大体思路。这也是纯 Java,没有任何 Vaadin 依赖。

    【讨论】:

      【解决方案2】:

      您可以使用 EventRouter。但我不使用它。

      或者您可以使用 ObjectProperty。

      这个对象可以在值改变时触发事件。 例如:

      public class MyApplication extends UI{
        private ObjectProperty<MyState> myState= new ObjectProperty<MyEvent>(new MyState());
      
        public ObjectProperty<MyState> getMyState(){return myState;}
      
      }
      
      
      public class MyComponent1 extends VerticalLayout{
      
        public MyComponent1(){
      
        //create UI
        ....
      
        updateData();
      
        Property.ValueChangeListener updateListener = new Property.ValueChangeListener() {
                          @Override
                          public void valueChange(Property.ValueChangeEvent event) {
                             updateData();
                          }
                      };
        MyApplication.getCurrent().getDispatcher().addValueChangeListener(updateListener);
      
      
        }
      
      private void updateData(){
        MyState myState = MyApplication.getCurrent().getMyState().getValue();
      
        //update this component with myState
      
      }
      }
      
       public class MyComponent2 extends VerticalLayout{/*Similarly with Component1*/}
      

      【讨论】:

        【解决方案3】:

        实际上,有一些基于 Vaadin 的框架可以解耦您的视图并提供简单的基于事件的通信,如您所说。这种方法称为 MVP 模式 - Model view presenter,它提供了组件之间的 event driver 通信。当时有一些 MVP Vaadin 框架可用:

        https://github.com/peholmst/MVP4Vaadin

        https://github.com/panter/org.vaadin.mvp

        【讨论】:

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