aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/itmill/toolkit/ui/Tree.java
diff options
context:
space:
mode:
authorMarc Englund <marc.englund@itmill.com>2007-11-19 14:03:05 +0000
committerMarc Englund <marc.englund@itmill.com>2007-11-19 14:03:05 +0000
commitf2e3722df9676436680afc0f1991e91e1696fb99 (patch)
tree6f255ff78abaf96f1e71a1f2c9ecd3b66647f4a2 /src/com/itmill/toolkit/ui/Tree.java
parent93291f532db9d545cf2a8dd98e2671f27cd197b0 (diff)
downloadvaadin-framework-f2e3722df9676436680afc0f1991e91e1696fb99.tar.gz
vaadin-framework-f2e3722df9676436680afc0f1991e91e1696fb99.zip
MASS REFORMAT.
According to http://toolkit.intra.itmill.com/trac/itmilltoolkit/wiki/CodingConventions svn changeset:2864/svn branch:trunk
Diffstat (limited to 'src/com/itmill/toolkit/ui/Tree.java')
-rw-r--r--src/com/itmill/toolkit/ui/Tree.java1902
1 files changed, 950 insertions, 952 deletions
diff --git a/src/com/itmill/toolkit/ui/Tree.java b/src/com/itmill/toolkit/ui/Tree.java
index a86717eb84..2042d4b312 100644
--- a/src/com/itmill/toolkit/ui/Tree.java
+++ b/src/com/itmill/toolkit/ui/Tree.java
@@ -59,957 +59,955 @@ import com.itmill.toolkit.terminal.Resource;
* @since 3.0
*/
public class Tree extends AbstractSelect implements Container.Hierarchical,
- Action.Container {
-
- /* Static members ***************************************************** */
-
- private static final Method EXPAND_METHOD;
-
- private static final Method COLLAPSE_METHOD;
-
- static {
- try {
- EXPAND_METHOD = ExpandListener.class.getDeclaredMethod(
- "nodeExpand", new Class[] { ExpandEvent.class });
- COLLAPSE_METHOD = CollapseListener.class.getDeclaredMethod(
- "nodeCollapse", new Class[] { CollapseEvent.class });
- } catch (java.lang.NoSuchMethodException e) {
- // This should never happen
- e.printStackTrace();
- throw new java.lang.RuntimeException(
- "Internal error, please report");
- }
- }
-
- /* Private members **************************************************** */
-
- /**
- * Set of expanded nodes.
- */
- private final HashSet expanded = new HashSet();
-
- /**
- * List of action handlers.
- */
- private LinkedList actionHandlers = null;
-
- /**
- * Action mapper.
- */
- private KeyMapper actionMapper = null;
-
- /**
- * Is the tree selectable .
- */
- private boolean selectable = true;
-
- /**
- * Flag to indicate sub-tree loading
- */
- private boolean partialUpdate = false;
-
- /**
- * Holds a itemId which was recently expanded
- */
- private Object expandedItemId;
-
- /**
- * a flag which indicates initial paint. After this flag set true partial
- * updates are allowed.
- */
- private boolean initialPaint = true;
-
- /* Tree constructors ************************************************** */
-
- /**
- * Creates a new empty tree.
- */
- public Tree() {
- }
-
- /**
- * Creates a new empty tree with caption.
- *
- * @param caption
- */
- public Tree(String caption) {
- setCaption(caption);
- }
-
- /**
- * Creates a new tree with caption and connect it to a Container.
- *
- * @param caption
- * @param dataSource
- */
- public Tree(String caption, Container dataSource) {
- setCaption(caption);
- setContainerDataSource(dataSource);
- }
-
- /* Expanding and collapsing ******************************************* */
-
- /**
- * Check is an item is expanded
- *
- * @param itemId
- * the item id.
- * @return true iff the item is expanded.
- */
- public boolean isExpanded(Object itemId) {
- return this.expanded.contains(itemId);
- }
-
- /**
- * Expands an item.
- *
- * @param itemId
- * the item id.
- * @return True iff the expand operation succeeded
- */
- public boolean expandItem(Object itemId) {
- return expandItem(itemId, true);
- }
-
- /**
- * Expands an item.
- *
- * @param itemId
- * the item id.
- * @param sendChildTree
- * flag to indicate if client needs subtree or not (may be cached)
- * @return True iff the expand operation succeeded
- */
- private boolean expandItem(Object itemId, boolean sendChildTree) {
-
- // Succeeds if the node is already expanded
- if (isExpanded(itemId)) {
- return true;
- }
-
- // Nodes that can not have children are not expandable
- if (!areChildrenAllowed(itemId)) {
- return false;
- }
-
- // Expands
- this.expanded.add(itemId);
-
- this.expandedItemId = itemId;
- if (this.initialPaint) {
- requestRepaint();
- } else if(sendChildTree) {
- requestPartialRepaint();
- }
- fireExpandEvent(itemId);
-
- return true;
- }
-
- public void requestRepaint() {
- super.requestRepaint();
- this.partialUpdate = false;
- }
-
- private void requestPartialRepaint() {
- super.requestRepaint();
- this.partialUpdate = true;
- }
-
- /**
- * Expands the items recursively
- *
- * Expands all the children recursively starting from an item. Operation
- * succeeds only if all expandable items are expanded.
- *
- * @param startItemId
- * @return True iff the expand operation succeeded
- */
- public boolean expandItemsRecursively(Object startItemId) {
-
- boolean result = true;
-
- // Initial stack
- Stack todo = new Stack();
- todo.add(startItemId);
-
- // Expands recursively
- while (!todo.isEmpty()) {
- Object id = todo.pop();
- if (areChildrenAllowed(id) && !expandItem(id, false)) {
- result = false;
- }
- if (hasChildren(id)) {
- todo.addAll(getChildren(id));
- }
- }
- requestRepaint();
- return result;
- }
-
- /**
- * Collapses an item.
- *
- * @param itemId
- * the item id.
- * @return True iff the collapse operation succeeded
- */
- public boolean collapseItem(Object itemId) {
-
- // Succeeds if the node is already collapsed
- if (!isExpanded(itemId)) {
- return true;
- }
-
- // Collapse
- this.expanded.remove(itemId);
- requestRepaint();
- fireCollapseEvent(itemId);
-
- return true;
- }
-
- /**
- * Collapses the items recursively.
- *
- * Collapse all the children recursively starting from an item. Operation
- * succeeds only if all expandable items are collapsed.
- *
- * @param startItemId
- * @return True iff the collapse operation succeeded
- */
- public boolean collapseItemsRecursively(Object startItemId) {
-
- boolean result = true;
-
- // Initial stack
- Stack todo = new Stack();
- todo.add(startItemId);
-
- // Collapse recursively
- while (!todo.isEmpty()) {
- Object id = todo.pop();
- if (areChildrenAllowed(id) && !collapseItem(id)) {
- result = false;
- }
- if (hasChildren(id)) {
- todo.addAll(getChildren(id));
- }
- }
-
- return result;
- }
-
- /**
- * Getter for property selectable.
- *
- * <p>
- * The tree is selectable by default.
- * </p>
- *
- * @return the Value of property selectable.
- */
- public boolean isSelectable() {
- return this.selectable;
- }
-
- /**
- * Setter for property selectable.
- *
- * <p>
- * The tree is selectable by default.
- * </p>
- *
- * @param selectable
- * the New value of property selectable.
- */
- public void setSelectable(boolean selectable) {
- if (this.selectable != selectable) {
- this.selectable = selectable;
- requestRepaint();
- }
- }
-
- /* Component API ****************************************************** */
-
- /**
- * Gets the UIDL tag corresponding to the component.
- *
- * @see com.itmill.toolkit.ui.AbstractComponent#getTag()
- */
- public String getTag() {
- return "tree";
- }
-
- /**
- * Called when one or more variables handled by the implementing class are
- * changed.
- *
- * @see com.itmill.toolkit.terminal.VariableOwner#changeVariables(Object
- * source, Map variables)
- */
- public void changeVariables(Object source, Map variables) {
-
- if (!isSelectable() && variables.containsKey("selected")) {
- // Not-selectable is a special case, AbstractSelect does not support
- // TODO could be optimized.
- variables = new HashMap(variables);
- variables.remove("selected");
- }
-
- // Collapses the nodes
- if (variables.containsKey("collapse")) {
- String[] keys = (String[]) variables.get("collapse");
- for (int i = 0; i < keys.length; i++) {
- Object id = this.itemIdMapper.get(keys[i]);
- if (id != null && isExpanded(id)) {
- this.expanded.remove(id);
- fireCollapseEvent(id);
- }
- }
- }
-
- // Expands the nodes
- if (variables.containsKey("expand")) {
- boolean sendChildTree = false;
- if(variables.containsKey("requestChildTree")) {
- sendChildTree = true;
- }
- String[] keys = (String[]) variables.get("expand");
- for (int i = 0; i < keys.length; i++) {
- Object id = this.itemIdMapper.get(keys[i]);
- if (id != null) {
- expandItem(id, sendChildTree);
- }
- }
- }
-
- // Selections are handled by the select component
- super.changeVariables(source, variables);
-
- // Actions
- if (variables.containsKey("action")) {
-
- StringTokenizer st = new StringTokenizer((String) variables
- .get("action"), ",");
- if (st.countTokens() == 2) {
- Object itemId = this.itemIdMapper.get(st.nextToken());
- Action action = (Action) this.actionMapper.get(st.nextToken());
- if (action != null && containsId(itemId)
- && this.actionHandlers != null) {
- for (Iterator i = this.actionHandlers.iterator(); i
- .hasNext();) {
- ((Action.Handler) i.next()).handleAction(action, this,
- itemId);
- }
- }
- }
- }
- }
-
- /**
- * Paints any needed component-specific things to the given UIDL stream.
- *
- * @see com.itmill.toolkit.ui.AbstractComponent#paintContent(PaintTarget)
- */
- public void paintContent(PaintTarget target) throws PaintException {
- this.initialPaint = false;
-
- if (this.partialUpdate) {
- target.addAttribute("partialUpdate", true);
- target.addAttribute("rootKey", this.itemIdMapper
- .key(this.expandedItemId));
- } else {
-
- // Focus control id
- if (getFocusableId() > 0) {
- target.addAttribute("focusid", getFocusableId());
- }
-
- // The tab ordering number
- if (getTabIndex() > 0) {
- target.addAttribute("tabindex", getTabIndex());
- }
-
- // Paint tree attributes
- if (isSelectable()) {
- target.addAttribute("selectmode", (isMultiSelect() ? "multi"
- : "single"));
- } else {
- target.addAttribute("selectmode", "none");
- }
- if (isNewItemsAllowed()) {
- target.addAttribute("allownewitem", true);
- }
-
- if (isNullSelectionAllowed()) {
- target.addAttribute("nullselect", true);
- }
-
- }
-
- // Initialize variables
- Set actionSet = new LinkedHashSet();
- String[] selectedKeys;
- if (isMultiSelect()) {
- selectedKeys = new String[((Set) getValue()).size()];
- } else {
- selectedKeys = new String[(getValue() == null ? 0 : 1)];
- }
- int keyIndex = 0;
- LinkedList expandedKeys = new LinkedList();
-
- // Iterates through hierarchical tree using a stack of iterators
- Stack iteratorStack = new Stack();
- Collection ids;
- if (this.partialUpdate) {
- ids = getChildren(this.expandedItemId);
- } else {
- ids = rootItemIds();
- }
-
- if (ids != null) {
- iteratorStack.push(ids.iterator());
- }
-
- while (!iteratorStack.isEmpty()) {
-
- // Gets the iterator for current tree level
- Iterator i = (Iterator) iteratorStack.peek();
-
- // If the level is finished, back to previous tree level
- if (!i.hasNext()) {
-
- // Removes used iterator from the stack
- iteratorStack.pop();
-
- // Closes node
- if (!iteratorStack.isEmpty()) {
- target.endTag("node");
- }
- }
-
- // Adds the item on current level
- else {
- Object itemId = i.next();
-
- // Starts the item / node
- boolean isNode = areChildrenAllowed(itemId)
- && hasChildren(itemId);
- if (isNode) {
- target.startTag("node");
- } else {
- target.startTag("leaf");
- }
-
- // Adds the attributes
- target.addAttribute("caption", getItemCaption(itemId));
- Resource icon = getItemIcon(itemId);
- if (icon != null) {
- target.addAttribute("icon", getItemIcon(itemId));
- }
- String key = this.itemIdMapper.key(itemId);
- target.addAttribute("key", key);
- if (isSelected(itemId)) {
- target.addAttribute("selected", true);
- selectedKeys[keyIndex++] = key;
- }
- if (areChildrenAllowed(itemId) && isExpanded(itemId)) {
- target.addAttribute("expanded", true);
- expandedKeys.add(key);
- }
-
- // Actions
- if (this.actionHandlers != null) {
- ArrayList keys = new ArrayList();
- for (Iterator ahi = this.actionHandlers.iterator(); ahi
- .hasNext();) {
- Action[] aa = ((Action.Handler) ahi.next()).getActions(
- itemId, this);
- if (aa != null) {
- for (int ai = 0; ai < aa.length; ai++) {
- String akey = this.actionMapper.key(aa[ai]);
- actionSet.add(aa[ai]);
- keys.add(akey);
- }
- }
- }
- target.addAttribute("al", keys.toArray());
- }
-
- // Adds the children if expanded, or close the tag
- if (isExpanded(itemId) && hasChildren(itemId)
- && areChildrenAllowed(itemId)) {
- iteratorStack.push(getChildren(itemId).iterator());
- } else {
- if (isNode) {
- target.endTag("node");
- } else {
- target.endTag("leaf");
- }
- }
- }
- }
-
- // Actions
- if (!actionSet.isEmpty()) {
- target.addVariable(this, "action", "");
- target.startTag("actions");
- for (Iterator i = actionSet.iterator(); i.hasNext();) {
- Action a = (Action) i.next();
- target.startTag("action");
- if (a.getCaption() != null) {
- target.addAttribute("caption", a.getCaption());
- }
- if (a.getIcon() != null) {
- target.addAttribute("icon", a.getIcon());
- }
- target.addAttribute("key", this.actionMapper.key(a));
- target.endTag("action");
- }
- target.endTag("actions");
- }
-
- if (this.partialUpdate) {
- this.partialUpdate = false;
- } else {
- // Selected
- target.addVariable(this, "selected", selectedKeys);
-
- // Expand and collapse
- target.addVariable(this, "expand", new String[] {});
- target.addVariable(this, "collapse", new String[] {});
-
- // New items
- target.addVariable(this, "newitem", new String[] {});
- }
- }
-
- /* Container.Hierarchical API ***************************************** */
-
- /**
- * Tests if the Item with given ID can have any children.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#areChildrenAllowed(Object)
- */
- public boolean areChildrenAllowed(Object itemId) {
- return ((Container.Hierarchical) this.items).areChildrenAllowed(itemId);
- }
-
- /**
- * Gets the IDs of all Items that are children of the specified Item.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#getChildren(Object)
- */
- public Collection getChildren(Object itemId) {
- return ((Container.Hierarchical) this.items).getChildren(itemId);
- }
-
- /**
- * Gets the ID of the parent Item of the specified Item.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#getParent(Object)
- */
- public Object getParent(Object itemId) {
- return ((Container.Hierarchical) this.items).getParent(itemId);
- }
-
- /**
- * Tests if the Item specified with <code>itemId</code> has any child
- * Items, that is, is it a leaf Item.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#hasChildren(Object)
- */
- public boolean hasChildren(Object itemId) {
- return ((Container.Hierarchical) this.items).hasChildren(itemId);
- }
-
- /**
- * Tests if the Item specified with <code>itemId</code> is a root Item.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#isRoot(Object)
- */
- public boolean isRoot(Object itemId) {
- return ((Container.Hierarchical) this.items).isRoot(itemId);
- }
-
- /**
- * Gets the IDs of all Items in the container that don't have a parent.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#rootItemIds()
- */
- public Collection rootItemIds() {
- return ((Container.Hierarchical) this.items).rootItemIds();
- }
-
- /**
- * Sets the given Item's capability to have children.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#setChildrenAllowed(Object,
- * boolean)
- */
- public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) {
- boolean success = ((Container.Hierarchical) this.items)
- .setChildrenAllowed(itemId, areChildrenAllowed);
- if (success) {
- fireValueChange(false);
- }
- return success;
- }
-
- /**
- * Sets the parent of an Item.
- *
- * @see com.itmill.toolkit.data.Container.Hierarchical#setParent(Object,
- * Object)
- */
- public boolean setParent(Object itemId, Object newParentId) {
- boolean success = ((Container.Hierarchical) this.items).setParent(
- itemId, newParentId);
- if (success) {
- requestRepaint();
- }
- return success;
- }
-
- /* Overriding select behavior******************************************** */
-
- /**
- * Sets the Container that serves as the data source of the viewer.
- *
- * @see com.itmill.toolkit.data.Container.Viewer#setContainerDataSource(Container)
- */
- public void setContainerDataSource(Container newDataSource) {
-
- // Assure that the data source is ordered by making unordered
- // containers ordered by wrapping them
- if (Container.Hierarchical.class.isAssignableFrom(newDataSource
- .getClass())) {
- super.setContainerDataSource(newDataSource);
- } else {
- super.setContainerDataSource(new ContainerHierarchicalWrapper(
- newDataSource));
- }
- }
-
- /* Expand event and listener ****************************************** */
-
- /**
- * Event to fired when a node is expanded. ExapandEvent is fired when a node
- * is to be expanded. it can me used to dynamically fill the sub-nodes of
- * the node.
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class ExpandEvent extends Component.Event {
-
- /**
- * Serial generated by eclipse.
- */
- private static final long serialVersionUID = 3832624001804481075L;
-
- private final Object expandedItemId;
-
- /**
- * New instance of options change event
- *
- * @param source
- * the Source of the event.
- * @param expandedItemId
- */
- public ExpandEvent(Component source, Object expandedItemId) {
- super(source);
- this.expandedItemId = expandedItemId;
- }
-
- /**
- * Node where the event occurred.
- *
- * @return the Source of the event.
- */
- public Object getItemId() {
- return this.expandedItemId;
- }
- }
-
- /**
- * Expand event listener.
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ExpandListener {
-
- /**
- * A node has been expanded.
- *
- * @param event
- * the Expand event.
- */
- public void nodeExpand(ExpandEvent event);
- }
-
- /**
- * Adds the expand listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(ExpandListener listener) {
- addListener(ExpandEvent.class, listener, EXPAND_METHOD);
- }
-
- /**
- * Removes the expand listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(ExpandListener listener) {
- removeListener(ExpandEvent.class, listener, EXPAND_METHOD);
- }
-
- /**
- * Emits the expand event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireExpandEvent(Object itemId) {
- fireEvent(new ExpandEvent(this, itemId));
- }
-
- /* Collapse event ****************************************** */
-
- /**
- * Collapse event
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class CollapseEvent extends Component.Event {
-
- /**
- * Serial generated by eclipse.
- */
- private static final long serialVersionUID = 3257009834783290160L;
-
- private final Object collapsedItemId;
-
- /**
- * New instance of options change event.
- *
- * @param source
- * the Source of the event.
- * @param collapsedItemId
- */
- public CollapseEvent(Component source, Object collapsedItemId) {
- super(source);
- this.collapsedItemId = collapsedItemId;
- }
-
- /**
- * Gets tge Collapsed Item id.
- *
- * @return the collapsed item id.
- */
- public Object getItemId() {
- return this.collapsedItemId;
- }
- }
-
- /**
- * Collapse event listener.
- *
- * @author IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface CollapseListener {
-
- /**
- * A node has been collapsed.
- *
- * @param event
- * the Collapse event.
- */
- public void nodeCollapse(CollapseEvent event);
- }
-
- /**
- * Adds the collapse listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(CollapseListener listener) {
- addListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
- }
-
- /**
- * Removes the collapse listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(CollapseListener listener) {
- removeListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
- }
-
- /**
- * Emits collapse event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireCollapseEvent(Object itemId) {
- fireEvent(new CollapseEvent(this, itemId));
- }
-
- /* Action container *************************************************** */
-
- /**
- * Adds an action handler.
- *
- * @see com.itmill.toolkit.event.Action.Container#addActionHandler(Action.Handler)
- */
- public void addActionHandler(Action.Handler actionHandler) {
-
- if (actionHandler != null) {
-
- if (this.actionHandlers == null) {
- this.actionHandlers = new LinkedList();
- this.actionMapper = new KeyMapper();
- }
-
- if (!this.actionHandlers.contains(actionHandler)) {
- this.actionHandlers.add(actionHandler);
- requestRepaint();
- }
- }
- }
-
- /**
- * Removes an action handler.
- *
- * @see com.itmill.toolkit.event.Action.Container#removeActionHandler(Action.Handler)
- */
- public void removeActionHandler(Action.Handler actionHandler) {
-
- if (this.actionHandlers != null
- && this.actionHandlers.contains(actionHandler)) {
-
- this.actionHandlers.remove(actionHandler);
-
- if (this.actionHandlers.isEmpty()) {
- this.actionHandlers = null;
- this.actionMapper = null;
- }
-
- requestRepaint();
- }
- }
-
- /**
- * Gets the visible item ids.
- *
- * @see com.itmill.toolkit.ui.Select#getVisibleItemIds()
- */
- public Collection getVisibleItemIds() {
-
- LinkedList visible = new LinkedList();
-
- // Iterates trough hierarchical tree using a stack of iterators
- Stack iteratorStack = new Stack();
- Collection ids = rootItemIds();
- if (ids != null) {
- iteratorStack.push(ids.iterator());
- }
- while (!iteratorStack.isEmpty()) {
-
- // Gets the iterator for current tree level
- Iterator i = (Iterator) iteratorStack.peek();
-
- // If the level is finished, back to previous tree level
- if (!i.hasNext()) {
-
- // Removes used iterator from the stack
- iteratorStack.pop();
- }
-
- // Adds the item on current level
- else {
- Object itemId = i.next();
-
- visible.add(itemId);
-
- // Adds children if expanded, or close the tag
- if (isExpanded(itemId) && hasChildren(itemId)) {
- iteratorStack.push(getChildren(itemId).iterator());
- }
- }
- }
-
- return visible;
- }
-
- /**
- * Tree does not support <code>setNullSelectionItemId</code>.
- *
- * @see com.itmill.toolkit.ui.AbstractSelect#setNullSelectionItemId(java.lang.Object)
- */
- public void setNullSelectionItemId(Object nullSelectionItemId)
- throws UnsupportedOperationException {
- if (nullSelectionItemId != null) {
- throw new UnsupportedOperationException();
- }
-
- }
-
- /**
- * Adding new items is not supported.
- *
- * @throws UnsupportedOperationException
- * if set to true.
- * @see com.itmill.toolkit.ui.Select#setNewItemsAllowed(boolean)
- */
- public void setNewItemsAllowed(boolean allowNewOptions)
- throws UnsupportedOperationException {
- if (allowNewOptions) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Focusing to this component is not supported.
- *
- * @throws UnsupportedOperationException
- * if invoked.
- * @see com.itmill.toolkit.ui.AbstractField#focus()
- */
- public void focus() throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Tree does not support lazy options loading mode. Setting this true will
- * throw UnsupportedOperationException.
- *
- * @see com.itmill.toolkit.ui.Select#setLazyLoading(boolean)
- */
- public void setLazyLoading(boolean useLazyLoading) {
- if (useLazyLoading) {
- throw new UnsupportedOperationException(
- "Lazy options loading is not supported by Tree.");
- }
- }
+ Action.Container {
+
+ /* Static members ***************************************************** */
+
+ private static final Method EXPAND_METHOD;
+
+ private static final Method COLLAPSE_METHOD;
+
+ static {
+ try {
+ EXPAND_METHOD = ExpandListener.class.getDeclaredMethod(
+ "nodeExpand", new Class[] { ExpandEvent.class });
+ COLLAPSE_METHOD = CollapseListener.class.getDeclaredMethod(
+ "nodeCollapse", new Class[] { CollapseEvent.class });
+ } catch (java.lang.NoSuchMethodException e) {
+ // This should never happen
+ e.printStackTrace();
+ throw new java.lang.RuntimeException(
+ "Internal error, please report");
+ }
+ }
+
+ /* Private members **************************************************** */
+
+ /**
+ * Set of expanded nodes.
+ */
+ private final HashSet expanded = new HashSet();
+
+ /**
+ * List of action handlers.
+ */
+ private LinkedList actionHandlers = null;
+
+ /**
+ * Action mapper.
+ */
+ private KeyMapper actionMapper = null;
+
+ /**
+ * Is the tree selectable .
+ */
+ private boolean selectable = true;
+
+ /**
+ * Flag to indicate sub-tree loading
+ */
+ private boolean partialUpdate = false;
+
+ /**
+ * Holds a itemId which was recently expanded
+ */
+ private Object expandedItemId;
+
+ /**
+ * a flag which indicates initial paint. After this flag set true partial
+ * updates are allowed.
+ */
+ private boolean initialPaint = true;
+
+ /* Tree constructors ************************************************** */
+
+ /**
+ * Creates a new empty tree.
+ */
+ public Tree() {
+ }
+
+ /**
+ * Creates a new empty tree with caption.
+ *
+ * @param caption
+ */
+ public Tree(String caption) {
+ setCaption(caption);
+ }
+
+ /**
+ * Creates a new tree with caption and connect it to a Container.
+ *
+ * @param caption
+ * @param dataSource
+ */
+ public Tree(String caption, Container dataSource) {
+ setCaption(caption);
+ setContainerDataSource(dataSource);
+ }
+
+ /* Expanding and collapsing ******************************************* */
+
+ /**
+ * Check is an item is expanded
+ *
+ * @param itemId
+ * the item id.
+ * @return true iff the item is expanded.
+ */
+ public boolean isExpanded(Object itemId) {
+ return expanded.contains(itemId);
+ }
+
+ /**
+ * Expands an item.
+ *
+ * @param itemId
+ * the item id.
+ * @return True iff the expand operation succeeded
+ */
+ public boolean expandItem(Object itemId) {
+ return expandItem(itemId, true);
+ }
+
+ /**
+ * Expands an item.
+ *
+ * @param itemId
+ * the item id.
+ * @param sendChildTree
+ * flag to indicate if client needs subtree or not (may be
+ * cached)
+ * @return True iff the expand operation succeeded
+ */
+ private boolean expandItem(Object itemId, boolean sendChildTree) {
+
+ // Succeeds if the node is already expanded
+ if (isExpanded(itemId)) {
+ return true;
+ }
+
+ // Nodes that can not have children are not expandable
+ if (!areChildrenAllowed(itemId)) {
+ return false;
+ }
+
+ // Expands
+ expanded.add(itemId);
+
+ expandedItemId = itemId;
+ if (initialPaint) {
+ requestRepaint();
+ } else if (sendChildTree) {
+ requestPartialRepaint();
+ }
+ fireExpandEvent(itemId);
+
+ return true;
+ }
+
+ public void requestRepaint() {
+ super.requestRepaint();
+ partialUpdate = false;
+ }
+
+ private void requestPartialRepaint() {
+ super.requestRepaint();
+ partialUpdate = true;
+ }
+
+ /**
+ * Expands the items recursively
+ *
+ * Expands all the children recursively starting from an item. Operation
+ * succeeds only if all expandable items are expanded.
+ *
+ * @param startItemId
+ * @return True iff the expand operation succeeded
+ */
+ public boolean expandItemsRecursively(Object startItemId) {
+
+ boolean result = true;
+
+ // Initial stack
+ Stack todo = new Stack();
+ todo.add(startItemId);
+
+ // Expands recursively
+ while (!todo.isEmpty()) {
+ Object id = todo.pop();
+ if (areChildrenAllowed(id) && !expandItem(id, false)) {
+ result = false;
+ }
+ if (hasChildren(id)) {
+ todo.addAll(getChildren(id));
+ }
+ }
+ requestRepaint();
+ return result;
+ }
+
+ /**
+ * Collapses an item.
+ *
+ * @param itemId
+ * the item id.
+ * @return True iff the collapse operation succeeded
+ */
+ public boolean collapseItem(Object itemId) {
+
+ // Succeeds if the node is already collapsed
+ if (!isExpanded(itemId)) {
+ return true;
+ }
+
+ // Collapse
+ expanded.remove(itemId);
+ requestRepaint();
+ fireCollapseEvent(itemId);
+
+ return true;
+ }
+
+ /**
+ * Collapses the items recursively.
+ *
+ * Collapse all the children recursively starting from an item. Operation
+ * succeeds only if all expandable items are collapsed.
+ *
+ * @param startItemId
+ * @return True iff the collapse operation succeeded
+ */
+ public boolean collapseItemsRecursively(Object startItemId) {
+
+ boolean result = true;
+
+ // Initial stack
+ Stack todo = new Stack();
+ todo.add(startItemId);
+
+ // Collapse recursively
+ while (!todo.isEmpty()) {
+ Object id = todo.pop();
+ if (areChildrenAllowed(id) && !collapseItem(id)) {
+ result = false;
+ }
+ if (hasChildren(id)) {
+ todo.addAll(getChildren(id));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Getter for property selectable.
+ *
+ * <p>
+ * The tree is selectable by default.
+ * </p>
+ *
+ * @return the Value of property selectable.
+ */
+ public boolean isSelectable() {
+ return selectable;
+ }
+
+ /**
+ * Setter for property selectable.
+ *
+ * <p>
+ * The tree is selectable by default.
+ * </p>
+ *
+ * @param selectable
+ * the New value of property selectable.
+ */
+ public void setSelectable(boolean selectable) {
+ if (this.selectable != selectable) {
+ this.selectable = selectable;
+ requestRepaint();
+ }
+ }
+
+ /* Component API ****************************************************** */
+
+ /**
+ * Gets the UIDL tag corresponding to the component.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponent#getTag()
+ */
+ public String getTag() {
+ return "tree";
+ }
+
+ /**
+ * Called when one or more variables handled by the implementing class are
+ * changed.
+ *
+ * @see com.itmill.toolkit.terminal.VariableOwner#changeVariables(Object
+ * source, Map variables)
+ */
+ public void changeVariables(Object source, Map variables) {
+
+ if (!isSelectable() && variables.containsKey("selected")) {
+ // Not-selectable is a special case, AbstractSelect does not support
+ // TODO could be optimized.
+ variables = new HashMap(variables);
+ variables.remove("selected");
+ }
+
+ // Collapses the nodes
+ if (variables.containsKey("collapse")) {
+ String[] keys = (String[]) variables.get("collapse");
+ for (int i = 0; i < keys.length; i++) {
+ Object id = itemIdMapper.get(keys[i]);
+ if (id != null && isExpanded(id)) {
+ expanded.remove(id);
+ fireCollapseEvent(id);
+ }
+ }
+ }
+
+ // Expands the nodes
+ if (variables.containsKey("expand")) {
+ boolean sendChildTree = false;
+ if (variables.containsKey("requestChildTree")) {
+ sendChildTree = true;
+ }
+ String[] keys = (String[]) variables.get("expand");
+ for (int i = 0; i < keys.length; i++) {
+ Object id = itemIdMapper.get(keys[i]);
+ if (id != null) {
+ expandItem(id, sendChildTree);
+ }
+ }
+ }
+
+ // Selections are handled by the select component
+ super.changeVariables(source, variables);
+
+ // Actions
+ if (variables.containsKey("action")) {
+
+ StringTokenizer st = new StringTokenizer((String) variables
+ .get("action"), ",");
+ if (st.countTokens() == 2) {
+ Object itemId = itemIdMapper.get(st.nextToken());
+ Action action = (Action) actionMapper.get(st.nextToken());
+ if (action != null && containsId(itemId)
+ && actionHandlers != null) {
+ for (Iterator i = actionHandlers.iterator(); i.hasNext();) {
+ ((Action.Handler) i.next()).handleAction(action, this,
+ itemId);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Paints any needed component-specific things to the given UIDL stream.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponent#paintContent(PaintTarget)
+ */
+ public void paintContent(PaintTarget target) throws PaintException {
+ initialPaint = false;
+
+ if (partialUpdate) {
+ target.addAttribute("partialUpdate", true);
+ target.addAttribute("rootKey", itemIdMapper.key(expandedItemId));
+ } else {
+
+ // Focus control id
+ if (getFocusableId() > 0) {
+ target.addAttribute("focusid", getFocusableId());
+ }
+
+ // The tab ordering number
+ if (getTabIndex() > 0) {
+ target.addAttribute("tabindex", getTabIndex());
+ }
+
+ // Paint tree attributes
+ if (isSelectable()) {
+ target.addAttribute("selectmode", (isMultiSelect() ? "multi"
+ : "single"));
+ } else {
+ target.addAttribute("selectmode", "none");
+ }
+ if (isNewItemsAllowed()) {
+ target.addAttribute("allownewitem", true);
+ }
+
+ if (isNullSelectionAllowed()) {
+ target.addAttribute("nullselect", true);
+ }
+
+ }
+
+ // Initialize variables
+ Set actionSet = new LinkedHashSet();
+ String[] selectedKeys;
+ if (isMultiSelect()) {
+ selectedKeys = new String[((Set) getValue()).size()];
+ } else {
+ selectedKeys = new String[(getValue() == null ? 0 : 1)];
+ }
+ int keyIndex = 0;
+ LinkedList expandedKeys = new LinkedList();
+
+ // Iterates through hierarchical tree using a stack of iterators
+ Stack iteratorStack = new Stack();
+ Collection ids;
+ if (partialUpdate) {
+ ids = getChildren(expandedItemId);
+ } else {
+ ids = rootItemIds();
+ }
+
+ if (ids != null) {
+ iteratorStack.push(ids.iterator());
+ }
+
+ while (!iteratorStack.isEmpty()) {
+
+ // Gets the iterator for current tree level
+ Iterator i = (Iterator) iteratorStack.peek();
+
+ // If the level is finished, back to previous tree level
+ if (!i.hasNext()) {
+
+ // Removes used iterator from the stack
+ iteratorStack.pop();
+
+ // Closes node
+ if (!iteratorStack.isEmpty()) {
+ target.endTag("node");
+ }
+ }
+
+ // Adds the item on current level
+ else {
+ Object itemId = i.next();
+
+ // Starts the item / node
+ boolean isNode = areChildrenAllowed(itemId)
+ && hasChildren(itemId);
+ if (isNode) {
+ target.startTag("node");
+ } else {
+ target.startTag("leaf");
+ }
+
+ // Adds the attributes
+ target.addAttribute("caption", getItemCaption(itemId));
+ Resource icon = getItemIcon(itemId);
+ if (icon != null) {
+ target.addAttribute("icon", getItemIcon(itemId));
+ }
+ String key = itemIdMapper.key(itemId);
+ target.addAttribute("key", key);
+ if (isSelected(itemId)) {
+ target.addAttribute("selected", true);
+ selectedKeys[keyIndex++] = key;
+ }
+ if (areChildrenAllowed(itemId) && isExpanded(itemId)) {
+ target.addAttribute("expanded", true);
+ expandedKeys.add(key);
+ }
+
+ // Actions
+ if (actionHandlers != null) {
+ ArrayList keys = new ArrayList();
+ for (Iterator ahi = actionHandlers.iterator(); ahi
+ .hasNext();) {
+ Action[] aa = ((Action.Handler) ahi.next()).getActions(
+ itemId, this);
+ if (aa != null) {
+ for (int ai = 0; ai < aa.length; ai++) {
+ String akey = actionMapper.key(aa[ai]);
+ actionSet.add(aa[ai]);
+ keys.add(akey);
+ }
+ }
+ }
+ target.addAttribute("al", keys.toArray());
+ }
+
+ // Adds the children if expanded, or close the tag
+ if (isExpanded(itemId) && hasChildren(itemId)
+ && areChildrenAllowed(itemId)) {
+ iteratorStack.push(getChildren(itemId).iterator());
+ } else {
+ if (isNode) {
+ target.endTag("node");
+ } else {
+ target.endTag("leaf");
+ }
+ }
+ }
+ }
+
+ // Actions
+ if (!actionSet.isEmpty()) {
+ target.addVariable(this, "action", "");
+ target.startTag("actions");
+ for (Iterator i = actionSet.iterator(); i.hasNext();) {
+ Action a = (Action) i.next();
+ target.startTag("action");
+ if (a.getCaption() != null) {
+ target.addAttribute("caption", a.getCaption());
+ }
+ if (a.getIcon() != null) {
+ target.addAttribute("icon", a.getIcon());
+ }
+ target.addAttribute("key", actionMapper.key(a));
+ target.endTag("action");
+ }
+ target.endTag("actions");
+ }
+
+ if (partialUpdate) {
+ partialUpdate = false;
+ } else {
+ // Selected
+ target.addVariable(this, "selected", selectedKeys);
+
+ // Expand and collapse
+ target.addVariable(this, "expand", new String[] {});
+ target.addVariable(this, "collapse", new String[] {});
+
+ // New items
+ target.addVariable(this, "newitem", new String[] {});
+ }
+ }
+
+ /* Container.Hierarchical API ***************************************** */
+
+ /**
+ * Tests if the Item with given ID can have any children.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#areChildrenAllowed(Object)
+ */
+ public boolean areChildrenAllowed(Object itemId) {
+ return ((Container.Hierarchical) items).areChildrenAllowed(itemId);
+ }
+
+ /**
+ * Gets the IDs of all Items that are children of the specified Item.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#getChildren(Object)
+ */
+ public Collection getChildren(Object itemId) {
+ return ((Container.Hierarchical) items).getChildren(itemId);
+ }
+
+ /**
+ * Gets the ID of the parent Item of the specified Item.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#getParent(Object)
+ */
+ public Object getParent(Object itemId) {
+ return ((Container.Hierarchical) items).getParent(itemId);
+ }
+
+ /**
+ * Tests if the Item specified with <code>itemId</code> has any child
+ * Items, that is, is it a leaf Item.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#hasChildren(Object)
+ */
+ public boolean hasChildren(Object itemId) {
+ return ((Container.Hierarchical) items).hasChildren(itemId);
+ }
+
+ /**
+ * Tests if the Item specified with <code>itemId</code> is a root Item.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#isRoot(Object)
+ */
+ public boolean isRoot(Object itemId) {
+ return ((Container.Hierarchical) items).isRoot(itemId);
+ }
+
+ /**
+ * Gets the IDs of all Items in the container that don't have a parent.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#rootItemIds()
+ */
+ public Collection rootItemIds() {
+ return ((Container.Hierarchical) items).rootItemIds();
+ }
+
+ /**
+ * Sets the given Item's capability to have children.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#setChildrenAllowed(Object,
+ * boolean)
+ */
+ public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) {
+ boolean success = ((Container.Hierarchical) items).setChildrenAllowed(
+ itemId, areChildrenAllowed);
+ if (success) {
+ fireValueChange(false);
+ }
+ return success;
+ }
+
+ /**
+ * Sets the parent of an Item.
+ *
+ * @see com.itmill.toolkit.data.Container.Hierarchical#setParent(Object,
+ * Object)
+ */
+ public boolean setParent(Object itemId, Object newParentId) {
+ boolean success = ((Container.Hierarchical) items).setParent(itemId,
+ newParentId);
+ if (success) {
+ requestRepaint();
+ }
+ return success;
+ }
+
+ /* Overriding select behavior******************************************** */
+
+ /**
+ * Sets the Container that serves as the data source of the viewer.
+ *
+ * @see com.itmill.toolkit.data.Container.Viewer#setContainerDataSource(Container)
+ */
+ public void setContainerDataSource(Container newDataSource) {
+
+ // Assure that the data source is ordered by making unordered
+ // containers ordered by wrapping them
+ if (Container.Hierarchical.class.isAssignableFrom(newDataSource
+ .getClass())) {
+ super.setContainerDataSource(newDataSource);
+ } else {
+ super.setContainerDataSource(new ContainerHierarchicalWrapper(
+ newDataSource));
+ }
+ }
+
+ /* Expand event and listener ****************************************** */
+
+ /**
+ * Event to fired when a node is expanded. ExapandEvent is fired when a node
+ * is to be expanded. it can me used to dynamically fill the sub-nodes of
+ * the node.
+ *
+ * @author IT Mill Ltd.
+ * @version
+ * @VERSION@
+ * @since 3.0
+ */
+ public class ExpandEvent extends Component.Event {
+
+ /**
+ * Serial generated by eclipse.
+ */
+ private static final long serialVersionUID = 3832624001804481075L;
+
+ private final Object expandedItemId;
+
+ /**
+ * New instance of options change event
+ *
+ * @param source
+ * the Source of the event.
+ * @param expandedItemId
+ */
+ public ExpandEvent(Component source, Object expandedItemId) {
+ super(source);
+ this.expandedItemId = expandedItemId;
+ }
+
+ /**
+ * Node where the event occurred.
+ *
+ * @return the Source of the event.
+ */
+ public Object getItemId() {
+ return expandedItemId;
+ }
+ }
+
+ /**
+ * Expand event listener.
+ *
+ * @author IT Mill Ltd.
+ * @version
+ * @VERSION@
+ * @since 3.0
+ */
+ public interface ExpandListener {
+
+ /**
+ * A node has been expanded.
+ *
+ * @param event
+ * the Expand event.
+ */
+ public void nodeExpand(ExpandEvent event);
+ }
+
+ /**
+ * Adds the expand listener.
+ *
+ * @param listener
+ * the Listener to be added.
+ */
+ public void addListener(ExpandListener listener) {
+ addListener(ExpandEvent.class, listener, EXPAND_METHOD);
+ }
+
+ /**
+ * Removes the expand listener.
+ *
+ * @param listener
+ * the Listener to be removed.
+ */
+ public void removeListener(ExpandListener listener) {
+ removeListener(ExpandEvent.class, listener, EXPAND_METHOD);
+ }
+
+ /**
+ * Emits the expand event.
+ *
+ * @param itemId
+ * the item id.
+ */
+ protected void fireExpandEvent(Object itemId) {
+ fireEvent(new ExpandEvent(this, itemId));
+ }
+
+ /* Collapse event ****************************************** */
+
+ /**
+ * Collapse event
+ *
+ * @author IT Mill Ltd.
+ * @version
+ * @VERSION@
+ * @since 3.0
+ */
+ public class CollapseEvent extends Component.Event {
+
+ /**
+ * Serial generated by eclipse.
+ */
+ private static final long serialVersionUID = 3257009834783290160L;
+
+ private final Object collapsedItemId;
+
+ /**
+ * New instance of options change event.
+ *
+ * @param source
+ * the Source of the event.
+ * @param collapsedItemId
+ */
+ public CollapseEvent(Component source, Object collapsedItemId) {
+ super(source);
+ this.collapsedItemId = collapsedItemId;
+ }
+
+ /**
+ * Gets tge Collapsed Item id.
+ *
+ * @return the collapsed item id.
+ */
+ public Object getItemId() {
+ return collapsedItemId;
+ }
+ }
+
+ /**
+ * Collapse event listener.
+ *
+ * @author IT Mill Ltd.
+ * @version
+ * @VERSION@
+ * @since 3.0
+ */
+ public interface CollapseListener {
+
+ /**
+ * A node has been collapsed.
+ *
+ * @param event
+ * the Collapse event.
+ */
+ public void nodeCollapse(CollapseEvent event);
+ }
+
+ /**
+ * Adds the collapse listener.
+ *
+ * @param listener
+ * the Listener to be added.
+ */
+ public void addListener(CollapseListener listener) {
+ addListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
+ }
+
+ /**
+ * Removes the collapse listener.
+ *
+ * @param listener
+ * the Listener to be removed.
+ */
+ public void removeListener(CollapseListener listener) {
+ removeListener(CollapseEvent.class, listener, COLLAPSE_METHOD);
+ }
+
+ /**
+ * Emits collapse event.
+ *
+ * @param itemId
+ * the item id.
+ */
+ protected void fireCollapseEvent(Object itemId) {
+ fireEvent(new CollapseEvent(this, itemId));
+ }
+
+ /* Action container *************************************************** */
+
+ /**
+ * Adds an action handler.
+ *
+ * @see com.itmill.toolkit.event.Action.Container#addActionHandler(Action.Handler)
+ */
+ public void addActionHandler(Action.Handler actionHandler) {
+
+ if (actionHandler != null) {
+
+ if (actionHandlers == null) {
+ actionHandlers = new LinkedList();
+ actionMapper = new KeyMapper();
+ }
+
+ if (!actionHandlers.contains(actionHandler)) {
+ actionHandlers.add(actionHandler);
+ requestRepaint();
+ }
+ }
+ }
+
+ /**
+ * Removes an action handler.
+ *
+ * @see com.itmill.toolkit.event.Action.Container#removeActionHandler(Action.Handler)
+ */
+ public void removeActionHandler(Action.Handler actionHandler) {
+
+ if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
+
+ actionHandlers.remove(actionHandler);
+
+ if (actionHandlers.isEmpty()) {
+ actionHandlers = null;
+ actionMapper = null;
+ }
+
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Gets the visible item ids.
+ *
+ * @see com.itmill.toolkit.ui.Select#getVisibleItemIds()
+ */
+ public Collection getVisibleItemIds() {
+
+ LinkedList visible = new LinkedList();
+
+ // Iterates trough hierarchical tree using a stack of iterators
+ Stack iteratorStack = new Stack();
+ Collection ids = rootItemIds();
+ if (ids != null) {
+ iteratorStack.push(ids.iterator());
+ }
+ while (!iteratorStack.isEmpty()) {
+
+ // Gets the iterator for current tree level
+ Iterator i = (Iterator) iteratorStack.peek();
+
+ // If the level is finished, back to previous tree level
+ if (!i.hasNext()) {
+
+ // Removes used iterator from the stack
+ iteratorStack.pop();
+ }
+
+ // Adds the item on current level
+ else {
+ Object itemId = i.next();
+
+ visible.add(itemId);
+
+ // Adds children if expanded, or close the tag
+ if (isExpanded(itemId) && hasChildren(itemId)) {
+ iteratorStack.push(getChildren(itemId).iterator());
+ }
+ }
+ }
+
+ return visible;
+ }
+
+ /**
+ * Tree does not support <code>setNullSelectionItemId</code>.
+ *
+ * @see com.itmill.toolkit.ui.AbstractSelect#setNullSelectionItemId(java.lang.Object)
+ */
+ public void setNullSelectionItemId(Object nullSelectionItemId)
+ throws UnsupportedOperationException {
+ if (nullSelectionItemId != null) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+ /**
+ * Adding new items is not supported.
+ *
+ * @throws UnsupportedOperationException
+ * if set to true.
+ * @see com.itmill.toolkit.ui.Select#setNewItemsAllowed(boolean)
+ */
+ public void setNewItemsAllowed(boolean allowNewOptions)
+ throws UnsupportedOperationException {
+ if (allowNewOptions) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Focusing to this component is not supported.
+ *
+ * @throws UnsupportedOperationException
+ * if invoked.
+ * @see com.itmill.toolkit.ui.AbstractField#focus()
+ */
+ public void focus() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Tree does not support lazy options loading mode. Setting this true will
+ * throw UnsupportedOperationException.
+ *
+ * @see com.itmill.toolkit.ui.Select#setLazyLoading(boolean)
+ */
+ public void setLazyLoading(boolean useLazyLoading) {
+ if (useLazyLoading) {
+ throw new UnsupportedOperationException(
+ "Lazy options loading is not supported by Tree.");
+ }
+ }
}