samer@0: /* samer@0: * BaseViewer.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.util; samer@0: import samer.core.*; samer@0: import java.util.*; samer@0: import java.awt.*; samer@0: samer@0: /** samer@0: Basic Viewer that appears as panel with an optional samer@0: label. It is actually an envelope class for the real Viewer samer@0: provided by Shell.createViewerPanel(), but in addition, it: samer@0: - handles a reference to an Observable. samer@0: - handles attach() and detach() in response to samer@0: underlying panel's visibility. samer@0: - responds to DISPOSE message from Observable by attempting samer@0: to destroy itself using Shell.releaseViewer() samer@0: */ samer@0: samer@0: public class BaseViewer implements Observer, Viewer samer@0: { samer@0: private Container panel; samer@0: private Viewer viewer; samer@0: protected Observable obs; samer@0: private Component label; samer@0: samer@0: /** Construct a BaseViewer for the given Viewable. If the Viewable samer@0: has an Agent (ie returns something from getAgent() ) then samer@0: the Agent's commands are exposed on the Viewer using samer@0: this.exposeCommmands() samer@0: */ samer@0: public BaseViewer(Viewable v) { samer@0: this((Observable)v); samer@0: Agent a=v.getAgent(); samer@0: if (a!=null) exposeCommands(a); samer@0: } samer@0: samer@0: /** Construct a BaseViewer for the given Observable. The only difference samer@0: between this constructor and the BaseViewer(Viewable) constructor samer@0: is that no agent is exposed. samer@0: */ samer@0: public BaseViewer(Observable o) { samer@0: obs=o; samer@0: viewer=Shell.createViewerPanel(this); samer@0: panel=(Container)viewer.getComponent(); samer@0: } samer@0: samer@0: /** Returns the Container to which Components can be added to samer@0: be exposed in this Viewer. samer@0: */ samer@0: public Container panel() { return panel; } samer@0: samer@0: /** Attempts to display a label or name for this viewer. samer@0: samer@0: */ samer@0: public void setText(String txt) { samer@0: if (txt==null) { samer@0: if (label!=null) panel.remove(label); samer@0: label=null; samer@0: } else if (label==null) { samer@0: panel.add(label=Shell.createLabel(txt)); samer@0: } else { samer@0: label.setName(txt); samer@0: } samer@0: } samer@0: samer@0: /** Equivalent to panel().setLayout(layout) - See java.awt.Container.setLayout() */ samer@0: public void setLayout(LayoutManager l) { panel.setLayout(l); } samer@0: samer@0: /** Equivalent to panel().add(component) - See java.awt.Container.add() */ samer@0: public void add(Component c) { panel.add(c); } samer@0: samer@0: /** Add a default viewer for the given Viewable samer@0: Equivalent to panel().add(vbl.getViewer().getComponent()) samer@0: See java.awt.Container.add() samer@0: */ samer@0: public void add(Viewable vbl) { panel.add(vbl.getViewer().getComponent()); } samer@0: samer@0: /** Implementation of Viewer.getComponent(): returns the samer@0: AWT Component for this Viewer. */ samer@0: public Component getComponent() { return panel; } samer@0: samer@0: /** Delegated to viewer returned frp, Shell.createViewerPanel() - samer@0: Generally, this will add an Agent's commands to a right-click popup menu */ samer@0: public void exposeCommands(Agent agent) { viewer.exposeCommands(agent); } samer@0: samer@0: /** A call to this means that the Viewer should begin observing and samer@0: reflecting changes in its Viewable */ samer@0: public void attach() { obs.addObserver(this); } samer@0: samer@0: /** This ought to be the reverse of attach(). Not entirely clear who samer@0: should be dropping references to whom here. Mainly, the Viewer samer@0: should become disposable, so Viewer should arrange for any references samer@0: to it (esp from the Viewable) to be dropped. This implementation samer@0: deletes this Viewer (Observer) from the Viewable (Observable), samer@0: but does not drop the Viewer's reference to the Observable incase samer@0: it needs to reattach. This will be a problem for Viewers that samer@0: observe more than one Viewable, so let's assume that BaseViewer samer@0: is specifically a monogamous Viewer! samer@0: */ samer@0: public void detach() { obs.deleteObserver(this); } // obs=null; samer@0: samer@0: /** Respond to changes in Observable. This implementation tests samer@0: to see if the Observable is being destroyed and if so, attempts to samer@0: destroy the Viewer. samer@0: */ samer@0: public void update(Observable o, Object arg) { disposeFilter(o,arg); } samer@0: samer@0: /** implementation of update method is here so that it can be called samer@0: easily by sub-classes more than one generation removed. */ samer@0: protected final boolean disposeFilter(Observable o, Object arg) samer@0: { samer@0: if (obs.equals(o) && Viewable.DISPOSING==arg) { samer@0: Shell.releaseViewer(this); samer@0: return true; samer@0: } samer@0: return false; samer@0: } samer@0: }