/*
* 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.ejs.control;
import java.util.Enumeration;
import java.util.Vector;
import org.opensourcephysics.ejs.control.value.DoubleValue;
import org.opensourcephysics.ejs.control.value.Value;
/**
* A utility class that holds information about a value that can be shared
* by different ControlElement internal variables and that can also trigger
* methods of a class
*/
public class GroupVariable {
private String name;
private Value value;
private Vector<Item> elementList;
private Vector<MethodWithOneParameter> methodList;
// A GroupVariable should be created with a non-null value
// that matches the type it is going to be used.
/**
* Constructor GroupVariable
* @param _aName
* @param _aValue
*/
public GroupVariable(String _aName, Value _aValue) {
name = _aName;
elementList = new Vector<Item>();
methodList = new Vector<MethodWithOneParameter>();
// value = _aValue.cloneValue();
if(_aValue!=null) {
value = _aValue.cloneValue();
} else {
value = new DoubleValue(0.0);
}
// else value = null; // This is rather dangerous if one doesn't follow the instructions above
}
public String getName() {
return name;
}
public String toString() {
return name;
}
public void setValue(Value _aValue) {
// This can be optimized by removing the check
// Again, this forces the instantiation to hold a non-null Value
// which must hold the right subclass of Value
// Unfortunately Ejs' users tend to modify the variable class
if(value.getClass()!=_aValue.getClass()) {
value = _aValue.cloneValue();
} else {
value.copyValue(_aValue);
}
}
public Value getValue() {
return value;
}
// --------------------------------------------------------
// Adding and removing control elements
// --------------------------------------------------------
public void addElementListener(ControlElement _element, int _index) {
elementList.add(new Item(_element, _index));
}
public void removeElementListener(ControlElement _element, int _index) {
for(Enumeration<Item> e = elementList.elements(); e.hasMoreElements(); ) {
Item item = e.nextElement();
if((item.element==_element)&&(item.index==_index)) {
elementList.removeElement(item);
return;
}
}
}
public void propagateValue(ControlElement _element) {
for(Enumeration<Item> e = elementList.elements(); e.hasMoreElements(); ) {
Item item = e.nextElement();
if(item.element!=_element) {
item.element.setActive(false);
if(item.element.myMethodsForProperties[item.index]!=null) { // AMAVP (See note in ControlElement)
// System.out.println ("I call the method "+item.element.myMethodsForProperties[item.index].toString()+ "first!");
item.element.setValue(item.index, item.element.myMethodsForProperties[item.index].invoke(ControlElement.METHOD_FOR_VARIABLE, null)); // null = no calling object
} else if(item.element.myExpressionsForProperties[item.index]!=null) { // AMAVP (See note in ControlElement)
// System.out.println ("I call the expression "+item.element.myExpressionsForProperties[item.index].expression+ "first!");
item.element.setValue(item.index, item.element.myExpressionsForProperties[item.index]);
} else {
item.element.setValue(item.index, value);
}
item.element.setActive(true);
}
}
}
// --------------------------------------------------------
// Adding and removing method elements
// --------------------------------------------------------
public void addListener(Object _target, String _method) {
addListener(_target, _method, null);
}
public void addListener(Object _target, String _method, Object _anObject) {
methodList.add(new MethodWithOneParameter(ControlElement.VARIABLE_CHANGED, _target, _method, null, null, _anObject));
}
public void removeListener(Object _target, String _method) {
for(Enumeration<MethodWithOneParameter> e = methodList.elements(); e.hasMoreElements(); ) {
MethodWithOneParameter method = e.nextElement();
if(method.equals(ControlElement.VARIABLE_CHANGED, _target, _method)) {
methodList.removeElement(method);
return;
}
}
}
public void invokeListeners(ControlElement _element) {
for(Enumeration<MethodWithOneParameter> e = methodList.elements(); e.hasMoreElements(); ) {
e.nextElement().invoke(ControlElement.VARIABLE_CHANGED, _element);
}
}
// --------------------------------------------------------
// Internal classes
// --------------------------------------------------------
private class Item {
public ControlElement element;
public int index;
Item(ControlElement _anElement, int _anIndex) {
element = _anElement;
index = _anIndex;
}
}
}
/*
* 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
*/