Using Polling

To set up polling for your UI, you only need to set a poll interval using UI.setPollInterval(timeout). By doing this the browser will poll the server each “timeout” ms and retrieve any possibly pending changes. You can test this in practice by creating a small application which initially creates a small “please wait” UI and then loads the actual UI in a background thread.

Java

  1. public class PollingUI extends UI {
  2. @WebServlet(value = "/*")
  3. @VaadinServletConfiguration(productionMode = false, ui = Polling7UI.class)
  4. public static class Servlet extends VaadinServlet {
  5. }
  6. @Override
  7. protected void init(VaadinRequest request) {
  8. setContent(new Label("Loading data, please wait..."));
  9. setPollInterval(1000);
  10. new Thread(new Loader()).start();
  11. }
  12. class Loader implements Runnable {
  13. @Override
  14. public void run() {
  15. // Simulate a heavy database operation
  16. try {
  17. Thread.sleep(4500);
  18. } catch (InterruptedException e) {
  19. }
  20. // Wrap UI updates in access to properly deal with locking
  21. access(new Runnable() {
  22. @Override
  23. public void run() {
  24. setContent(new Label("This is the real content"));
  25. // Stop polling once the update is done
  26. setPollInterval(-1);
  27. }
  28. });
  29. }
  30. }
  31. }

For more information regarding locking the session, see [Using server initiated events]

Polling for multiple components

If you have the situation that several components need polling at some point you should use some kind of Manager to handle the polling, for it can only be set UI-wise (which makes perfectly sense)

A simple UIPollingManager which always uses the lowest registered intervalTime could look like this:

Java

  1. import java.util.Collection;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.WeakHashMap;
  5. import com.vaadin.ui.UI;
  6. public class UIPollingManager
  7. {
  8. private Map<UI, Map<Object, Integer>> pollRequests;
  9. public UIPollingManager()
  10. {
  11. pollRequests = new WeakHashMap<>(); // Let's use weak references in case someone forgets to unregister properly
  12. }
  13. /**
  14. * Registers a poll request for the given UI. Sets the pollInterval of this UI to the lowest registered interval.
  15. * @param ui
  16. * @param requestor
  17. * @param pollIntervalInMillis poll interval in milliseconds
  18. */
  19. public void registerPollRequest(UI ui, Object requestor, int pollIntervalInMillis)
  20. {
  21. Map<Object, Integer> uiRequests = pollRequests.get(ui);
  22. if (uiRequests == null)
  23. {
  24. uiRequests = new HashMap<>();
  25. pollRequests.put(ui, uiRequests);
  26. }
  27. uiRequests.put(requestor, pollIntervalInMillis);
  28. setPollInterval(ui);
  29. }
  30. /**
  31. * Removes a poll request for the given UI (if existent). Sets the pollInterval of this UI to the lowest registered interval
  32. * remaining or -1 if no more requests exist for the UI
  33. * @param ui
  34. * @param requestor
  35. */
  36. public void unregisterPollRequest(UI ui, Object requestor)
  37. {
  38. Map<Object, Integer> uiRequests = pollRequests.get(ui);
  39. if (uiRequests != null)
  40. {
  41. uiRequests.remove(requestor);
  42. // Remove the UI from our map if no requests exist anymore
  43. if (uiRequests.size() <= 0) pollRequests.remove(ui);
  44. }
  45. setPollInterval(ui);
  46. }
  47. /**
  48. * Removes all poll requests of the given UI and sets the pollInterval to -1
  49. * @param ui
  50. */
  51. public void unregisterAllPollRequests(UI ui)
  52. {
  53. pollRequests.remove(ui);
  54. ui.setPollInterval(-1);
  55. }
  56. /**
  57. * Sets the pollInterval of the given UI to the lowest registered interval time of this UI
  58. * @param ui
  59. */
  60. private void setPollInterval(UI ui)
  61. {
  62. Map<Object, Integer> uiRequests = pollRequests.get(ui);
  63. if (uiRequests != null)
  64. {
  65. ui.setPollInterval(getLowestNumber(uiRequests.values()));
  66. }
  67. }
  68. /**
  69. * Returns the lowest number of a given Integer-Collection. Returns -1 if no valid Integer is included in the collection.
  70. * @param intervalArray
  71. * @return
  72. */
  73. private Integer getLowestNumber(Collection<Integer> intervalArray)
  74. {
  75. Integer lowestNum = null;
  76. for (Integer i : intervalArray)
  77. {
  78. if (i != null && ( lowestNum == null || i < lowestNum )) lowestNum = i;
  79. }
  80. if (lowestNum == null) return -1;
  81. else
  82. return lowestNum;
  83. }
  84. }

The changed example could then look like this:

Java

  1. public class Polling7UI extends UI {
  2. private UIPollingManager pollingManager; // Instantiate this via Spring or get it via Singleton or whatever
  3. @WebServlet(value = "/*")
  4. @VaadinServletConfiguration(productionMode = false, ui = Polling7UI.class)
  5. public static class Servlet extends VaadinServlet {
  6. }
  7. @Override
  8. protected void init(VaadinRequest request) {
  9. setContent(new Label("Loading data, please wait..."));
  10. Loader loader = new Loader();
  11. pollingManager.registerPollRequest(this, loader, 1000);
  12. new Thread(loader).start();
  13. }
  14. class Loader implements Runnable {
  15. private UI ui;
  16. private UIPollingManager pollingManager;
  17. public Loader( UI ui, UIPollingManager pollingManager )
  18. {
  19. this.ui = ui;
  20. this.pollingManager = pollingManager;
  21. }
  22. @Override
  23. public void run() {
  24. // Simulate a heavy database operation
  25. try {
  26. Thread.sleep(4500);
  27. } catch (InterruptedException e) {
  28. }
  29. final Loader loader = this;
  30. // Wrap UI updates in access to properly deal with locking
  31. access(new Runnable() {
  32. @Override
  33. public void run() {
  34. setContent(new Label("This is the real content"));
  35. // Stop polling once the update is done
  36. pollingManager.unregisterPollRequest(ui, loader);
  37. }
  38. });
  39. }
  40. }
  41. }