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.

FeatureBrowser.java 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.automatedtests.featurebrowser;
  5. import java.util.HashMap;
  6. import java.util.Iterator;
  7. import com.vaadin.data.Item;
  8. import com.vaadin.data.Property;
  9. import com.vaadin.data.Property.ValueChangeEvent;
  10. import com.vaadin.data.util.HierarchicalContainer;
  11. import com.vaadin.data.util.IndexedContainer;
  12. import com.vaadin.terminal.ExternalResource;
  13. import com.vaadin.terminal.ThemeResource;
  14. import com.vaadin.ui.AbstractSelect;
  15. import com.vaadin.ui.Alignment;
  16. import com.vaadin.ui.Button;
  17. import com.vaadin.ui.Component;
  18. import com.vaadin.ui.Embedded;
  19. import com.vaadin.ui.HorizontalLayout;
  20. import com.vaadin.ui.Label;
  21. import com.vaadin.ui.Layout;
  22. import com.vaadin.ui.Select;
  23. import com.vaadin.ui.SplitPanel;
  24. import com.vaadin.ui.TabSheet;
  25. import com.vaadin.ui.Table;
  26. import com.vaadin.ui.Tree;
  27. import com.vaadin.ui.VerticalLayout;
  28. import com.vaadin.ui.Window;
  29. import com.vaadin.ui.Button.ClickEvent;
  30. /**
  31. *
  32. * @author IT Mill Ltd.
  33. * @see com.vaadin.ui.Window
  34. */
  35. @SuppressWarnings("serial")
  36. public class FeatureBrowser extends com.vaadin.Application implements
  37. Select.ValueChangeListener {
  38. // Property IDs
  39. private static final Object PROPERTY_ID_CATEGORY = "Category";
  40. private static final Object PROPERTY_ID_NAME = "Name";
  41. private static final Object PROPERTY_ID_DESC = "Description";
  42. private static final Object PROPERTY_ID_CLASS = "Class";
  43. private static final Object PROPERTY_ID_VIEWED = "Viewed";
  44. // Global components
  45. private Tree tree;
  46. private Table table;
  47. private TabSheet ts;
  48. // Example "cache"
  49. private final HashMap exampleInstances = new HashMap();
  50. private String section;
  51. // List of examples
  52. private static final Object[][] demos = new Object[][] {
  53. // Category, Name, Desc, Class, Viewed
  54. // Getting started: Labels
  55. { "Getting started", "Labels", "Some variations of Labels",
  56. LabelExample.class },
  57. // Getting started: Buttons
  58. { "Getting started", "Buttons and links",
  59. "Various Buttons and Links", ButtonExample.class },
  60. // Getting started: Fields
  61. { "Getting started", "Basic value input",
  62. "TextFields, DateFields, and such", ValueInputExample.class },
  63. //
  64. { "Getting started", "RichText", "Rich text editing",
  65. RichTextExample.class },
  66. // Getting started: Selects
  67. { "Getting started", "Choices, choices",
  68. "Some variations of simple selects", SelectExample.class },
  69. // Layouts
  70. { "Layouts", "Basic layouts", "Laying out components",
  71. LayoutExample.class },
  72. // Layouts
  73. { "Layouts", "Accordion", "Play the Accordion!",
  74. AccordionExample.class },
  75. // Wrangling data: ComboBox
  76. { "Wrangling data", "ComboBox", "ComboBox - the swiss army select",
  77. ComboBoxExample.class },
  78. // Wrangling data: Table
  79. {
  80. "Wrangling data",
  81. "Table (\"grid\")",
  82. "Table with bells, whistles, editmode and actions (contextmenu)",
  83. TableExample.class },
  84. // Wrangling data: Form
  85. { "Wrangling data", "Form", "Every application needs forms",
  86. FormExample.class },
  87. // Wrangling data: Tree
  88. { "Wrangling data", "Tree", "A hierarchy of things",
  89. TreeExample.class },
  90. // Misc: Notifications
  91. { "Misc", "Notifications", "Notifications can improve usability",
  92. NotificationExample.class },
  93. // Misc: Caching
  94. { "Misc", "Client caching", "Demonstrating of client-side caching",
  95. ClientCachingExample.class },
  96. // Misc: Embedded
  97. { "Misc", "Embedding",
  98. "Embedding resources - another site in this case",
  99. EmbeddedBrowserExample.class },
  100. // Windowing
  101. { "Misc", "Windowing", "About windowing", WindowingExample.class },
  102. // JavaScript API
  103. { "Misc", "JavaScript API",
  104. "JavaScript to IT Mill Toolkit communication",
  105. JavaScriptAPIExample.class },
  106. // END
  107. };
  108. @Override
  109. public void init() {
  110. // Need to set a theme for ThemeResources to work
  111. setTheme("example");
  112. // Create new window for the application and give the window a visible.
  113. final Window main = new Window("IT Mill Toolkit 5");
  114. main.setDebugId("mainWindow");
  115. // set as main window
  116. setMainWindow(main);
  117. final SplitPanel split = new SplitPanel(
  118. SplitPanel.ORIENTATION_HORIZONTAL);
  119. split.setSplitPosition(200, SplitPanel.UNITS_PIXELS);
  120. main.setLayout(split);
  121. final HashMap sectionIds = new HashMap();
  122. final HierarchicalContainer container = createContainer();
  123. final Object rootId = container.addItem();
  124. Item item = container.getItem(rootId);
  125. Property p = item.getItemProperty(PROPERTY_ID_NAME);
  126. p.setValue("All examples");
  127. for (int i = 0; i < demos.length; i++) {
  128. final Object[] demo = demos[i];
  129. final String section = (String) demo[0];
  130. Object sectionId;
  131. if (sectionIds.containsKey(section)) {
  132. sectionId = sectionIds.get(section);
  133. } else {
  134. sectionId = container.addItem();
  135. sectionIds.put(section, sectionId);
  136. container.setParent(sectionId, rootId);
  137. item = container.getItem(sectionId);
  138. p = item.getItemProperty(PROPERTY_ID_NAME);
  139. p.setValue(section);
  140. }
  141. final Object id = container.addItem();
  142. container.setParent(id, sectionId);
  143. initItem(container.getItem(id), demo);
  144. }
  145. tree = new Tree();
  146. tree.setDebugId("FeatureBrowser: Main Tree");
  147. tree.setSelectable(true);
  148. tree.setMultiSelect(false);
  149. tree.setNullSelectionAllowed(false);
  150. tree.setContainerDataSource(container);
  151. tree.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
  152. tree.setItemCaptionPropertyId(PROPERTY_ID_NAME);
  153. tree.addListener(this);
  154. tree.setImmediate(true);
  155. tree.expandItemsRecursively(rootId);
  156. for (Iterator<?> i = container.getItemIds().iterator(); i.hasNext();) {
  157. Object id = i.next();
  158. if (container.getChildren(id) == null) {
  159. tree.setChildrenAllowed(id, false);
  160. }
  161. }
  162. split.addComponent(tree);
  163. final SplitPanel split2 = new SplitPanel();
  164. split2.setSplitPosition(200, SplitPanel.UNITS_PIXELS);
  165. split.addComponent(split2);
  166. table = new Table();
  167. table.setDebugId("FeatureBrowser: Main Table");
  168. table.setSizeFull();
  169. table.setColumnReorderingAllowed(true);
  170. table.setColumnCollapsingAllowed(true);
  171. table.setSelectable(true);
  172. table.setMultiSelect(false);
  173. table.setNullSelectionAllowed(false);
  174. try {
  175. table.setContainerDataSource((IndexedContainer) container.clone());
  176. } catch (final Exception e) {
  177. e.printStackTrace(System.err);
  178. }
  179. // Hide some columns
  180. table.setVisibleColumns(new Object[] { PROPERTY_ID_CATEGORY,
  181. PROPERTY_ID_NAME, PROPERTY_ID_DESC, PROPERTY_ID_VIEWED });
  182. table.addListener(this);
  183. table.setImmediate(true);
  184. split2.addComponent(table);
  185. final VerticalLayout exp = new VerticalLayout();
  186. exp.setSizeFull();
  187. exp.setMargin(true);
  188. split2.addComponent(exp);
  189. final HorizontalLayout wbLayout = new HorizontalLayout();
  190. Button b = new Button("Open in sub-window", new Button.ClickListener() {
  191. public void buttonClick(ClickEvent event) {
  192. Component component = (Component) ts.getComponentIterator()
  193. .next();
  194. String caption = ts.getTabCaption(component);
  195. try {
  196. component = component.getClass().newInstance();
  197. } catch (Exception e) {
  198. // Could not create
  199. return;
  200. }
  201. Window w = new Window(caption);
  202. w.setWidth("640px");
  203. if (Layout.class.isAssignableFrom(component.getClass())) {
  204. w.setLayout((Layout) component);
  205. } else {
  206. // w.getLayout().getSize().setSizeFull();
  207. w.addComponent(component);
  208. }
  209. getMainWindow().addWindow(w);
  210. }
  211. });
  212. b.setStyleName(Button.STYLE_LINK);
  213. wbLayout.addComponent(b);
  214. b = new Button("Open in native window", new Button.ClickListener() {
  215. public void buttonClick(ClickEvent event) {
  216. Component component = (Component) ts.getComponentIterator()
  217. .next();
  218. final String caption = ts.getTabCaption(component);
  219. Window w = getWindow(caption);
  220. if (w == null) {
  221. try {
  222. component = component.getClass().newInstance();
  223. } catch (final Exception e) {
  224. // Could not create
  225. return;
  226. }
  227. w = new Window(caption);
  228. w.setName(caption);
  229. if (Layout.class.isAssignableFrom(component.getClass())) {
  230. w.setLayout((Layout) component);
  231. } else {
  232. // w.getLayout().getSize().setSizeFull();
  233. w.addComponent(component);
  234. }
  235. addWindow(w);
  236. }
  237. getMainWindow().open(new ExternalResource(w.getURL()), caption);
  238. }
  239. });
  240. b.setStyleName(Button.STYLE_LINK);
  241. wbLayout.addComponent(b);
  242. exp.addComponent(wbLayout);
  243. exp.setComponentAlignment(wbLayout, Alignment.TOP_RIGHT);
  244. ts = new TabSheet();
  245. ts.setSizeFull();
  246. ts.addTab(new Label(""), "Choose example", null);
  247. exp.addComponent(ts);
  248. exp.setExpandRatio(ts, 1);
  249. final Label status = new Label(
  250. "<a href=\"http://www.itmill.com/developers/\">Developer Area</a>"
  251. + " | <a href=\"http://www.itmill.com/documentation/\">Documentation</a>");
  252. status.setContentMode(Label.CONTENT_XHTML);
  253. exp.addComponent(status);
  254. exp.setComponentAlignment(status, Alignment.MIDDLE_RIGHT);
  255. // select initial section ("All")
  256. tree.setValue(rootId);
  257. getMainWindow()
  258. .showNotification(
  259. "Welcome",
  260. "Choose an example to begin.<br/><br/>And remember to experiment!",
  261. Window.Notification.TYPE_TRAY_NOTIFICATION);
  262. }
  263. private void initItem(Item item, Object[] data) {
  264. int p = 0;
  265. Property prop = item.getItemProperty(PROPERTY_ID_CATEGORY);
  266. prop.setValue(data[p++]);
  267. prop = item.getItemProperty(PROPERTY_ID_NAME);
  268. prop.setValue(data[p++]);
  269. prop = item.getItemProperty(PROPERTY_ID_DESC);
  270. prop.setValue(data[p++]);
  271. prop = item.getItemProperty(PROPERTY_ID_CLASS);
  272. prop.setValue(data[p++]);
  273. }
  274. private HierarchicalContainer createContainer() {
  275. final HierarchicalContainer c = new HierarchicalContainer();
  276. c.addContainerProperty(PROPERTY_ID_CATEGORY, String.class, null);
  277. c.addContainerProperty(PROPERTY_ID_NAME, String.class, "");
  278. c.addContainerProperty(PROPERTY_ID_DESC, String.class, "");
  279. c.addContainerProperty(PROPERTY_ID_CLASS, Class.class, null);
  280. c.addContainerProperty(PROPERTY_ID_VIEWED, Embedded.class, null);
  281. return c;
  282. }
  283. public void valueChange(ValueChangeEvent event) {
  284. if (event.getProperty() == tree) {
  285. final Object id = tree.getValue();
  286. if (id == null) {
  287. return;
  288. }
  289. final Item item = tree.getItem(id);
  290. //
  291. String newSection;
  292. if (tree.isRoot(id)) {
  293. newSection = ""; // show all sections
  294. } else if (tree.hasChildren(id)) {
  295. newSection = (String) item.getItemProperty(PROPERTY_ID_NAME)
  296. .getValue();
  297. } else {
  298. newSection = (String) item
  299. .getItemProperty(PROPERTY_ID_CATEGORY).getValue();
  300. }
  301. table.setValue(null);
  302. final IndexedContainer c = (IndexedContainer) table
  303. .getContainerDataSource();
  304. if (newSection != null && !newSection.equals(section)) {
  305. c.removeAllContainerFilters();
  306. c.addContainerFilter(PROPERTY_ID_CATEGORY, newSection, false,
  307. true);
  308. }
  309. section = newSection;
  310. if (!tree.hasChildren(id)) {
  311. // Example, not section
  312. // update table selection
  313. table.setValue(id);
  314. }
  315. } else if (event.getProperty() == table) {
  316. if (table.getValue() != null) {
  317. table.removeListener(this);
  318. tree.setValue(table.getValue());
  319. table.addListener(this);
  320. final Item item = table.getItem(table.getValue());
  321. final Class<?> c = (Class<?>) item.getItemProperty(
  322. PROPERTY_ID_CLASS).getValue();
  323. final Component component = getComponent(c);
  324. if (component != null) {
  325. final String caption = (String) item.getItemProperty(
  326. PROPERTY_ID_NAME).getValue();
  327. ts.removeAllComponents();
  328. ts.addTab(component, caption, null);
  329. }
  330. // update "viewed" state
  331. final Property p = item.getItemProperty(PROPERTY_ID_VIEWED);
  332. if (p.getValue() == null) {
  333. p.setValue(new Embedded("", new ThemeResource(
  334. "icons/ok.png")));
  335. }
  336. table.requestRepaint();
  337. }
  338. }
  339. }
  340. private Component getComponent(Class<?> componentClass) {
  341. if (!exampleInstances.containsKey(componentClass)) {
  342. try {
  343. final Component c = (Component) componentClass.newInstance();
  344. exampleInstances.put(componentClass, c);
  345. } catch (final Exception e) {
  346. return null;
  347. }
  348. }
  349. return (Component) exampleInstances.get(componentClass);
  350. }
  351. }