You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ActionManager.java 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.event;
  5. import java.util.HashSet;
  6. import java.util.Map;
  7. import com.vaadin.event.Action.Container;
  8. import com.vaadin.event.Action.Handler;
  9. import com.vaadin.terminal.KeyMapper;
  10. import com.vaadin.terminal.PaintException;
  11. import com.vaadin.terminal.PaintTarget;
  12. import com.vaadin.terminal.VariableOwner;
  13. import com.vaadin.ui.Component;
  14. /**
  15. * Javadoc TODO
  16. *
  17. * Notes:
  18. * <p>
  19. * Empties the keymapper for each repaint to avoid leaks; can cause problems in
  20. * the future if the client assumes key don't change. (if lazyloading, one must
  21. * not cache results)
  22. * </p>
  23. *
  24. *
  25. */
  26. public class ActionManager implements Action.Container, Action.Handler,
  27. Action.Notifier {
  28. private static final long serialVersionUID = 1641868163608066491L;
  29. /** List of action handlers */
  30. protected HashSet<Action> ownActions = null;
  31. /** List of action handlers */
  32. protected HashSet<Handler> actionHandlers = null;
  33. /** Action mapper */
  34. protected KeyMapper<Action> actionMapper = null;
  35. protected Component viewer;
  36. private boolean clientHasActions = false;
  37. public ActionManager() {
  38. }
  39. public <T extends Component & Container & VariableOwner> ActionManager(
  40. T viewer) {
  41. this.viewer = viewer;
  42. }
  43. private void requestRepaint() {
  44. if (viewer != null) {
  45. viewer.requestRepaint();
  46. }
  47. }
  48. public <T extends Component & Container & VariableOwner> void setViewer(
  49. T viewer) {
  50. if (viewer == this.viewer) {
  51. return;
  52. }
  53. if (this.viewer != null) {
  54. ((Container) this.viewer).removeActionHandler(this);
  55. }
  56. requestRepaint(); // this goes to the old viewer
  57. if (viewer != null) {
  58. viewer.addActionHandler(this);
  59. }
  60. this.viewer = viewer;
  61. requestRepaint(); // this goes to the new viewer
  62. }
  63. @Override
  64. public <T extends Action & Action.Listener> void addAction(T action) {
  65. if (ownActions == null) {
  66. ownActions = new HashSet<Action>();
  67. }
  68. if (ownActions.add(action)) {
  69. requestRepaint();
  70. }
  71. }
  72. @Override
  73. public <T extends Action & Action.Listener> void removeAction(T action) {
  74. if (ownActions != null) {
  75. if (ownActions.remove(action)) {
  76. requestRepaint();
  77. }
  78. }
  79. }
  80. @Override
  81. public void addActionHandler(Handler actionHandler) {
  82. if (actionHandler == this) {
  83. // don't add the actionHandler to itself
  84. return;
  85. }
  86. if (actionHandler != null) {
  87. if (actionHandlers == null) {
  88. actionHandlers = new HashSet<Handler>();
  89. }
  90. if (actionHandlers.add(actionHandler)) {
  91. requestRepaint();
  92. }
  93. }
  94. }
  95. @Override
  96. public void removeActionHandler(Action.Handler actionHandler) {
  97. if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
  98. if (actionHandlers.remove(actionHandler)) {
  99. requestRepaint();
  100. }
  101. if (actionHandlers.isEmpty()) {
  102. actionHandlers = null;
  103. }
  104. }
  105. }
  106. public void removeAllActionHandlers() {
  107. if (actionHandlers != null) {
  108. actionHandlers = null;
  109. requestRepaint();
  110. }
  111. }
  112. public void paintActions(Object actionTarget, PaintTarget paintTarget)
  113. throws PaintException {
  114. actionMapper = null;
  115. HashSet<Action> actions = new HashSet<Action>();
  116. if (actionHandlers != null) {
  117. for (Action.Handler handler : actionHandlers) {
  118. Action[] as = handler.getActions(actionTarget, viewer);
  119. if (as != null) {
  120. for (Action action : as) {
  121. actions.add(action);
  122. }
  123. }
  124. }
  125. }
  126. if (ownActions != null) {
  127. actions.addAll(ownActions);
  128. }
  129. /*
  130. * Must repaint whenever there are actions OR if all actions have been
  131. * removed but still exist on client side
  132. */
  133. if (!actions.isEmpty() || clientHasActions) {
  134. actionMapper = new KeyMapper<Action>();
  135. paintTarget.addVariable((VariableOwner) viewer, "action", "");
  136. paintTarget.startTag("actions");
  137. for (final Action a : actions) {
  138. paintTarget.startTag("action");
  139. final String akey = actionMapper.key(a);
  140. paintTarget.addAttribute("key", akey);
  141. if (a.getCaption() != null) {
  142. paintTarget.addAttribute("caption", a.getCaption());
  143. }
  144. if (a.getIcon() != null) {
  145. paintTarget.addAttribute("icon", a.getIcon());
  146. }
  147. if (a instanceof ShortcutAction) {
  148. final ShortcutAction sa = (ShortcutAction) a;
  149. paintTarget.addAttribute("kc", sa.getKeyCode());
  150. final int[] modifiers = sa.getModifiers();
  151. if (modifiers != null) {
  152. final String[] smodifiers = new String[modifiers.length];
  153. for (int i = 0; i < modifiers.length; i++) {
  154. smodifiers[i] = String.valueOf(modifiers[i]);
  155. }
  156. paintTarget.addAttribute("mk", smodifiers);
  157. }
  158. }
  159. paintTarget.endTag("action");
  160. }
  161. paintTarget.endTag("actions");
  162. }
  163. /*
  164. * Update flag for next repaint so we know if we need to paint empty
  165. * actions or not (must send actions is client had actions before and
  166. * all actions were removed).
  167. */
  168. clientHasActions = !actions.isEmpty();
  169. }
  170. public void handleActions(Map<String, Object> variables, Container sender) {
  171. if (variables.containsKey("action") && actionMapper != null) {
  172. final String key = (String) variables.get("action");
  173. final Action action = actionMapper.get(key);
  174. final Object target = variables.get("actiontarget");
  175. if (action != null) {
  176. handleAction(action, sender, target);
  177. }
  178. }
  179. }
  180. @Override
  181. public Action[] getActions(Object target, Object sender) {
  182. HashSet<Action> actions = new HashSet<Action>();
  183. if (ownActions != null) {
  184. for (Action a : ownActions) {
  185. actions.add(a);
  186. }
  187. }
  188. if (actionHandlers != null) {
  189. for (Action.Handler h : actionHandlers) {
  190. Action[] as = h.getActions(target, sender);
  191. if (as != null) {
  192. for (Action a : as) {
  193. actions.add(a);
  194. }
  195. }
  196. }
  197. }
  198. return actions.toArray(new Action[actions.size()]);
  199. }
  200. @Override
  201. public void handleAction(Action action, Object sender, Object target) {
  202. if (actionHandlers != null) {
  203. Handler[] array = actionHandlers.toArray(new Handler[actionHandlers
  204. .size()]);
  205. for (Handler handler : array) {
  206. handler.handleAction(action, sender, target);
  207. }
  208. }
  209. if (ownActions != null && ownActions.contains(action)
  210. && action instanceof Action.Listener) {
  211. ((Action.Listener) action).handleAction(sender, target);
  212. }
  213. }
  214. }