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);
    }
  }
}

Reply via email to