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: - If no label exists, then one is created via Shell.createLabel()
samer@0:
- If a label exists, it's text is changed to match the
txt
samer@0: - If
txt==null
then any label is removed
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: }