samer@0: /* samer@0: * Viewable.java samer@0: * samer@0: * Copyright (c) 2000, Samer Abdallah, King's College London. samer@0: * All rights reserved. samer@0: * samer@0: * This software is provided AS iS and WITHOUT ANY WARRANTY; samer@0: * without even the implied warranty of MERCHANTABILITY or samer@0: * FITNESS FOR A PARTICULAR PURPOSE. samer@0: */ samer@0: samer@0: package samer.core; samer@0: import java.util.*; samer@0: samer@0: samer@0: /** samer@0:
samer@0: A Viewable is a named Observable object, for which samer@0: can be created a Viewer. A Viewer is meant to allow user samer@0: interaction with the object. The name is managed samer@0: by a Node object, so they can form a heirarchy. samer@0: A Viewable can also have an associated Agent, so that samer@0: Viewers can automatically expose commands samer@0: for the Agent. samer@0: */ samer@0: samer@0: samer@0: public class Viewable extends Observable samer@0: { samer@0: /** sent to Obervable.update() when Viewable is samer@0: * being disposed of. samer@0: */ samer@0: public final static Object DISPOSING = new Object(); samer@0: samer@0: public final Node getNode() { return node; } samer@0: public final void setNode(Node n) { node=n; } samer@0: public Agent getAgent() { return agent; } samer@0: public void setAgent(Agent a) { agent=a; } samer@0: public void addAgent(Agent a) { setAgent(new CompoundAgent(agent,a)); } samer@0: samer@0: public String getLabel() { samer@0: String str = Shell.getString(node.fullNameFor("label"),null); samer@0: return str==null ? node.fullName().substring(1) : str; samer@0: } samer@0: samer@0: /**
Should leave the Viewable in such a state that the samer@0: * garbage collector can get it as soon as any direct samer@0: * references go out of scope. In particular, any attached samer@0: * Viewers or Observers should drop their references to samer@0: * this Viewable, and if necessary, dispose of themselves. samer@0: *
samer@0: * The default implementation deregisters the Viewable,
samer@0: * notifies Obervers and detaches the node.
samer@0: */
samer@0:
samer@0: public void dispose()
samer@0: {
samer@0: Shell.deregisterViewable(this);
samer@0: changed(DISPOSING);
samer@0: }
samer@0:
samer@0: /** This should return a suitable Viewer for this object.
samer@0: Default implementation asks the samer.core.Registry
samer@0: to create one. */
samer@0: public Viewer getViewer() { return Registry.createViewer(this); }
samer@0:
samer@0: protected Viewable(String nm) { node = new Node(nm); }
samer@0: protected Viewable(Node nd) { node = nd; }
samer@0: protected Viewable() {}
samer@0:
samer@0: protected Node node;
samer@0: protected Agent agent=null;
samer@0: // protected Vector agents=new Vector();
samer@0:
samer@0: public String toString() {
samer@0: return Node.lastPart(getClass().getName())+":"+getLabel();
samer@0: }
samer@0:
samer@0: public void finalize() { Shell.trace("Viewable finalizing: "+toString()); }
samer@0:
samer@0: /* ------- override implementation of Observable here -----------*/
samer@0:
samer@0: private static class Vector extends java.util.Vector {
samer@0: public Object[] getArray() { return elementData; }
samer@0: }
samer@0:
samer@0: private Vector observers=new Vector();
samer@0:
samer@0: public synchronized void addObserver(Observer o) {
samer@0: if (!observers.contains(o)) observers.addElement(o);
samer@0: }
samer@0:
samer@0: public synchronized void deleteObserver(Observer o) {
samer@0: observers.removeElement(o);
samer@0: }
samer@0:
samer@0: public synchronized void deleteObservers() {
samer@0: observers.removeAllElements();
samer@0: }
samer@0:
samer@0: public void notifyObservers(Object arg)
samer@0: {
samer@0: Object [] arr=observers.getArray();
samer@0:
samer@0: for (int i=observers.size()-1; i>=0; i--) {
samer@0: ((Observer)arr[i]).update(this, arg);
samer@0: }
samer@0: }
samer@0:
samer@0: /** This will notify all observers that this object may have changed
samer@0: The second argument to Observer.update() will be null */
samer@0: public final void changed() { notifyObservers(null); }
samer@0:
samer@0: /** This will notify all observers that this object may have changed.
samer@0: The second argument to Observer.update() will be the given object */
samer@0: public final void changed(Object o) { notifyObservers(o); }
samer@0: }
samer@0: