/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.tools; import java.util.ArrayList; import java.util.List; import org.opensourcephysics.controls.XMLControl; import org.opensourcephysics.display.DatasetManager; /** * A FunctionEditor for Parameters. * * @author Douglas Brown */ public class ParamEditor extends FunctionEditor { protected double[] paramValues = new double[0]; private DatasetManager data; private FunctionEditor[] functionEditors; protected String[] paramDescriptions = new String[0]; /** * Default constructor */ public ParamEditor() { super(); paramEditor = this; } /** * Constructor using a DatasetManager to define initial parameters * * @param input the DatasetManager */ public ParamEditor(DatasetManager input) { this(); data = input; loadParametersFromData(); } /** * Gets an array containing copies of the current parameters. * * @return an array of Parameters */ public Parameter[] getParameters() { Parameter[] params = new Parameter[objects.size()]; for(int i = 0; i<objects.size(); i++) { Parameter next = (Parameter) objects.get(i); params[i] = new Parameter(next.paramName, next.expression); params[i].setExpressionEditable(next.isExpressionEditable()); params[i].setNameEditable(next.isNameEditable()); params[i].setDescription(next.getDescription()); params[i].value = next.value; } return params; } /** * Replaces the current parameters with new ones. * * @param params an array of Parameters */ public void setParameters(Parameter[] params) { List<Object> list = new ArrayList<Object>(); for(int i = 0; i<params.length; i++) { list.add(params[i]); } setObjects(list); } /** * Sets the function editors that use these parameters. * * @param editors an array of FunctionEditors */ public void setFunctionEditors(FunctionEditor[] editors) { functionEditors = editors; if (functionEditors==null) { paramEditor = null; } } /** * Gets the current parameter values. * * @return an array of values */ public double[] getValues() { return paramValues; } /** * Gets the current parameter descriptions. * * @return an array of descriptions */ public String[] getDescriptions() { return paramDescriptions; } /** * Returns the name of the object. * * @param obj the object * @return the name */ public String getName(Object obj) { return(obj==null) ? null : ((Parameter) obj).paramName; } /** * Returns the expression of the object. * * @param obj the object * @return the expression */ public String getExpression(Object obj) { return(obj==null) ? null : ((Parameter) obj).expression; } /** * Returns the description of the object. * * @param obj the object * @return the description */ public String getDescription(Object obj) { return (obj==null)? null: ((Parameter)obj).getDescription(); } /** * Sets the description of an object. * * @param obj the object * @param desc the description */ public void setDescription(Object obj, String desc) { if (obj!=null) { Parameter p = (Parameter)obj; if (desc!=null && desc.trim().equals("")) { //$NON-NLS-1$ desc = null; } p.setDescription(desc); // for(int i = 0; i<objects.size(); i++) { // p = (Parameter) objects.get(i); // paramValues[i] = p.getValue(); // paramDescriptions[i] = p.getDescription(); // } super.setDescription(obj, desc); } } /** * Sets the description of the named parameter, if any. * * @param name the name * @param description the description */ public void setDescription(String name, String description) { for(Object obj: objects) { Parameter param = (Parameter)obj; if (param.getName().equals(name)) { setDescription(obj, description); break; } } } /** * Returns a tooltip for the object. * * @param obj the object * @return the tooltip */ public String getTooltip(Object obj) { String s = ((Parameter) obj).getDescription(); if (s==null) { s = ToolsRes.getString("ParamEditor.Table.Cell.Name.Tooltip"); //$NON-NLS-1$ s += " ("+ToolsRes.getString("FunctionEditor.Tooltip.HowToEdit")+")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } return s; } /** * Determines if an object's name is editable. * * @param obj the object * @return true if the name is editable */ public boolean isNameEditable(Object obj) { return((Parameter) obj).isNameEditable(); } /** * Determines if an object's expression is editable. * * @param obj the object * @return true if the expression is editable */ public boolean isExpressionEditable(Object obj) { return((Parameter) obj).isExpressionEditable(); } /** * Evaluates an object. */ protected void evaluateObject(Object obj) { Parameter p = (Parameter) obj; p.evaluate(objects); } /** * Evaluates parameters that depend on the named parameter. * * @param seed the independent parameter * @return a list of evaluated dependent parameters */ public ArrayList<Parameter> evaluateDependents(Parameter seed) { ArrayList<Parameter> temp = new ArrayList<Parameter>(); ArrayList<Parameter> toRemove = new ArrayList<Parameter>(); for(int i = 0; i<evaluate.size(); i++) { Parameter param = (Parameter) evaluate.get(i); if(param.paramName.equals(seed.paramName)) { temp.add(seed); toRemove.add(seed); for(int j = i+1; j<evaluate.size(); j++) { Parameter p = (Parameter) evaluate.get(j); temp.add(new Parameter(p.paramName, p.expression)); } // evaluate temp list for(int j = 0; j<temp.size(); j++) { // for each parameter, evaluate and set paramValues element Parameter p = temp.get(j); p.evaluate(temp); if(getReferences(p.getName(), null).isEmpty()) { toRemove.add(p); } } temp.removeAll(toRemove); return temp; } } return temp; } /** * Evaluates all current objects. */ public void evaluateAll() { super.evaluateAll(); if(this.getClass()!=ParamEditor.class) { return; } if(paramValues.length!=objects.size()) { paramValues = new double[objects.size()]; } for(int i = 0; i<evaluate.size(); i++) { Parameter p = (Parameter) evaluate.get(i); p.evaluate(objects); } if(paramDescriptions.length!=objects.size()) { paramDescriptions = new String[objects.size()]; } for(int i = 0; i<objects.size(); i++) { Parameter p = (Parameter) objects.get(i); paramValues[i] = p.getValue(); paramDescriptions[i] = p.getDescription(); } } /** * Returns true if a name is already in use. * * @param obj the object (may be null) * @param name the proposed name for the object * @return true if duplicate */ protected boolean isDisallowedName(Object obj, String name) { boolean disallowed = super.isDisallowedName(obj, name); // added following line so leaving object name unchanged is not disallowed if (!disallowed && obj!=null && getName(obj).equals(name)) return false; if(functionEditors!=null) { for(int i = 0; i<functionEditors.length; i++) { disallowed = disallowed||functionEditors[i].isDisallowedName(null, name); } } return disallowed; } /** * Pastes the clipboard contents. */ protected void paste() { XMLControl[] controls = getClipboardContents(); if(controls==null) { return; } for(int i = 0; i<controls.length; i++) { // create a new object Parameter param = (Parameter) controls[i].loadObject(null); param.setNameEditable(true); param.setExpressionEditable(true); addObject(param, true); } evaluateAll(); } /** * Returns true if the object expression is invalid. */ protected boolean isInvalidExpression(Object obj) { return Double.isNaN(((Parameter) obj).getValue()); } /** * Creates an object with specified name and expression. * This always returns a new Parameter but copies the editable properties. * * @param name the name * @param expression the expression * @param obj ignored * @return the object */ protected Object createObject(String name, String expression, Object obj) { Parameter original = (Parameter) obj; if((original!=null)&&original.paramName.equals(name)&&original.expression.equals(expression)) { return original; } Parameter p = new Parameter(name, expression); if(original!=null) { p.setExpressionEditable(original.isExpressionEditable()); p.setNameEditable(original.isNameEditable()); p.setDescription(original.getDescription()); } return p; } /** * Refreshes the GUI. */ protected void refreshGUI() { super.refreshGUI(); newButton.setToolTipText(ToolsRes.getString("ParamEditor.Button.New.Tooltip")); //$NON-NLS-1$ titledBorder.setTitle(ToolsRes.getString("ParamEditor.Border.Title")); //$NON-NLS-1$ } /** * Loads parameters from the current datasetManager. */ public void loadParametersFromData() { if(data==null) return; String[] names = data.getConstantNames(); for (String name: names) { String expression = data.getConstantExpression(name); Parameter p = (Parameter) getObject(name); if(p==null) { p = new Parameter(name, expression); p.setDescription(data.getConstantDescription(name)); addObject(p, false); } else { setExpression(name, expression, false); } } } /** * Refreshes the parameters associated with a user function. */ protected void refreshParametersFromFunction(UserFunction f) { // identify values that have changed for(int i = 0; i<f.getParameterCount(); i++) { String name = f.getParameterName(i); String val = String.valueOf(f.getParameterValue(i)); Parameter p = (Parameter) getObject(name); if(p==null) { p = new Parameter(name, val); p.setNameEditable(false); p.setExpressionEditable(false); addObject(p, false); } // change parameter value else { setExpression(name, val, false); } } } /** * Returns the default name for newly created objects. */ protected String getDefaultName() { return ToolsRes.getString("ParamEditor.New.Name.Default"); //$NON-NLS-1$ } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */