Fix some NPEs and other exceptions in property change handling.
For the 'IntAdjust' and 'BooleanAdjust' classes, handle
PropertyChangeEvents where the values are null or Strings instead of
the expected Integer or Boolean types, respectively.
It's kinda amazing that this has never come up before.
Each Adjust stores to a PrefsConfig, which is backed by a Properties,
which stores all values as Strings. Not only that, but it does not
store in any way what the expected type of a property is.
It is determined by which getter you call:
_cfg.setValue("foo", "2");
_cfg.getValue("foo", (String)null); // returns "2"
_cfg.getValue("foo", 0); // returns 2
_cfg.getValue("foo", 3.0f); // returns 2.0f
If a property is removed, then null is the new value, and it also
doesn't know what type the old value was. These runtime adjusts
need to be able to revert to their default value and they will
always need to be able to potentially parse a String. And since
someone can legally change the type of a property, they need
to be able to recover if the property is a type they don't even
expect.
The real problem here is using shitty Properties for backing,
and/or not storing something more complex than the simple toString()
representation of the value.
Don't interpret this fix as a blessing to use these old, old things.
I'm supporting legacy code.
The other adjust subclasses weren't ...adjusted... because my project
doesn't use them and I'm not going to dig in and test them.
This commit is contained in:
@@ -149,6 +149,7 @@ public class RuntimeAdjust
|
||||
public BooleanAdjust (String descrip, String name, PrefsConfig config, boolean defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_defval = defval;
|
||||
_value = _config.getValue(_name, defval);
|
||||
}
|
||||
|
||||
@@ -176,18 +177,30 @@ public class RuntimeAdjust
|
||||
|
||||
public void propertyChange (PropertyChangeEvent evt)
|
||||
{
|
||||
_value = ((Boolean)evt.getNewValue()).booleanValue();
|
||||
_value = toValue(evt.getNewValue());
|
||||
adjusted(_value);
|
||||
if (_valbox != null) {
|
||||
_valbox.setSelected(_value);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean toValue (Object o)
|
||||
{
|
||||
if (o instanceof Boolean) {
|
||||
return ((Boolean)o).booleanValue();
|
||||
}
|
||||
if (o instanceof String) {
|
||||
return Boolean.parseBoolean((String)o); // never throws!
|
||||
}
|
||||
return _defval;
|
||||
}
|
||||
|
||||
protected void adjusted (boolean newValue)
|
||||
{
|
||||
// Log.info(_name + " => " + newValue);
|
||||
}
|
||||
|
||||
protected final boolean _defval;
|
||||
protected boolean _value;
|
||||
protected JCheckBox _valbox;
|
||||
}
|
||||
@@ -198,6 +211,7 @@ public class RuntimeAdjust
|
||||
public IntAdjust (String descrip, String name, PrefsConfig config, int defval)
|
||||
{
|
||||
super(descrip, name, config);
|
||||
_defval = defval;
|
||||
_value = _config.getValue(_name, defval);
|
||||
}
|
||||
|
||||
@@ -228,19 +242,34 @@ public class RuntimeAdjust
|
||||
|
||||
public void propertyChange (PropertyChangeEvent evt)
|
||||
{
|
||||
_value = ((Integer)evt.getNewValue()).intValue();
|
||||
Integer oval = (Integer)evt.getOldValue();
|
||||
adjusted(_value, (oval == null ? -1 : oval.intValue()));
|
||||
_value = toValue(evt.getNewValue());
|
||||
adjusted(_value, toValue(evt.getOldValue()));
|
||||
if (_valbox != null) {
|
||||
_valbox.setText("" + _value);
|
||||
}
|
||||
}
|
||||
|
||||
protected int toValue (Object o)
|
||||
{
|
||||
if (o instanceof Integer) {
|
||||
return ((Integer)o).intValue();
|
||||
}
|
||||
if (o instanceof String) {
|
||||
try {
|
||||
return Integer.parseInt((String)o);
|
||||
} catch (NumberFormatException nfe) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
return _defval;
|
||||
}
|
||||
|
||||
protected void adjusted (int newValue, int oldValue)
|
||||
{
|
||||
// Log.info(_name + " => " + newValue);
|
||||
}
|
||||
|
||||
protected final int _defval;
|
||||
protected int _value;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user