From 6b6b9f5dce0897ee06d478cafc75676575cecaee Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Thu, 9 Oct 2008 10:44:35 +0000 Subject: [PATCH] Pre-svn-move Sampler-proto commit svn changeset:5618/svn branch:trunk --- .../toolkit/demo/sampler/ExampleUtil.java | 13 + .../itmill/toolkit/demo/sampler/Feature.java | 69 ++++ .../toolkit/demo/sampler/FeatureSet.png | Bin 0 -> 5758 bytes .../toolkit/demo/sampler/FeatureView.java | 23 ++ .../demo/sampler/SamplerApplication.java | 355 ++++++++++++++++++ .../demo/sampler/features/DummyFeature.gif | Bin 0 -> 8417 bytes .../demo/sampler/features/DummyFeature.java | 11 + .../sampler/features/DummyFeatureExample.java | 12 + 8 files changed, 483 insertions(+) create mode 100644 src/com/itmill/toolkit/demo/sampler/ExampleUtil.java create mode 100644 src/com/itmill/toolkit/demo/sampler/Feature.java create mode 100644 src/com/itmill/toolkit/demo/sampler/FeatureSet.png create mode 100644 src/com/itmill/toolkit/demo/sampler/FeatureView.java create mode 100644 src/com/itmill/toolkit/demo/sampler/SamplerApplication.java create mode 100644 src/com/itmill/toolkit/demo/sampler/features/DummyFeature.gif create mode 100644 src/com/itmill/toolkit/demo/sampler/features/DummyFeature.java create mode 100644 src/com/itmill/toolkit/demo/sampler/features/DummyFeatureExample.java diff --git a/src/com/itmill/toolkit/demo/sampler/ExampleUtil.java b/src/com/itmill/toolkit/demo/sampler/ExampleUtil.java new file mode 100644 index 0000000000..41961a8f89 --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/ExampleUtil.java @@ -0,0 +1,13 @@ +package com.itmill.toolkit.demo.sampler; + +import com.itmill.toolkit.data.Container; + +public final class ExampleUtil { + + public static void fillContainerWithEmailAddresses(Container c, int amount) { + for (int i = 0; i < amount; i++) { + // TODO + } + } + +} diff --git a/src/com/itmill/toolkit/demo/sampler/Feature.java b/src/com/itmill/toolkit/demo/sampler/Feature.java new file mode 100644 index 0000000000..44eaa1bdb1 --- /dev/null +++ b/src/com/itmill/toolkit/demo/sampler/Feature.java @@ -0,0 +1,69 @@ +/** + * + */ +package com.itmill.toolkit.demo.sampler; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import com.google.gwt.i18n.client.Messages.Example; + +abstract public class Feature { + + public static final Object PROPERTY_ICON = "Icon"; + public static final Object PROPERTY_NAME = "Name"; + public static final Object PROPERTY_DESCRIPTION = "Description"; + + protected Example example = null; + + /** Get the name of the feature. Override if needed. */ + public String getName() { + String[] cn = this.getClass().getName().split("\\."); + return cn[cn.length - 1]; + } + + abstract public String getDescription(); + + public String getIconName() { + String[] cn = this.getClass().getName().split("\\."); + String icon = cn[cn.length - 1] + ".gif"; + return icon; + } + + /** Get the example instance. Override if instantiation needs parameters. */ + public Example getExample() { + if (example == null) { + String className = this.getClass().getName() + "Example"; + try { + Class classObject = getClass().getClassLoader().loadClass( + className); + example = (Example) classObject.newInstance(); + } catch (ClassNotFoundException e) { + return null; + } catch (InstantiationException e) { + return null; + } catch (IllegalAccessException e) { + return null; + } + } + return example; + } + + public Reader getSource() { + String className = this.getClass().getName() + "Example"; + String javaFileName = className.replace(".", "/"); + InputStream is = getClass().getClassLoader().getResourceAsStream( + javaFileName); + return new InputStreamReader(is); + } + + public Reader getSourceHTML() { + return getSource(); + } + + public String toString() { + return getName(); + } + +} \ No newline at end of file diff --git a/src/com/itmill/toolkit/demo/sampler/FeatureSet.png b/src/com/itmill/toolkit/demo/sampler/FeatureSet.png new file mode 100644 index 0000000000000000000000000000000000000000..69e13fa395c40cbf5c5abf62af57beaf93daca19 GIT binary patch literal 5758 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", new ClickListener() { + public void buttonClick(ClickEvent event) { + Object curr = currentFeature.getValue(); + Object next = allFeatures.nextItemId(curr); + while (next != null && next instanceof FeatureSet) { + next = allFeatures.nextItemId(next); + } + currentFeature.setValue(next); + + } + }); + nav.addComponent(b); + nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_LEFT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + + b = new Button(":: | \\⊡/ | ≣"); + nav.addComponent(b); + nav.expand(b); + nav.setComponentAlignment(b, ExpandLayout.ALIGNMENT_RIGHT, + ExpandLayout.ALIGNMENT_VERTICAL_CENTER); + + Tree tree = new Tree(); + tree.setImmediate(true); + split.addComponent(tree); + tree.setContainerDataSource(allFeatures); + tree.setPropertyDataSource(currentFeature); + for (int i = 0; i < features.getFeatures().length; i++) { + tree.expandItemsRecursively(features.getFeatures()[i]); + } + tree.expandItemsRecursively(features); + tree.addListener(new Table.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + Feature val = (Feature) event.getProperty().getValue(); + if (val == null) { + currentList.setFeatureContainer(features + .getContainer(true)); + if (currentList.getParent() != split) { + split.replaceComponent(featureView, currentList); + } + + } else if (val instanceof FeatureSet) { + currentList.setFeatureContainer(((FeatureSet) val) + .getContainer(false)); + if (currentList.getParent() != split) { + split.replaceComponent(featureView, currentList); + } + } else { + if (featureView.getParent() != split) { + split.replaceComponent(currentList, featureView); + } + featureView.setFeature(val); + } + } + }); + + FeatureTable tbl = new FeatureTable(); + tbl.setFeatureContainer(allFeatures); + currentList = tbl; + + split.addComponent(tbl); + + featureView = new FeatureView(); + + Feature f = features.getFeatureByPath("Components/c/DummyFeature"); + tree.setValue(f); + } + } + + private class FeatureTable extends Table implements FeatureList { + FeatureTable() { + alwaysRecalculateColumnWidths = true; + setSelectable(false); + setSizeFull(); + setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN); + addGeneratedColumn(Feature.PROPERTY_ICON, + new Table.ColumnGenerator() { + public Component generateCell(Table source, + Object itemId, Object columnId) { + Feature f = (Feature) itemId; + Resource res = new ClassResource(f.getClass(), f + .getIconName(), SamplerApplication.this); + Embedded emb = new Embedded("", res); + emb.setWidth("48px"); + emb.setHeight("48px"); + emb.setType(Embedded.TYPE_IMAGE); + return emb; + } + + }); + addGeneratedColumn("", new Table.ColumnGenerator() { + public Component generateCell(Table source, Object itemId, + Object columnId) { + Button b = new Button( + itemId instanceof FeatureSet ? "See samples ‣" + : "See sample ‣"); + b.setData(itemId); + b.addListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + currentFeature + .setValue(event.getButton().getData()); + } + }); + b.setStyleName(Button.STYLE_LINK); + return b; + } + + }); + } + + public void setFeatureContainer(Container c) { + setContainerDataSource(c); + setVisibleColumns(new Object[] { Feature.PROPERTY_ICON, + Feature.PROPERTY_NAME, Feature.PROPERTY_DESCRIPTION, "" }); + setColumnWidth(Feature.PROPERTY_ICON, 60); + setColumnWidth(Feature.PROPERTY_NAME, 150); + + } + + } + + static class FeatureSet extends Feature { + + String name; + + Feature[] content; + + HierarchicalContainer container = null; + + FeatureSet(String name, Feature[] content) { + this.name = name; + this.content = content; + } + + Feature[] getFeatures() { + return content; + } + + Feature getFeatureByPath(String path) { + LinkedList parts = new LinkedList(); + Collections.addAll(parts, path.split("/")); + FeatureSet f = this; + while (f != null) { + Feature[] fs = f.getFeatures(); + f = null; // break while if no new found + String part = parts.remove(0); + for (int i = 0; i < fs.length; i++) { + if (fs[i].getName().equals(part)) { + if (parts.isEmpty()) { + return fs[i]; + } else if (fs[i] instanceof FeatureSet) { + f = (FeatureSet) fs[i]; + break; + } else { + return null; + } + } + } + } + return null; + } + + Container.Hierarchical getContainer(boolean recurse) { + if (container == null) { + container = new HierarchicalContainer(); + container.addContainerProperty(PROPERTY_NAME, String.class, ""); + container.addContainerProperty(PROPERTY_DESCRIPTION, + String.class, ""); + // fill + addFeatures(this, container, recurse); + } + return container; + } + + private void addFeatures(FeatureSet f, Container.Hierarchical c, + boolean recurse) { + Feature[] features = f.getFeatures(); + for (int i = 0; i < features.length; i++) { + Item item = c.addItem(features[i]); + Property property = item.getItemProperty(PROPERTY_NAME); + property.setValue(features[i].getName()); + property = item.getItemProperty(PROPERTY_DESCRIPTION); + property.setValue(features[i].getDescription()); + if (recurse) { + c.setParent(features[i], f); + if (features[i] instanceof FeatureSet) { + addFeatures((FeatureSet) features[i], c, recurse); + } + } + if (!(features[i] instanceof FeatureSet)) { + c.setChildrenAllowed(features[i], false); + } + } + } + + @Override + public String getDescription() { + return null; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getIconName() { + return "FeatureSet.png"; + } + + } + + interface FeatureList extends Component { + public void setFeatureContainer(Container c); + } + +} diff --git a/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.gif b/src/com/itmill/toolkit/demo/sampler/features/DummyFeature.gif new file mode 100644 index 0000000000000000000000000000000000000000..fa6b38b4c91fa17cdf59fdef2fc0ef46160bd2cf GIT binary patch literal 8417 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