您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Trees.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package com.vaadin.v7.tests.components.tree;
  2. import java.util.ArrayList;
  3. import java.util.LinkedHashMap;
  4. import java.util.List;
  5. import com.vaadin.event.Action;
  6. import com.vaadin.event.Action.Handler;
  7. import com.vaadin.shared.ui.MultiSelectMode;
  8. import com.vaadin.tests.components.select.AbstractSelectTestCase;
  9. import com.vaadin.v7.data.Container;
  10. import com.vaadin.v7.data.Container.Hierarchical;
  11. import com.vaadin.v7.data.util.HierarchicalContainer;
  12. import com.vaadin.v7.ui.Tree;
  13. import com.vaadin.v7.ui.Tree.CollapseEvent;
  14. import com.vaadin.v7.ui.Tree.CollapseListener;
  15. import com.vaadin.v7.ui.Tree.ExpandEvent;
  16. import com.vaadin.v7.ui.Tree.ExpandListener;
  17. import com.vaadin.v7.ui.Tree.ItemStyleGenerator;
  18. public class Trees extends AbstractSelectTestCase<Tree>
  19. implements ExpandListener, CollapseListener {
  20. private int rootItemIds = 3;
  21. private ItemStyleGenerator rootGreenSecondLevelRed = new com.vaadin.v7.ui.Tree.ItemStyleGenerator() {
  22. @Override
  23. public String getStyle(Tree source, Object itemId) {
  24. Hierarchical c = (Container.Hierarchical) getComponent()
  25. .getContainerDataSource();
  26. if (c.isRoot(itemId)) {
  27. return "green";
  28. }
  29. Object parent = c.getParent(itemId);
  30. if (!c.isRoot(parent)) {
  31. return "red";
  32. }
  33. return null;
  34. }
  35. @Override
  36. public String toString() {
  37. return "Root green, second level red";
  38. }
  39. };
  40. private ItemStyleGenerator evenItemsBold = new com.vaadin.v7.ui.Tree.ItemStyleGenerator() {
  41. @Override
  42. public String getStyle(Tree source, Object itemId) {
  43. Hierarchical c = (Container.Hierarchical) getComponent()
  44. .getContainerDataSource();
  45. int idx = 0;
  46. for (Object id : c.getItemIds()) {
  47. if (id == itemId) {
  48. if (idx % 2 == 1) {
  49. return "bold";
  50. } else {
  51. return null;
  52. }
  53. }
  54. idx++;
  55. }
  56. return null;
  57. }
  58. @Override
  59. public String toString() {
  60. return "Even items bold";
  61. }
  62. };
  63. private Command<Tree, ContextMenu> contextMenuCommand = new Command<Tree, ContextMenu>() {
  64. @Override
  65. public void execute(Tree c, final ContextMenu value, Object data) {
  66. c.removeAllActionHandlers();
  67. if (value != null) {
  68. c.addActionHandler(new Handler() {
  69. @Override
  70. public void handleAction(Action action, Object sender,
  71. Object target) {
  72. log("Action " + action.getCaption() + " performed on "
  73. + target);
  74. }
  75. @Override
  76. public Action[] getActions(Object target, Object sender) {
  77. return value.getActions(target, sender);
  78. }
  79. });
  80. }
  81. }
  82. };
  83. @Override
  84. protected Class<Tree> getTestClass() {
  85. return Tree.class;
  86. }
  87. @Override
  88. protected void createActions() {
  89. super.createActions();
  90. // Causes container changes so doing this first..
  91. createRootItemSelectAction(CATEGORY_DATA_SOURCE);
  92. createExpandCollapseActions(CATEGORY_FEATURES);
  93. createSelectionModeSelect(CATEGORY_SELECTION);
  94. createChildrenAllowedAction(CATEGORY_DATA_SOURCE);
  95. createListeners(CATEGORY_LISTENERS);
  96. createItemStyleGenerator(CATEGORY_FEATURES);
  97. createContextMenuAction(CATEGORY_FEATURES);
  98. // TODO: DropHandler
  99. // TODO: DragMode
  100. // TODO: ActionHandler
  101. }
  102. private void createContextMenuAction(String category) {
  103. LinkedHashMap<String, ContextMenu> options = new LinkedHashMap<>();
  104. options.put("None", null);
  105. options.put("Item without icon", new ContextMenu("No icon", null));
  106. ContextMenu cm = new ContextMenu();
  107. cm.addItem("Caption only", null);
  108. cm.addItem("Has icon", ICON_16_USER_PNG_UNCACHEABLE);
  109. options.put("With and without icon", cm);
  110. options.put("Only one large icon",
  111. new ContextMenu("Icon", ICON_64_EMAIL_REPLY_PNG_UNCACHEABLE));
  112. createSelectAction("Context menu", category, options, "None",
  113. contextMenuCommand, true);
  114. }
  115. private void createItemStyleGenerator(String category) {
  116. LinkedHashMap<String, com.vaadin.v7.ui.Tree.ItemStyleGenerator> options = new LinkedHashMap<>();
  117. options.put("-", null);
  118. options.put(rootGreenSecondLevelRed.toString(),
  119. rootGreenSecondLevelRed);
  120. options.put(evenItemsBold.toString(), evenItemsBold);
  121. createSelectAction("Item Style generator", category, options, "-",
  122. itemStyleGeneratorCommand);
  123. }
  124. private void createListeners(String category) {
  125. createBooleanAction("Expand listener", category, false,
  126. expandListenerCommand);
  127. createBooleanAction("Collapse listener", category, false,
  128. collapseListenerCommand);
  129. createBooleanAction("Item click listener", category, false,
  130. itemClickListenerCommand);
  131. }
  132. private enum SelectMode {
  133. NONE, SINGLE, MULTI_SIMPLE, MULTI;
  134. }
  135. protected void createSelectionModeSelect(String category) {
  136. LinkedHashMap<String, SelectMode> options = new LinkedHashMap<>();
  137. options.put("None", SelectMode.NONE);
  138. options.put("Single", SelectMode.SINGLE);
  139. options.put("Multi - simple", SelectMode.MULTI_SIMPLE);
  140. options.put("Multi - ctrl/shift", SelectMode.MULTI);
  141. createSelectAction("Selection Mode", category, options,
  142. "Multi - ctrl/shift", new Command<Tree, SelectMode>() {
  143. @Override
  144. public void execute(Tree t, SelectMode value, Object data) {
  145. switch (value) {
  146. case NONE:
  147. t.setSelectable(false);
  148. break;
  149. case SINGLE:
  150. t.setMultiSelect(false);
  151. t.setSelectable(true);
  152. break;
  153. case MULTI_SIMPLE:
  154. t.setSelectable(true);
  155. t.setMultiSelect(true);
  156. t.setMultiselectMode(MultiSelectMode.SIMPLE);
  157. break;
  158. case MULTI:
  159. t.setSelectable(true);
  160. t.setMultiSelect(true);
  161. t.setMultiselectMode(MultiSelectMode.DEFAULT);
  162. break;
  163. }
  164. }
  165. });
  166. }
  167. @Override
  168. protected Container createContainer(int properties, int items) {
  169. return createHierarchicalContainer(properties, items, rootItemIds);
  170. }
  171. private Container.Hierarchical createHierarchicalContainer(int properties,
  172. int items, int roots) {
  173. Container.Hierarchical c = new HierarchicalContainer();
  174. populateContainer(c, properties, items);
  175. if (items <= roots) {
  176. return c;
  177. }
  178. // "roots" roots, each with
  179. // "firstLevel" children, two with no children (one with childAllowed,
  180. // one without)
  181. // ("firstLevel"-2)*"secondLevel" children ("secondLevel"/2 with
  182. // childAllowed, "secondLevel"/2 without)
  183. // N*M+N*(M-2)*C = items
  184. // items=N(M+MC-2C)
  185. // Using secondLevel=firstLevel/2 =>
  186. // items = roots*(firstLevel+firstLevel*firstLevel/2-2*firstLevel/2)
  187. // =roots*(firstLevel+firstLevel^2/2-firstLevel)
  188. // = roots*firstLevel^2/2
  189. // => firstLevel = sqrt(items/roots*2)
  190. int firstLevel = (int) Math.ceil(Math.sqrt(items / roots * 2.0));
  191. int secondLevel = firstLevel / 2;
  192. while (roots * (1 + 2 + (firstLevel - 2) * secondLevel) < items) {
  193. // Increase something so we get enough items
  194. secondLevel++;
  195. }
  196. List<Object> itemIds = new ArrayList<>(c.getItemIds());
  197. int nextItemId = roots;
  198. for (int rootIndex = 0; rootIndex < roots; rootIndex++) {
  199. // roots use items 0..roots-1
  200. Object rootItemId = itemIds.get(rootIndex);
  201. // force roots to be roots even though they automatically should be
  202. c.setParent(rootItemId, null);
  203. for (int firstLevelIndex = 0; firstLevelIndex < firstLevel; firstLevelIndex++) {
  204. if (nextItemId >= items) {
  205. break;
  206. }
  207. Object firstLevelItemId = itemIds.get(nextItemId++);
  208. c.setParent(firstLevelItemId, rootItemId);
  209. if (firstLevelIndex < 2) {
  210. continue;
  211. }
  212. // firstLevelChildren 2.. have child nodes
  213. for (int secondLevelIndex = 0; secondLevelIndex < secondLevel; secondLevelIndex++) {
  214. if (nextItemId >= items) {
  215. break;
  216. }
  217. Object secondLevelItemId = itemIds.get(nextItemId++);
  218. c.setParent(secondLevelItemId, firstLevelItemId);
  219. }
  220. }
  221. }
  222. return c;
  223. }
  224. private void createRootItemSelectAction(String category) {
  225. LinkedHashMap<String, Integer> options = new LinkedHashMap<>();
  226. for (int i = 1; i <= 10; i++) {
  227. options.put(String.valueOf(i), i);
  228. }
  229. options.put("20", 20);
  230. options.put("50", 50);
  231. options.put("100", 100);
  232. createSelectAction("Number of root items", category, options, "3",
  233. rootItemIdsCommand);
  234. }
  235. private void createExpandCollapseActions(String category) {
  236. LinkedHashMap<String, Object> options = new LinkedHashMap<>();
  237. for (Object id : getComponent().getItemIds()) {
  238. options.put(id.toString(), id);
  239. }
  240. createMultiClickAction("Expand", category, options, expandItemCommand,
  241. null);
  242. createMultiClickAction("Expand recursively", category, options,
  243. expandItemRecursivelyCommand, null);
  244. createMultiClickAction("Collapse", category, options,
  245. collapseItemCommand, null);
  246. }
  247. private void createChildrenAllowedAction(String category) {
  248. LinkedHashMap<String, Object> options = new LinkedHashMap<>();
  249. for (Object id : getComponent().getItemIds()) {
  250. options.put(id.toString(), id);
  251. }
  252. createMultiToggleAction("Children allowed", category, options,
  253. setChildrenAllowedCommand, true);
  254. }
  255. /*
  256. * COMMANDS
  257. */
  258. private Command<Tree, Integer> rootItemIdsCommand = new Command<Tree, Integer>() {
  259. @Override
  260. public void execute(Tree c, Integer value, Object data) {
  261. rootItemIds = value;
  262. updateContainer();
  263. }
  264. };
  265. private Command<Tree, Object> expandItemCommand = new Command<Tree, Object>() {
  266. @Override
  267. public void execute(Tree c, Object itemId, Object data) {
  268. c.expandItem(itemId);
  269. }
  270. };
  271. private Command<Tree, Object> expandItemRecursivelyCommand = new Command<Tree, Object>() {
  272. @Override
  273. public void execute(Tree c, Object itemId, Object data) {
  274. c.expandItemsRecursively(itemId);
  275. }
  276. };
  277. private Command<Tree, Object> collapseItemCommand = new Command<Tree, Object>() {
  278. @Override
  279. public void execute(Tree c, Object itemId, Object data) {
  280. c.collapseItem(itemId);
  281. }
  282. };
  283. private Command<Tree, Boolean> setChildrenAllowedCommand = new Command<Tree, Boolean>() {
  284. @Override
  285. public void execute(Tree c, Boolean areChildrenAllowed, Object itemId) {
  286. c.setChildrenAllowed(itemId, areChildrenAllowed);
  287. }
  288. };
  289. private Command<Tree, Boolean> expandListenerCommand = new Command<Tree, Boolean>() {
  290. @Override
  291. public void execute(Tree c, Boolean value, Object data) {
  292. if (value) {
  293. c.addListener((ExpandListener) Trees.this);
  294. } else {
  295. c.removeListener((ExpandListener) Trees.this);
  296. }
  297. }
  298. };
  299. private Command<Tree, Boolean> collapseListenerCommand = new Command<Tree, Boolean>() {
  300. @Override
  301. public void execute(Tree c, Boolean value, Object data) {
  302. if (value) {
  303. c.addListener((CollapseListener) Trees.this);
  304. } else {
  305. c.removeListener((CollapseListener) Trees.this);
  306. }
  307. }
  308. };
  309. private Command<Tree, com.vaadin.v7.ui.Tree.ItemStyleGenerator> itemStyleGeneratorCommand = new Command<Tree, com.vaadin.v7.ui.Tree.ItemStyleGenerator>() {
  310. @Override
  311. public void execute(Tree c,
  312. com.vaadin.v7.ui.Tree.ItemStyleGenerator value, Object data) {
  313. c.setItemStyleGenerator(value);
  314. }
  315. };
  316. @Override
  317. public void nodeCollapse(CollapseEvent event) {
  318. log(event.getClass().getSimpleName() + ": " + event.getItemId());
  319. }
  320. @Override
  321. public void nodeExpand(ExpandEvent event) {
  322. log(event.getClass().getSimpleName() + ": " + event.getItemId());
  323. }
  324. }