2016-09-16 66 views
0

我想换一个Vaadin UI中的数据。该更改由一个休息电话调用。在那里,我不知何故需要引用UI类来调用它的方法,例如changeValue(字符串值)。Vaadin:UI的获得参考更改数据

我使用vaadin弹簧引导起动1.0.0

这个现象的原因可能吗?

编辑:现在还有一个问题: 我尝试这样做,服务器推送,通过@Eric提到,一个视图中,这样的观点将得到一个广播消息更新。但是,这不起作用(没有例外,没有什么可调试的,只是视图中没有更新)。这是我在我看来这样做:

@UIScope 
@SpringView(name = LoadWebsiteView.VIEW_NAME) 
@Push 
public class LoadWebsiteView extends VerticalLayout implements View, Broadcaster.BroadcastListener { 
... 

@Autowired 
public LoadWebsiteView(ScraperMainUI scraperMainUi) { 
    this.scraperMainUi = scraperMainUi; 
    Broadcaster.register(this); 
    initControlPane(); 
} 

@Override 
public void receiveBroadcast(String message) { 
    scraperMainUi.access(new Runnable() { 
     @Override 
     public void run() { 
      urlTxtField.setValue(message); 
     } 
    }); 
} 

,这里是简单的东西,我在我的restcontroller做:

Broadcaster.broadcast(text); 
+1

当您打开10个UI实例时,您希望访问哪些实例?大概你会更好地使用tome排队/广播系统 –

+0

你的权利,但我认为它没问题,因为应用程序将是软件的单个用户配置部分。但是,是否有可能通过例如区分UI实例? ID? – eSKape

回答

2

你正在寻找什么是Vaadin的Push功能和方式发送消息发送到已注册的“客户端”列表(在这种情况下,需要知道有关更改的Vaadin UI)。

你可以阅读有关Vaadin推动此处:Enabling Server Push,也是文章Advanced Push

中的Vaadin推送功能可以让您的服务器来强制更新客户端,而不是等待浏览器再次请求。

消息组件简单地作为一种方法来告诉用户界面订阅,有他们需要采取行动的最新情况。

此说,我有一个项目,做大约相同的多个用户actioning项目,有一些还可以效应改变了用户需要了解春季计划任务。

注意,下面的例子是基于Enabling Server Push文章中可用的例子。

Broadcaster.java - 充当注册实例以接收广播并提供发送广播设施的机制。在下面的例子中,我有一个表示消息(BroadcastMessage)的类,但是您可以简化它。

public class Broadcaster implements Serializable { 

    private static final long serialVersionUID = 3540459607283346649L; 

    static ExecutorService executorService = Executors.newSingleThreadExecutor(); 

    private static LinkedList<BroadcastListener> listeners = new LinkedList<BroadcastListener>(); 

    public interface BroadcastListener { 
     void receiveBroadcast(BroadcastMessage message); 
    } 

    public static synchronized void register(BroadcastListener listener) { 
     listeners.add(listener); 
    } 

    public static synchronized void unregister(BroadcastListener listener) { 
     listeners.remove(listener); 
    } 

    public static synchronized void broadcast(final BroadcastMessage message) { 
     for (final BroadcastListener listener: listeners) 
      executorService.execute(new Runnable() { 
       @Override 
       public void run() { 
        listener.receiveBroadcast(message); 
       } 
      }); 
    } 
} 

这是我为我的BroadcastMessage定义的类。这个想法是有一种方法来表示我有什么样的信息,也有一些有效载荷在地图

public class BroadcastMessage implements Serializable { 

    private static final long serialVersionUID = 5637577096751222106L; 

    public BroadcastMessageType messageType; 
    public Map<String, String> params; 

    public BroadcastMessage() { 
    } 

    public BroadcastMessage(BroadcastMessageType messageType) { 
     this.messageType = messageType; 
     this.params = new HashMap<String, String>(); 
    } 

    public BroadcastMessage(BroadcastMessageType messageType, Map<String, String> params) { 
     this.messageType = messageType; 
     this.params = params; 
    } 

    public BroadcastMessageType getMessageType() { 
     return messageType; 
    } 
    public void setMessageType(BroadcastMessageType messageType) { 
     this.messageType = messageType; 
    } 
    public Map<String, String> getParams() { 
     return params; 
    } 
    public void setParams(Map<String, String> params) { 
     this.params = params; 
    } 

} 

这种形式是想监听广播为例Vaadin UI。 请注意@Push注释。没有这个,客户端只会在浏览器决定时刷新。 @Push使得即时**

@SpringComponent 
@UIScope 
@Push 
@SpringView(name=TaskListComponent.NAME) 
public class TaskListComponent extends MyCustomComponent implements Broadcaster.BroadcastListener, View { 

    /** PRUNED DOWN, TO DEMONSTRATE THE KEY CODE **/ 

    // Register this window when we enter it 
    @Override 
    public void enter(ViewChangeEvent event) { 
     Broadcaster.register(this); 

    } 

    // Must also unregister when the UI expires  
    @Override 
    public void detach() { 
     Broadcaster.unregister(this); 
     super.detach(); 
    } 

    // Receive a broadcast 
    @Override 
    public void receiveBroadcast(BroadcastMessage message) { 

     getUI().access(new Runnable() { 
      @Override 
      public void run() { 
       // DO WHATEVER YOU NEED TO DO HERE. 
       // I CALLED INITIALIZE BUT IT COULD BE 
       // JUST YOU FIELD UPDATE 
       if (message.getMessageType().equals(BroadcastMessageType.REFRESH_TASK_LIST)) 
        initialize(); 
      } 
     }); 

    } 

} 

要从休息界面发送消息:

Broadcaster.broadcast( 
    new BroadcastMessage( 
     BroadcastMessageType.AUTO_REFRESH_LIST 
    ) 
); 

希望这有助于! :)

+0

伟大的答案埃里克!完美的解决方案。我尝试过的唯一的其他解决方案是在数据库或文件中的中间存储,以便其余接口使用CustomPollListener将数据保存在那里,并且UI每秒轮询一次(setPollInterval(1000);)。但是按照你描述的方式推动它会更好! – eSKape