📄 abstractcomponent.java
字号:
invalidate(); } } //-- in the redrawing phase --// /** Includes the page returned by {@link #getMoldURI} and * set the self attribute to be this component. */ public void redraw(Writer out) throws IOException { final String mold = getMoldURI(); if (D.ON && log.finerable()) log.finer("Redraw comp: "+this+" with "+mold); final Map attrs = new HashMap(3); attrs.put("self", this); _desktop.getExecution() .include(out, mold, attrs, Execution.PASS_THRU_ATTR); } /* Default: does nothing. */ public void onDrawNewChild(Component child, StringBuffer out) throws IOException { } public boolean addEventListener(String evtnm, EventListener listener) { if (evtnm == null || listener == null) throw new IllegalArgumentException("null"); if (!Events.isValid(evtnm)) throw new IllegalArgumentException("Invalid event name: "+evtnm); if (_listeners == null) _listeners = new HashMap(); List l = (List)_listeners.get(evtnm); if (l != null) { for (Iterator it = l.iterator(); it.hasNext();) { final EventListener li = (EventListener)it.next(); if (listener.equals(li)) return false; } } else { _listeners.put(evtnm, l = new LinkedList()); } l.add(listener); checkRootEvents(evtnm); return true; } /** Checks special events for root components. * * @param evtnm which event is changed. If null, it means all have to check. */ private void checkRootEvents(String evtnm) { if (_desktop != null && _parent == null) { if ((evtnm == null || Events.ON_CLIENT_INFO.equals(evtnm)) && Events.isListenerAvailable(this, Events.ON_CLIENT_INFO, true)) response("clientInfo", new AuClientInfo()); } } public boolean removeEventListener(String evtnm, EventListener listener) { if (evtnm == null || listener == null) throw new IllegalArgumentException("null"); if (_listeners != null) { final List l = (List)_listeners.get(evtnm); if (l != null) { for (Iterator it = l.iterator(); it.hasNext();) { final EventListener li = (EventListener)it.next(); if (listener.equals(li)) { if (l.size() == 1) _listeners.remove(evtnm); else it.remove(); return true; } } } } return false; } public Class getClass(String clsnm) throws ClassNotFoundException { return getNamespace().getClass(clsnm); } public Namespace getNamespace() { if (this instanceof IdSpace) return _spaceInfo.ns; final IdSpace idspace = getSpaceOwner(); return idspace instanceof Page ? ((Page)idspace).getNamespace(): idspace == null ? null: ((Component)idspace).getNamespace(); } public boolean isListenerAvailable(String evtnm, boolean asap) { if (_listeners != null) { final List l = (List)_listeners.get(evtnm); if (l != null) { if (!asap) return !l.isEmpty(); for (Iterator it = l.iterator(); it.hasNext();) { final EventListener li = (EventListener)it.next(); if (li.isAsap()) return true; } } } return false; } public Iterator getListenerIterator(String evtnm) { if (_listeners != null) { final List l = (List)_listeners.get(evtnm); if (l != null) return l.iterator(); } return CollectionsX.EMPTY_ITERATOR; } public void applyProperties() { _mill.applyProperties(this); } //-- ComponentCtrl --// public Milieu getMilieu() { return _mill; } public Annotation getAnnotation(String annotName) { return annotmap().getAnnotation(annotName); } public Annotation getAnnotation(String propName, String annotName) { return annotmap().getAnnotation(propName, annotName); } public Collection getAnnotations() { return annotmap().getAnnotations(); } public Collection getAnnotations(String propName) { return annotmap().getAnnotations(propName); } public List getAnnotatedPropertiesBy(String annotName) { return annotmap().getAnnotatedPropertiesBy(annotName); } public List getAnnotatedProperties() { return annotmap().getAnnotatedProperties(); } public void addAnnotation(String annotName, Map annotAttrs) { if (_annots == null) _annots = (AnnotationMapImpl)getMilieu().getAnnotationMap().clone(); _annots.addAnnotation(annotName, annotAttrs); } public void addAnnotation(String propName, String annotName, Map annotAttrs) { if (_annots == null) _annots = (AnnotationMapImpl)getMilieu().getAnnotationMap().clone(); _annots.addAnnotation(propName, annotName, annotAttrs); } private AnnotationMap annotmap() { return _annots != null ? _annots: getMilieu().getAnnotationMap(); } public void sessionWillPassivate(Page page) { //nothing to do } public void sessionDidActivate(Page page) { sessionDidActivate0(page, this, true); } /** * @param pageLevelIdSpace whether this component's ID space is * at the page level. */ private static void sessionDidActivate0(Page page, AbstractComponent comp, boolean pageLevelIdSpace) { comp._page = page; comp._desktop = page.getDesktop(); //Note: we need only to fix the first-level spaceInfo. //Others are handled by readObject if (pageLevelIdSpace && comp._spaceInfo != null) { pageLevelIdSpace = false; comp._spaceInfo.ns.setParent(page.getNamespace()); } for (Iterator it = comp.getChildren().iterator(); it.hasNext();) { final AbstractComponent child = (AbstractComponent)it.next(); sessionDidActivate0(page, child, pageLevelIdSpace); //recursive } } /** Returns the extra controls that tell ZK how to handle this component * specially. * It is used only by component developers. * * <p>It is simpler to override {@link #newExtraCtrl} instead of this. * By use of {@link #newExtraCtrl}, you don't need to care of * cloning and serialization. * * <p>Default: return the object being created by {@link #newExtraCtrl}, * if any. * * @see ComponentCtrl#getExtraCtrl */ public Object getExtraCtrl() { return _xtrl; } /** Used by {@link #getExtraCtrl} to create a client control. * It is used only by component developers. * * <p>Default: return null. * * <p>To provide extra controls, it is simpler to override this method * instead of {@link #getExtraCtrl}. * By use of {@link #newExtraCtrl}, you don't need to care of * cloning and serialization. */ protected Object newExtraCtrl() { return null; } //-- Object --// public String toString() { final String clsnm = getClass().getName(); final int j = clsnm.lastIndexOf('.'); return "<"+clsnm.substring(j+1)+' '+_id+'>'; } public final boolean equals(Object o) { //no more override return this == o; } /** Holds info shared of the same ID space. */ private static class SpaceInfo { private Map attrs = new HashMap(); //don't create it dynamically because _ip bind it at constructor private Namespace ns; /** A map of ((String id, Component fellow). */ private Map fellows = new HashMap(41); private SpaceInfo(Component owner, String id) { ns = new BshNamespace(id); ns.setVariable("spaceScope", attrs, true); ns.setVariable("spaceOwner", owner, true); } } private class ChildIter implements ListIterator { private final ListIterator _it; private Object _last; private boolean _bNxt; private ChildIter(int index) { _it = _children.listIterator(index); } public void add(Object o) { final Component comp = (Component)o; if (comp.getParent() == AbstractComponent.this) throw new UnsupportedOperationException("Unable to add component with the same parent: "+o); //1. it is confusing to allow adding (with replace) //2. the code is complicated _it.add(o); //Note: we must go thru insertBefore because spec //(such that component need only to override removeChhild _modChildByIter = true; try { final Component ref; if (_bNxt) { if (_it.hasNext()) { ref = (Component)_it.next(); _it.previous(); } else ref = null; } else ref = (Component)_last; insertBefore(comp, ref); } finally { _modChildByIter = false; } } public boolean hasNext() { return _it.hasNext(); } public boolean hasPrevious() { return _it.hasPrevious(); } public Object next() { _bNxt = true; return _last = _it.next(); } public Object previous() { _bNxt = false; return _last = _it.previous(); } public int nextIndex() { return _it.nextIndex(); } public int previousIndex() { return _it.previousIndex(); } public void remove() { _it.remove(); //Note: we must go thru removeChild because spec //(such that component need only to override removeChhild _modChildByIter = true; try { removeChild((Component)_last); } finally { _modChildByIter = false; } } public void set(Object o) { throw new UnsupportedOperationException("set"); //Possible to implement this but confusing to developers //if o has the same parent (since we have to move) } } //Cloneable// public Object clone() { final AbstractComponent clone; try { clone = (AbstractComponent)super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } //1. make it not belonging to any page clone._desktop = null; clone._page = null; clone._parent = null; clone._attrs = new HashMap(_attrs); if (_listeners != null) clone._listeners = new HashMap(_listeners); if (_annots != null) clone._annots = (AnnotationMapImpl)_annots.clone(); //2. clone children (deep cloning) cloneChildren(clone); clone.init(true); //3. spaceinfo if (clone._spaceInfo != null) { clone._spaceInfo = new SpaceInfo(clone, clone._uuid); cloneSpaceInfo(clone, this._spaceInfo); } return clone; } private static final void cloneSpaceInfo(AbstractComponent clone, SpaceInfo from) { final SpaceInfo to = clone._spaceInfo; to.attrs.putAll(from.attrs); to.ns.copy(from.ns, null); //rebuild ID space by binding itself and all children clone.bindToIdSpace(clone); for (Iterator it = clone.getChildren().iterator(); it.hasNext();) addToIdSpacesDown((Component)it.next(), clone); } private static final void cloneChildren(AbstractComponent comp) { final Iterator it = comp._children.iterator(); comp._children = new LinkedList(); while (it.hasNext()) { final AbstractComponent child = (AbstractComponent) ((AbstractComponent)it.next()).clone(); //recursive child._parent = comp; //correct it if (child._spaceInfo != null) child._spaceInfo.ns.setParent(comp.getNamespace()); comp._children.add(child); } } //Serializable// //NOTE: they must be declared as private private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); Serializables.smartWrite(s, _attrs); if (_listeners != null) for (Iterator it = _listeners.entrySet().iterator(); it.hasNext();) { final Map.Entry me = (Map.Entry)it.next(); s.writeObject(me.getKey()); Serializables.smartWrite(s, (Collection)me.getValue()); } s.writeObject(null); //store _spaceInfo if (this instanceof IdSpace) { //write _spaceInfo.attrs Serializables.smartWrite(s, _spaceInfo.attrs); //write _spaceInfo.ns (only variables that are not fellows) _spaceInfo.ns.write(s, new Namespace.Filter() { public boolean accept(String name, Object value) { return !(value instanceof Component); } }); } } private synchronized void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); init(false); Serializables.smartRead(s, _attrs); for (;;) { final String evtnm = (String)s.readObject(); if (evtnm == null) break; //no more if (_listeners == null) _listeners = new HashMap(); _listeners.put(evtnm, Serializables.smartRead(s, (Collection)null)); } //restore child's _parent for (Iterator it = getChildren().iterator(); it.hasNext();) { final AbstractComponent child = (AbstractComponent)it.next(); child._parent = this; } //restore _spaceInfo if (this instanceof IdSpace) { _spaceInfo = new SpaceInfo(this, _uuid); //fix child's _spaceInfo's parent fixSpaceParentOneLevelDown(this, _spaceInfo.ns); //read _spaceInfo.attrs Serializables.smartRead(s, _spaceInfo.attrs); //_spaceInfo.ns _spaceInfo.ns.read(s); //restore ID space by binding itself and all children bindToIdSpace(this); for (Iterator it = getChildren().iterator(); it.hasNext();) addToIdSpacesDown((Component)it.next(), this); } } /** Fixed Namespace's parent of children only one level. */ private static final void fixSpaceParentOneLevelDown(Component comp, Namespace nsparent) { for (Iterator it = comp.getChildren().iterator(); it.hasNext();) { final AbstractComponent child = (AbstractComponent)it.next(); //Others are handled by readObject if (child._spaceInfo != null) child._spaceInfo.ns.setParent(nsparent); else fixSpaceParentOneLevelDown(child, nsparent); //recursive } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -