view src/samer/core_/util/BaseViewer.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	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;
	}
}