Mercurial > hg > jslab
diff src/samer/core_/util/BaseViewer.java @ 0:bf79fb79ee13
Initial Mercurial check in.
author | samer |
---|---|
date | Tue, 17 Jan 2012 17:50:20 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/samer/core_/util/BaseViewer.java Tue Jan 17 17:50:20 2012 +0000 @@ -0,0 +1,131 @@ +/* + * BaseViewer.java + * + * Copyright (c) 2000, Samer Abdallah, King's College London. + * All rights reserved. + * + * This software is provided AS iS and WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +package samer.core.util; +import samer.core.*; +import java.util.*; +import java.awt.*; + +/** + Basic Viewer that appears as panel with an optional + label. It is actually an envelope class for the real Viewer + provided by Shell.createViewerPanel(), but in addition, it: + - handles a reference to an Observable. + - handles attach() and detach() in response to + underlying panel's visibility. + - responds to DISPOSE message from Observable by attempting + to destroy itself using Shell.releaseViewer() + */ + +public class BaseViewer implements Observer, Viewer +{ + private Container panel; + private Viewer viewer; + protected Observable obs; + private Component label; + + /** Construct a BaseViewer for the given Viewable. If the Viewable + has an Agent (ie returns something from getAgent() ) then + the Agent's commands are exposed on the Viewer using + this.exposeCommmands() + */ + public BaseViewer(Viewable v) { + this((Observable)v); + Agent a=v.getAgent(); + if (a!=null) exposeCommands(a); + } + + /** Construct a BaseViewer for the given Observable. The only difference + between this constructor and the BaseViewer(Viewable) constructor + is that no agent is exposed. + */ + public BaseViewer(Observable o) { + obs=o; + viewer=Shell.createViewerPanel(this); + panel=(Container)viewer.getComponent(); + } + + /** Returns the Container to which Components can be added to + be exposed in this Viewer. + */ + public Container panel() { return panel; } + + /** Attempts to display a label or name for this viewer. + <ul> + <li>If no label exists, then one is created via Shell.createLabel() + <li>If a label exists, it's text is changed to match the <code>txt</code> + <li>If <code>txt==null</code> then any label is removed + </ul> + */ + public void setText(String txt) { + if (txt==null) { + if (label!=null) panel.remove(label); + label=null; + } else if (label==null) { + panel.add(label=Shell.createLabel(txt)); + } else { + label.setName(txt); + } + } + + /** Equivalent to panel().setLayout(layout) - See java.awt.Container.setLayout() */ + public void setLayout(LayoutManager l) { panel.setLayout(l); } + + /** Equivalent to panel().add(component) - See java.awt.Container.add() */ + public void add(Component c) { panel.add(c); } + + /** Add a default viewer for the given Viewable + Equivalent to panel().add(vbl.getViewer().getComponent()) + See java.awt.Container.add() + */ + public void add(Viewable vbl) { panel.add(vbl.getViewer().getComponent()); } + + /** Implementation of Viewer.getComponent(): returns the + AWT Component for this Viewer. */ + public Component getComponent() { return panel; } + + /** Delegated to viewer returned frp, Shell.createViewerPanel() - + Generally, this will add an Agent's commands to a right-click popup menu */ + public void exposeCommands(Agent agent) { viewer.exposeCommands(agent); } + + /** A call to this means that the Viewer should begin observing and + reflecting changes in its Viewable */ + public void attach() { obs.addObserver(this); } + + /** This ought to be the reverse of attach(). Not entirely clear who + should be dropping references to whom here. Mainly, the Viewer + should become disposable, so Viewer should arrange for any references + to it (esp from the Viewable) to be dropped. This implementation + deletes this Viewer (Observer) from the Viewable (Observable), + but does not drop the Viewer's reference to the Observable incase + it needs to reattach. This will be a problem for Viewers that + observe more than one Viewable, so let's assume that BaseViewer + is specifically a monogamous Viewer! + */ + public void detach() { obs.deleteObserver(this); } // obs=null; + + /** Respond to changes in Observable. This implementation tests + to see if the Observable is being destroyed and if so, attempts to + destroy the Viewer. + */ + public void update(Observable o, Object arg) { disposeFilter(o,arg); } + + /** implementation of update method is here so that it can be called + easily by sub-classes more than one generation removed. */ + protected final boolean disposeFilter(Observable o, Object arg) + { + if (obs.equals(o) && Viewable.DISPOSING==arg) { + Shell.releaseViewer(this); + return true; + } + return false; + } +}