
com.extjs.gxt.ui.client.store.TreeStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gxt Show documentation
Show all versions of gxt Show documentation
Rich Internet Application Framework for GWT
/*
* Sencha GXT 2.3.1 - Sencha for GWT
* Copyright(c) 2007-2013, Sencha, Inc.
* [email protected]
*
* http://www.sencha.com/products/gxt/license/
*/
package com.extjs.gxt.ui.client.store;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.core.FastMap;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.data.ChangeEvent;
import com.extjs.gxt.ui.client.data.ChangeEventSource;
import com.extjs.gxt.ui.client.data.ListLoadConfig;
import com.extjs.gxt.ui.client.data.LoadEvent;
import com.extjs.gxt.ui.client.data.Loader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RemoteSortTreeLoader;
import com.extjs.gxt.ui.client.data.SortInfo;
import com.extjs.gxt.ui.client.data.TreeLoadEvent;
import com.extjs.gxt.ui.client.data.TreeLoader;
import com.extjs.gxt.ui.client.data.TreeModel;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.LoadListener;
import com.extjs.gxt.ui.client.util.Util;
/**
* A store for hierarchical data.
*
*
* The parent child relationships are handled internally by the store. It is
* important to note that the store does not use the the parent and children of
* any TreeModel instances added to the store.
*
*
* It is important to note the sorting behavior when working with TreeStore.
* When a sorter is set, it is applied to all existing models in the cache and
* the Sort event is fired. At this point, the sorter is enabled and active.
*
*
* Remote sorting is not supported with TreeStore.
*
*
* - Events:
* - Store.BeforeDataChanged : TreeStoreEvent(store)
* Fires before the store's data is changed. Apply applies when a store is
* bound to a loader.
*
* - store : this
*
*
*
* - Store.DataChange : TreeStoreEvent(store)
* Fires when the data cache has changed, and a widget which is using this
* Store as a Model cache should refresh its view.
*
* - store : this
*
*
*
* - Store.Filter : TreeStoreEvent(store)
* Fires when filters are applied and removed from the store.
*
* - store : this
*
*
*
* - Store.Add : TreeStoreEvent(store, parent, child)
* Fires when models have been added to the store.
*
* - store : this
* - parent : the parent
* - children : this list of model(s) added
* - index : the insert index
*
*
*
* - Store.Remove : TreeStoreEvent(store, parent, child)
* Fires when a model has been removed from the store.
*
* - store : this
* - parent : the parent
* - child : the removed child
* - children : all the children (deep) of the removed item
*
*
*
* - Store.Update : TreeStoreEvent(store, model, record)
* Fires when a model has been updated via its record.
*
* - store : this
* - model : the model that was updated
* - record : the record that was updated
* - operation : the update operation being performed.
*
*
*
* - Store.Clear : TreeStoreEvent(store)
* Fires when the data cache has been cleared.
*
* - store : this
*
*
*
* - Store.Sort : TreeStoreEvent(store)
* Fires after a sorter is applied to the store.
*
* - store : this
*
*
*
*
*/
public class TreeStore extends Store {
protected TreeLoader loader;
protected Map modelFastMap;
protected Map modelMap;
protected BaseTreeModel rootWrapper = new BaseTreeModel();
protected Map wrapperMap = new FastMap();
private int counter = 0;
private Boolean useKeyProvider = null;
/**
* Creates a new tree store.
*/
public TreeStore() {
super();
}
/**
* Creates a new tree store.
*
* @param loader the tree loader
*/
public TreeStore(TreeLoader loader) {
this.loader = loader;
loader.addLoadListener(new LoadListener() {
public void loaderBeforeLoad(LoadEvent le) {
onBeforeLoad(le);
}
public void loaderLoad(LoadEvent le) {
onLoad((TreeLoadEvent) le);
}
public void loaderLoadException(LoadEvent le) {
onLoadException(le);
}
});
}
/**
* Adds the models to the root of the store and fires the Add event.
*
* @param models the models to be added
* @param addChildren true to recursively add all children
*/
public void add(List models, boolean addChildren) {
insert(models, rootWrapper.getChildCount(), addChildren);
}
/**
* Adds the items to the store and fires the Add event.
*
* @param item the item to add
* @param addChildren true to recursively add all children
*/
@SuppressWarnings("unchecked")
public void add(M item, boolean addChildren) {
add(Util.createList(item), addChildren);
}
/**
* Adds the models to the given parent and fires the Add event.
*
* @param parent the parent
* @param children the children
* @param addChildren true to recursively add all children
*/
public void add(M parent, List children, boolean addChildren) {
insert(parent, children, getChildCount(parent), addChildren);
}
/**
* Adds the child to the parent and fires the Add event.
*
* @param parent the parent item
* @param item the child item
* @param addChildren true to recursively add all children
*/
public void add(M parent, M item, boolean addChildren) {
insert(parent, item, getChildCount(parent), addChildren);
}
@Override
public void applyFilters(String property) {
filterProperty = property;
filtersEnabled = true;
filterTreeWrap(rootWrapper);
fireEvent(Filter, createStoreEvent());
}
@Override
public void clearFilters() {
if (isFiltered()) {
filtersEnabled = false;
snapshot = null;
for (M m : all) {
TreeModel wrap = findWrapper(m);
wrap.remove("filtered");
}
fireEvent(Filter, createStoreEvent());
}
}
/**
* Returns all the stores items. The items are not returned in any order.
*
* @return the items
*/
public List getAllItems() {
return all;
}
/**
* Returns the root level child.
*
* @param index the index
* @return the child
*/
public M getChild(int index) {
return getFilteredChildren(rootWrapper).get(index);
}
/**
* Returns the child at the given index.
*
* @param parent the parent model or null if parent is root
* @param index the index
* @return the child of the parent at the given index
*/
public M getChild(M parent, int index) {
if (parent == null) {
return getFilteredChildren(rootWrapper).get(index);
}
TreeModel p = findWrapper(parent);
if (p != null) {
return getFilteredChildren(p).get(index);
}
return null;
}
/**
* Returns the root level child count.
*
* @return the child count
*/
public int getChildCount() {
return getRootItems().size();
}
/**
* Returns the child count for the parent.
*
* @param parent the parent
* @return the child count or -1 if parent not found in the store
*/
public int getChildCount(M parent) {
if (parent == null) {
return getChildCount();
} else {
TreeModel p = findWrapper(parent);
if (p != null) {
return getFilteredChildren(p).size();
}
return -1;
}
}
/**
* Returns the children of the parent.
*
* @param parent the parent
* @return the children or null if parent not found in the store
*/
public List getChildren(M parent) {
return getChildren(parent, false);
}
/**
* Returns the children of the parent.
*
* @param parent the parent
* @param deep true to return all children recursively
* @return the children or null if parent not found in the store
*/
public List getChildren(M parent, boolean deep) {
TreeModel p = findWrapper(parent);
if (p != null) {
if (deep) {
List temp = new ArrayList();
List children = getFilteredChildren(p);
for (M child : children) {
temp.add(child);
temp.addAll(getChildren(child, true));
}
return temp;
} else {
return getFilteredChildren(p);
}
}
return null;
}
/**
* Returns the depth of the item.
*
* @param item the item
* @return the item's depth
*/
public int getDepth(M item) {
int depth = 0;
while (item != null) {
depth++;
item = getParent(item);
}
return depth;
}
/**
* Returns the fist child of the parent.
*
* @param parent the parent
* @return the first child or null if no children
*/
public M getFirstChild(M parent) {
List children = parent == null ? getRootItems() : getChildren(parent);
if (children != null && children.size() > 0) {
return children.get(0);
}
return null;
}
/**
* Returns the last child of the parent.
*
* @param parent the parent
* @return the last child of null if no children
*/
public M getLastChild(M parent) {
List children = parent == null ? getRootItems() : getChildren(parent);
if (children != null && children.size() > 0) {
return children.get(children.size() - 1);
}
return null;
}
/**
* Returns the store's loader.
*
* @return the loader
*/
public TreeLoader getLoader() {
return loader;
}
/**
* Returns the parent-child relationships for the given model. The actual
* model can be retrieved in each TreeModel's "model" property using the
* {@link TreeStoreModel#getModel()} method. The children of each tree model
* contains tree model instances which wrap the actual child model.
*
* @param model the model
* @return the model and it's children
*/
public TreeStoreModel getModelState(M model) {
TreeStoreModel tm = new TreeStoreModel(model);
int count = getChildCount(model);
for (int i = 0; i < count; i++) {
tm.add(getModelState(getChild(model, i)));
}
return tm;
}
/**
* Returns the next sibling of the model.
*
* @param item the model
* @return the next sibling or null
*/
public M getNextSibling(M item) {
M parent = getParent(item);
List children = parent == null ? getRootItems() : getChildren(parent);
int index = children.indexOf(item);
if (children.size() > (index + 1)) {
return children.get(index + 1);
}
return null;
}
/**
* Returns the parent of the item.
*
* @param item the item
* @return the item's parent
*/
public M getParent(M item) {
TreeModel child = findWrapper(item);
if (child != null) {
TreeModel p = child.getParent();
if (p != null) {
return unwrap(p);
}
}
return null;
}
/**
* Returns the item's previous sibling.
*
* @param item the item
* @return the previous sibling
*/
public M getPreviousSibling(M item) {
M parent = getParent(item);
List children = parent == null ? getRootItems() : getChildren(parent);
int index = children.indexOf(item);
if (index > 0) {
return children.get(index - 1);
}
return null;
}
/**
* Returns the root level items.
*
* @return the items
*/
public List getRootItems() {
return unwrapChildren(rootWrapper);
}
/**
* Returns the current sort state of this store.
*
* @return the sort state
*/
public SortInfo getSortState() {
return sortInfo;
}
/**
* Returns true if the given parent model has any children.
*
* @param parent the parent model
* @return true if the given parent model has any children
*/
public boolean hasChildren(M parent) {
if (parent == null) {
return rootWrapper.getChildCount() > 0;
} else {
TreeModel p = findWrapper(parent);
if (p != null) {
for (ModelData child : p.getChildren()) {
if (!isFiltered((TreeModel) child)) {
return true;
}
}
}
}
return false;
}
/**
* Returns the item's index in it's parent including root level items.
*
* @param item the item
* @return the index
*/
public int indexOf(M item) {
M parent = getParent(item);
if (parent == null) {
return getRootItems().indexOf(item);
} else {
return getChildren(parent).indexOf(item);
}
}
/**
* Inserts the models into the store and fires the Add event.
*
* @param models the models to insert
* @param index the insert index
* @param addChildren true to recursively add all children
*/
public void insert(List models, int index, boolean addChildren) {
List insert = new ArrayList();
for (M model : models) {
insert.add(wrap(model));
}
doInsert(rootWrapper, insert, index, addChildren, false);
}
/**
* Adds the item to the store and fires the Add event.
*
* @param item the item to insert
* @param index the insert index
* @param addChildren true to recursively add all children
*/
@SuppressWarnings("unchecked")
public void insert(M item, int index, boolean addChildren) {
doInsert(rootWrapper, Util.createList(wrap(item)), index, addChildren, false);
}
/**
* Inserts the children to the parent and fires the Add event.
*
* @param parent the parent
* @param children the children
* @param index the insert index
* @param addChildren true to recursively add all children
*/
public void insert(M parent, List children, int index, boolean addChildren) {
TreeModel wrapper = findWrapper(parent);
if (wrapper != null) {
List insert = new ArrayList();
for (M model : children) {
insert.add(wrap(model));
}
doInsert(wrapper, insert, index, addChildren, false);
}
}
/**
* Adds the child to the parent and fires the Add event.
*
* @param parent the parent model
* @param model the child model
* @param index the insert index
* @param addChildren true to recursively add all children
*/
@SuppressWarnings("unchecked")
public void insert(M parent, M model, int index, boolean addChildren) {
insert(parent, Util.createList(model), index, addChildren);
}
/**
* Removes the model from the store and fires the Remove event. Works
* with both regular and root nodes.
*
* @param model the item to be removed
*/
public void remove(M model) {
M parent = getParent(model);
if (parent == null) {
remove(rootWrapper, findWrapper(model), false);
} else {
remove(parent, model);
}
}
/**
* Removes the child from the parent and fires the Remove event.
*
* @param parent the parent model
* @param child the child model
*/
public void remove(M parent, M child) {
TreeModel p = findWrapper(parent);
TreeModel c = findWrapper(child);
if (p != null && c != null) {
remove(p, c, false);
}
}
@Override
public void removeAll() {
removeAll(false);
}
/**
* Removes all the parent's children.
*
* @param parent the parent
*/
public void removeAll(M parent) {
TreeModel p = findWrapper(parent);
if (p != null) {
List children = getChildren(parent);
for (M m : children) {
TreeModel child = findWrapper(m);
if (child != null) {
remove(p, child, false);
}
}
}
}
/**
* Sets the current sort info used when sorting items in the store.
*
* @param info the sort info
*/
public void setSortInfo(SortInfo info) {
this.sortInfo = info;
}
@Override
public void setStoreSorter(StoreSorter storeSorter) {
super.setStoreSorter(storeSorter);
applySort(false);
}
/**
* Sorts the store.
*
* @param field the field to sort by
* @param sortDir the sort dir
*/
@SuppressWarnings("rawtypes")
public void sort(String field, SortDir sortDir) {
final StoreEvent event = createStoreEvent();
event.setSortInfo(new SortInfo(field, sortDir));
if (!fireEvent(BeforeSort, event)) {
return;
}
SortInfo prev = new SortInfo(sortInfo.getSortField(), sortInfo.getSortDir());
if (sortDir == null) {
if (sortInfo.getSortField() != null && !sortInfo.getSortField().equals(field)) {
sortInfo.setSortDir(SortDir.NONE);
}
switch (sortInfo.getSortDir()) {
case ASC:
sortDir = SortDir.DESC;
break;
case DESC:
case NONE:
sortDir = SortDir.ASC;
break;
}
}
sortInfo.setSortField(field);
sortInfo.setSortDir(sortDir);
if (loader != null && loader instanceof RemoteSortTreeLoader) {
final RemoteSortTreeLoader treeLoader = (RemoteSortTreeLoader) loader;
if (treeLoader.isRemoteSort()) {
Listener l = new Listener() {
public void handleEvent(LoadEvent le) {
treeLoader.removeListener(Loader.Load, this);
sortInfo = le. getConfig().getSortInfo();
event.setSortInfo(sortInfo);
fireEvent(Sort, createStoreEvent());
}
};
treeLoader.addListener(Loader.Load, l);
treeLoader.setSortDir(sortDir);
treeLoader.setSortField(field);
if (!treeLoader.load()) {
treeLoader.removeListener(Loader.Load, l);
sortInfo.setSortField(prev.getSortField());
sortInfo.setSortDir(prev.getSortDir());
}
return;
}
}
applySort(false);
fireEvent(DataChanged, createStoreEvent());
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
protected void applySort(boolean supressEvent) {
List children = (List) rootWrapper.getChildren();
if (children.size() > 0) {
applySort(children);
}
if (useKeyProvider != null) {
Collection collection = useKeyProvider ? modelFastMap.values() : modelMap.values();
for (TreeModel wrapper : collection) {
children = (List) wrapper.getChildren();
if (children.size() > 0) {
applySort(children);
}
}
}
if (!supressEvent) {
StoreEvent event = createStoreEvent();
event.setSortInfo(sortInfo);
fireEvent(Sort, event);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected void applySort(List list) {
storeSorter = storeSorter == null ? new StoreSorter() : storeSorter;
Collections.sort(list, new Comparator() {
public int compare(TreeModel m1, TreeModel m2) {
return storeSorter.compare(TreeStore.this, unwrap(m1), unwrap(m2), sortInfo.getSortField());
}
});
if (sortInfo.getSortDir() == SortDir.DESC) {
Collections.reverse(list);
}
}
@Override
protected TreeStoreEvent createStoreEvent() {
return new TreeStoreEvent(this);
}
protected TreeModel findWrapper(M item) {
if (item != null) {
if (useKeyProvider != null) {
if (useKeyProvider) {
return modelFastMap.get(getKey(item));
}
return modelMap.get(item);
}
}
return null;
}
protected void onBeforeLoad(LoadEvent le) {
if (!le.isCancelled() && !fireEvent(BeforeDataChanged, createStoreEvent())) {
le.setCancelled(true);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected void onLoad(TreeLoadEvent le) {
if (le.parent == null) {
removeAll(true);
List insert = new ArrayList();
for (M model : (List) le.getData()) {
insert.add(wrap(model));
}
Object obj = le.getConfig();
if (obj != null && obj instanceof ListLoadConfig) {
ListLoadConfig config = le.getConfig();
if (config.getSortInfo().getSortField() != null) {
sortInfo = config.getSortInfo();
} else {
sortInfo = new SortInfo();
}
}
doInsert(rootWrapper, insert, 0, false, true);
if (filtersEnabled) {
filtersEnabled = false;
applyFilters(filterProperty);
} else {
fireEvent(DataChanged, new TreeStoreEvent(this));
}
} else {
TreeModel wrapper = findWrapper((M) le.parent);
if (wrapper != null) {
if (wrapper.getChildren().size() > 0) {
removeAll((M) le.parent);
}
List insert = new ArrayList();
List list = (List) le.getData();
for (M model : list) {
insert.add(wrap(model));
}
doInsert(wrapper, insert, 0, false, true);
if (filtersEnabled) {
filtersEnabled = false;
applyFilters(filterProperty);
} else {
TreeStoreEvent evt = new TreeStoreEvent(this);
evt.setParent(le.parent);
evt.setChildren(unwrapChildren(wrapper));
fireEvent(DataChanged, evt);
}
}
}
}
protected void onLoadException(LoadEvent le) {
}
@SuppressWarnings("unchecked")
@Override
protected void onModelChange(ChangeEvent ce) {
super.onModelChange(ce);
switch (ce.getType()) {
case ChangeEventSource.Add: {
if (ce.getSource() == ce.getParent()) {
M parent = (M) ce.getParent();
M child = (M) ce.getItem();
insert(parent, child, ce.getIndex(), false);
}
break;
}
case ChangeEventSource.Remove: {
if (ce.getSource() == ce.getParent()) {
M parent = (M) ce.getParent();
M child = (M) ce.getItem();
remove(parent, child);
}
break;
}
}
}
protected void swapModelInstance(M oldModel, M newModel) {
super.swapModelInstance(oldModel, newModel);
if (useKeyProvider != null) {
TreeModel wrapper = null;
if (useKeyProvider) {
wrapper = modelFastMap.get(getKey(oldModel));
} else {
wrapper = modelMap.get(oldModel);
}
if (wrapper != null) {
wrapperMap.put(wrapper. get("id"), newModel);
if (!useKeyProvider && modelMap != null) {
modelMap.remove(oldModel);
modelMap.put(newModel, wrapper);
}
}
}
}
protected List unwrap(List models) {
List children = new ArrayList();
if (isFiltered()) {
for (TreeModel child : models) {
if (!"true".equals(child.get("filtered"))) {
children.add(unwrap(child));
}
}
} else {
for (TreeModel child : models) {
children.add(unwrap(child));
}
}
return children;
}
protected M unwrap(TreeModel wrapper) {
return wrapperMap.get(wrapper. get("id"));
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected List unwrapChildren(TreeModel parent) {
return unwrap((List) parent.getChildren());
}
protected TreeModel wrap(M model) {
if (useKeyProvider == null) {
if (getKeyProvider() == null) {
modelMap = new HashMap();
useKeyProvider = false;
} else {
modelFastMap = new FastMap();
useKeyProvider = true;
}
}
TreeModel wrapper = new BaseTreeModel();
wrapper.set("id", String.valueOf(counter++));
if (useKeyProvider) {
modelFastMap.put(getKey(model), wrapper);
} else {
modelMap.put(model, wrapper);
}
wrapperMap.put(wrapper. get("id"), model);
return wrapper;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void doInsert(TreeModel parent, List children, int index, boolean addChildren, boolean supressEvent) {
if (parent != null && children != null && children.size() > 0) {
M modelParent = unwrap(parent);
for (int i = children.size() - 1; i >= 0; i--) {
TreeModel child = children.get(i);
parent.insert(child, index);
M m = unwrap(child);
all.add(m);
registerModel(m);
if (storeSorter != null) {
applySort((List) parent.getChildren());
if (!supressEvent) {
TreeStoreEvent evt = createStoreEvent();;
evt.setParent(modelParent);
evt.setIndex(parent.indexOf(child));
evt.setChildren(Arrays.asList(m));
fireEvent(Add, evt);
}
}
}
if (!supressEvent && storeSorter == null) {
TreeStoreEvent evt = createStoreEvent();;
evt.setParent(modelParent);
evt.setChildren(unwrap(children));
evt.setIndex(index);
fireEvent(Add, evt);
}
if (addChildren) {
for (TreeModel sub : children) {
M model = unwrap(sub);
if (model instanceof TreeModel) {
TreeModel treeSub = (TreeModel) model;
List c = (List) treeSub.getChildren();
if (c.size() > 0) {
List insert = new ArrayList();
for (M m : c) {
insert.add(wrap(m));
}
doInsert(sub, insert, getChildCount(model), true, supressEvent);
update(model);
}
}
}
}
}
}
private void filterTreeWrap(TreeModel wrap) {
List children = wrap.getChildren();
for (int i = 0, len = children.size(); i < len; i++) {
TreeModel tm = (TreeModel) children.get(i);
if (isOrDecendantSelected(tm, unwrap(tm))) {
tm.set("filtered", "false");
} else {
tm.set("filtered", "true");
}
filterTreeWrap(tm);
}
}
private void findChildren(M parent, List children) {
for (M child : getChildren(parent)) {
children.add(child);
findChildren(child, children);
}
}
private List getFilteredChildren(TreeModel wrap) {
List filtered = new ArrayList();
for (ModelData child : wrap.getChildren()) {
if (!isFiltered((TreeModel) child)) {
filtered.add((TreeModel) child);
}
}
return unwrap(filtered);
}
private String getKey(M model) {
return getKeyProvider().getKey(model);
}
private boolean isFiltered(TreeModel wrap) {
return "true".equals(wrap.get("filtered"));
}
private boolean isOrDecendantSelected(TreeModel wrap, M model) {
if (!isFiltered(model, filterProperty)) {
return true;
}
List children = wrap.getChildren();
for (int i = 0, len = children.size(); i < len; i++) {
TreeModel tm = (TreeModel) children.get(i);
boolean result = isOrDecendantSelected(tm, unwrap(tm));
if (result) {
return true;
}
}
return false;
}
private void remove(TreeModel parent, TreeModel child, boolean supressEvent) {
int index = parent.getChildren().indexOf(child);
if (index != -1) {
parent.remove(child);
M model = unwrap(child);
List children = new ArrayList();
findChildren(model, children);
for (M c : children) {
all.remove(c);
wrapperMap.remove(findWrapper(c). get("id"));
if (useKeyProvider) {
modelFastMap.remove(getKey(c));
} else {
modelMap.remove(c);
}
modified.remove(recordMap.get(c));
unregisterModel(c);
}
all.remove(model);
wrapperMap.remove(child. get("id"));
if (useKeyProvider) {
modelFastMap.remove(getKey(model));
} else {
modelMap.remove(model);
}
modified.remove(recordMap.get(model));
unregisterModel(model);
if (!supressEvent) {
TreeStoreEvent evt = new TreeStoreEvent(this);
evt.setParent(unwrap(parent));
evt.setChild(model);
evt.setChildren(children);
evt.setIndex(index);
fireEvent(Remove, evt);
}
}
}
private void removeAll(boolean supressEvent) {
for (M m : all) {
unregisterModel(m);
}
all.clear();
modified.clear();
recordMap.clear();
if (modelMap != null) {
modelMap.clear();
} else if (modelFastMap != null) {
modelFastMap.clear();
}
wrapperMap.clear();
rootWrapper.removeAll();
if (!supressEvent) {
fireEvent(Clear, createStoreEvent());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy