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.3KB

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