how to implement JavaFX property "throwing" exception

Vasiliy Baranov vasiliy.baranov at oracle.com
Fri Apr 5 09:33:37 PDT 2013


Greetings,

I need to implement a JavaFX property that may only be modified while 
the object is in an appropriate state, and so that any attempt to modify 
the property while the object is in an inappropriate state must result 
in IllegalStateException.

My first and naive implementation for this was as follows:

     private StringProperty foo;

     public final StringProperty fooProperty() {
         if (foo == null) {
             foo = new SimpleStringProperty(this, "foo") {
                 @Override protected void invalidated() {
                     if (!isInAppropriateState()) {
                         throw new IllegalStateException();
                     }
                 }
             };
         }
         return foo;
     }

The problem with this implementation is, throwing an exception from the 
invalidated() method results in both the exception being passed to the 
caller and the property value being updated with the new value. The 
latter is an undesirable side effect and, one can say, plain wrong 
behavior, even though it looks like some JavaFX classes find it 
acceptable, see e.g. Scene.camera property.

So I went on to searching JavaFX codebase and found that several JavaFX 
classes solve the problem by stashing the last valid property value 
somewhere and resetting the property to that value when throwing the 
exception, as follows:

     private StringProperty foo;
     private String oldFoo;

     public final StringProperty fooProperty() {
         if (foo == null) {
             foo = new SimpleStringProperty(this, "foo") {
                 @Override protected void invalidated() {
                     if (!isInAppropriateState()) {
                         if (isBound()) {
                             unbind();
                         }
                         set(oldFoo);
                         throw new IllegalStateException();
                     } else {
                         oldFoo = getFoo();
                     }
                 }
             };
         }
         return myValue;
     }

Examples of this approach include Animation.rate property and 
Effect.EffectInputProperty class.

I must admit I don't find this approach exceptionally elegant, but I may 
be missing something and there may indeed be a more elegant solution. So 
my question is, is this approach the recommended one?

Thanks,
-- Vasiliy


More information about the openjfx-dev mailing list