Dead horse, Bindings spam when something is null

John Hendrikx hjohn at xs4all.nl
Fri Dec 13 13:11:59 PST 2013


Run the following code.  It has a simple ObjectProperty that -can- be 
null when there is no Media inserted.  I want to make a binding that 
displays this information to the user, but will display "-no-media-" if 
nothing is inserted.

Is it really necessary to spam my logs with fake NPE's when 
insertedMedia happens to be null ?  This seems like a perfectly valid 
use case, and one that has been working fine up until somewhere halfway 
through the JavaFX 8 development cycle (and it still works fine, but now 
it spams me).

This is not the only spot I have this in my Application.... almost 
everything in my Application is dynamically loaded -- user interfaces 
are shown to the user before all data is present, which means I have 
lots and lots and lots of bindings that will be null for a short while 
as they get loaded.  Typically this loading occurs on background threads 
in order not to choke the Event thread, nor force the user to look at 
some waiting screen while Images get decoded, HTTP requests complete and 
Database calls get done.

For the life of me I cannot figure out what could be "wrong" with an 
ObjectProperty being null when evaluating a Binding.  Either make it 
catastrophically fail, so this use case is disallowed as it is obviously 
somehow super (confusing|dangerous|morally wrong|politicaly incorrect) 
or remove this logging which looks deceptively like a real error, but is 
not.

The only reasonable workaround I've found is to just replace the 
Bindings class with my own which is a bit more frugal with its logging.

I know about when/then/otherwise... it becomes unreadable at several 
levels deep, not to mention being completely unnecessary.

--John

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.stage.Stage;

public class BindingTest extends Application {
   public static void main(String[] args) {
     Application.launch(args);
   }

   @Override
   public void start(Stage primaryStage) {
     ObjectProperty<Media> insertedMedia = new SimpleObjectProperty<>();

     StringBinding x = new StringBinding() {
       StringBinding selectString = Bindings.selectString(insertedMedia, 
"title");

       {
         bind(selectString);
       }

       @Override
       protected String computeValue() {
         return selectString.get() == null ? "-no-media-" : 
selectString.get();
       }
     };

     System.out.println("x = " + x.get());

     insertedMedia.set(new Media());
     System.out.println("x = " + x.get());

     insertedMedia.get().titleProperty().set("B");
     System.out.println("x = " + x.get());

     insertedMedia.get().titleProperty().set("B2");
     System.out.println("x = " + x.get() + " vs. " + 
insertedMedia.get().titleProperty().get());
   }

   public static class Media {
     private final StringProperty title = new SimpleStringProperty();

     public StringProperty titleProperty() {
       return title;
     }

     public String getTitle() {
       return title.get();
     }

     public void setTitle(String title) {
       this.title.set(title);
     }
   }
}



More information about the openjfx-dev mailing list