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;
+	}
+}