if (attribute == null) {
// No associated attribute.
return;
}
ChangeRequest request;
if (attribute instanceof PasswordAttribute) {
// Passwords have to be handled specially because the password
// is not represented in a string.
request = new ChangeRequest(this, name) {
protected void _execute() throws IllegalActionException {
char[] password = getCharArrayValue(name);
((PasswordAttribute) attribute).setPassword(password);
attribute.validate();
Iterator derived = ((PasswordAttribute) attribute)
.getDerivedList().iterator();
while (derived.hasNext()) {
PasswordAttribute derivedPassword = (PasswordAttribute) derived
.next();
derivedPassword.setPassword(password);
}
}
};
} else if (attribute instanceof NamedObj) {
// NOTE: We must use a MoMLChangeRequest so that changes
// propagate to any objects that have been instantiating
// using this one as a class. This is only an issue if
// attribute is a NamedObj.
NamedObj castAttribute = (NamedObj) attribute;
String stringValue = getStringValue(name);
// If the attribute is a DoubleRangeParameter, then we
// have to translate the integer value returned by the
// JSlider into a double.
if (attribute instanceof DoubleRangeParameter) {
try {
int newValue = Integer.parseInt(stringValue);
int precision = ((IntToken) ((DoubleRangeParameter) attribute).precision
.getToken()).intValue();
double max = ((DoubleToken) ((DoubleRangeParameter) attribute).max
.getToken()).doubleValue();
double min = ((DoubleToken) ((DoubleRangeParameter) attribute).min
.getToken()).doubleValue();
double newValueAsDouble = min
+ (((max - min) * newValue) / precision);
stringValue = "" + newValueAsDouble;
} catch (IllegalActionException e) {
throw new InternalErrorException(e);
}
}
// The context for the MoML should be the first container
// above this attribute in the hierarchy that defers its
// MoML definition, or the immediate parent if there is none.
NamedObj parent = castAttribute.getContainer();
String moml = "<property name=\"" + castAttribute.getName()
+ "\" value=\""
+ StringUtilities.escapeForXML(stringValue) + "\"/>";
request = new MoMLChangeRequest(this, // originator
parent, // context
moml, // MoML code
null) { // base
protected void _execute() throws Exception {
synchronized (PtolemyQuery.this) {
try {
_ignoreChangeNotifications = true;
super._execute();
} finally {
_ignoreChangeNotifications = false;
}
}
}
};
} else {
// If the attribute is not a NamedObj, then we
// set its value directly.
request = new ChangeRequest(this, name) {
protected void _execute() throws IllegalActionException {
attribute.setExpression(getStringValue(name));
attribute.validate();
/* NOTE: Earlier version:
// Here, we need to handle instances of Variable
// specially. This is too bad...
if (attribute instanceof Variable) {
// Will this ever happen? A
// Variable that is not a NamedObj???
// Retrieve the token to force
// evaluation, so as to check the
// validity of the new value.
((Variable)attribute).getToken();
}
*/
}
};
}
// NOTE: This object is never removed as a listener from
// the change request. This is OK because this query will
// be closed at some point, and all references to it will
// disappear, and thus both it and the change request should
// become accessible to the garbage collector. However, I
// don't quite trust Java to do this right, since it's not
// completely clear that it releases resources when windows
// are closed. It would be better if this listener were
// a weak reference.
// NOTE: This appears to be unnecessary, since we register
// as a change listener on the handler. This results in
// two notifications. EAL 9/15/02.
request.addChangeListener(this);
if (_handler == null) {
request.execute();
} else {
if (request instanceof MoMLChangeRequest) {
((MoMLChangeRequest) request).setUndoable(true);
}