package gve.calc.formula;

/* MVC stuff.
 * Controllers and Views always come in pairs. They can
 * communicate directly to each other. They can also communicate
 * directly with the model.
 * A single model can be connected to a number of Controller/View pairs.
 * The model is unaware of its controllers.  
 */

import java.util.Hashtable;
import java.util.Vector;

public class MVC {
	
This class cannot be instantiated. It is a repository of functions.
private MVC() {} /* Keys are models; values are (Vectors of) views */ private static Hashtable registrations = new Hashtable(); /* A view wants to be notified whenever a model changes. * This is similar to having Listeners, but avoids the overhead * of adding a "listeners" field in each model */ public static void registerView(Object model,View view) { Object views = registrations.get(model); if (views == null) { // For efficiency, don't create a Vector // when there's only a single listener registrations.put(model,view); } else if (views instanceof Vector) { ((Vector)views).addElement(view); } else { // there was one view registered Vector v = new Vector(4); v.addElement(views); v.addElement(view); registrations.put(model,v); } } public static void unregisterView(Object model,View view) { Object views = registrations.get(model); if (views == null) throw new Error("unregisterView: view was not registered"); else if (views instanceof Vector) { Vector v = (Vector)views; if (v.removeElement(view)) { if (v.size() == 1) { // only one registered view left view = (View)v.elementAt(0); v.setSize(0); registrations.put(model,view); } } else throw new Error("unregisterView: view was not registered"); } else { if (views != view) throw new Error("unregisterView: view was not registered"); // All views are unregistered now registrations.remove(model); } } public static View [] getViews(Object model) { Object views = registrations.get(model); if (views == null) return new View[0]; if (views instanceof Vector) { Vector v = (Vector)views; View [] result = new View[v.size()]; v.copyInto(result); return result; } View [] result = new View[1]; result[0] = (View)views; return result; } /* Model has changed. This function notifies * all the dependent views of the change by calling their * updateView() method. */ public static void changed(Object model) { changed(model,null); } /* Same as above, but allow us to pass extra parameter. */ public static void changed(Object model,Object with) { Object views = registrations.get(model); if (views == null) return; if (views instanceof Vector) { Vector v = (Vector)views; for (int count = v.size()-1; count>-0; count--) { View view = (View)v.elementAt(count); view.updateView(with); } return; } ((View)views).updateView(with); } }