package jas.hist; import jas.util.JASDialog; import jas.util.JASIcon; import jas.util.JASState; import jas.util.NestedRuntimeException; import jas.util.ObjectFactory; import jas.util.ObjectFactoryException; import java.awt.Component; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Enumeration; import java.util.Vector; import javax.swing.DefaultListCellRenderer; import javax.swing.Icon; import javax.swing.JList; /** * * A class which maintains a list of functions which can be overlayed * * on a plot. * */ public class FunctionRegistry { private FunctionRegistry() { } /** * Get the (unique) instance of FunctionRegistry */ static public FunctionRegistry instance() { return theFunctionRegistry; } /** * Register a function given its class and name * @param c The class of the function * @param name The name of the function */ public void registerFunction(Class c, String name) { registerFunction(createFunctionFactory(c,name)); } /** * Create a default function factory from a class and a name * @param c The class of the function * @param name The name of the function * @return The function factory */ public FunctionFactory createFunctionFactory(Class c, String name) { try { return new DefaultFunctionFactory(c,name); } catch (FunctionFactoryError e) { // convert the error to a runtime error throw new NestedRuntimeException(e); } } /** * Add a function by specifing a FunctionFactory */ public void registerFunction(FunctionFactory f) { m_functions.addElement(f); } /** * Remove a function factory from the list */ public void removeFunctionFactory(FunctionFactory f) { m_functions.removeElement(f); } /** * Clear the list */ public void removeAllFunctions() { m_functions.removeAllElements(); } /** * Get an enumeration of all the FunctionFactories in the registry */ public Enumeration elements() { return m_functions.elements(); } /** * Get the size of the registry */ public int size() { return m_functions.size(); } public FunctionFactory find(String name) { Enumeration e = m_functions.elements(); while (e.hasMoreElements()) { FunctionFactory ff = (FunctionFactory) e.nextElement(); if (ff.getFunctionName().equals(name)) return ff; } return null; } /** * Replace the contents of the list * @param e An enumeration of function factories */ public void setContents(Vector v) { m_functions = v; } FunctionFactory chooseFunction(Frame f) { // These lines need to be excised in applet version ChooseFunctionDialog dlg = new ChooseFunctionDialog(f); if (dlg.doModal()) { return dlg.getSelectedFunction(); } return null; } private Vector m_functions = new Vector(); private static FunctionRegistry theFunctionRegistry = new FunctionRegistry(); private class ChooseFunctionDialog extends JASDialog implements ItemListener, ActionListener { ChooseFunctionDialog(Frame f) { super(f,"Choose Function..."); m_list = new javax.swing.JList(m_functions); m_list.setCellRenderer(new FunctionListCellRenderer()); getContentPane().add("Center",m_list); pack(); } public void itemStateChanged(ItemEvent evt) { callEnable(); } public void actionPerformed(ActionEvent evt) { onOK(); } public void enableOK(JASState state) { //state.setEnabled(m_list.getSelectedValue()!=null); } public void onOK() { m_selection = (FunctionFactory) m_list.getSelectedValue(); super.onOK(); } public FunctionFactory getSelectedFunction() { return m_selection; } } private FunctionFactory m_selection; private javax.swing.JList m_list; } class DefaultFunctionFactory extends ObjectFactory implements FunctionFactory { DefaultFunctionFactory(Class c, String name) throws FunctionFactoryError { super(c); this.name = name; // Class must be a subclass of Basic1DFunction if (!inheritsFrom(Basic1DFunction.class)) throw new FunctionFactoryError("Function "+name+" does not inherit from Basic1DFunction"); // Class must be declared public if (!checkAccess()) throw new FunctionFactoryError("Function "+name+" is not declared public"); // The function needs to have a suitable constructor if (!canBeCreatedFrom(Double.TYPE,Double.TYPE,Double.TYPE,Double.TYPE)) throw new FunctionFactoryError("Function "+name+" does not have a suitable constructor"); } public Basic1DFunction createFunction(JASHist h) throws FunctionFactoryError { try { JASHistAxis xAxis = h.getXAxis(); JASHistAxis yAxis = h.getYAxis(); // which Y axis? return (Basic1DFunction) create(new Double(xAxis.getMin()), new Double(xAxis.getMax()), new Double(yAxis.getMin()), new Double(yAxis.getMax())); } catch (ObjectFactoryException e) { throw new FunctionFactoryError("Unexpected failure to create function"); } } public String getFunctionName() { return name; } public Icon getFunctionIcon() { return icon; } private String name; private Icon icon = JASIcon.create(this,"function.gif"); } class FunctionListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, // value to display int index, // cell index boolean isSelected, // is the cell selected boolean cellHasFocus) // the list and the cell have the focus { super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus); if (value instanceof FunctionFactory) { FunctionFactory ff = (FunctionFactory) value; setText(ff.getFunctionName()); setIcon(ff.getFunctionIcon()); } return this; } }