0

Background:

According to the accepted answer of this question, a TextArea has an underlying Text node that contains the text and acts as its bounding box. It is useful for calculating the visual (pre-transform) height of the text, even when the text wraps around.

The Text node is not exposed in the public JavaFX 8 API, but it can be gotten via .lookup(). Moreover, it seems it is not initialized till after the Scene is rendered. The above said answer shows how to get it successfully by listening to the Scene.

Problem:

I have taken the logic of the listener, which works, and implemented it as a binding instead. But the binding does not work, and I cannot understand why. The value of the property updated by the listener is successfully set to the new Text node, while the value of the binding is always null because it is not detecting the change of Scene from null to a Scene object.

public ObjectExpression<Text> getObservableTextNode(TextArea textArea) {
    // The underlying text node can be looked up only after applying CSS when there is a scene.
    // For that reason we return it as an observable.

    // Way #1: Listener
    ObjectProperty<Text> property = new SimpleObjectProperty<>();
    textArea.sceneProperty().addListener((observableNewScene, oldScene, newScene) -> {
        if (newScene != null) {
            textArea.applyCss();
            Node text = textArea.lookup(".text");
            property.set((Text) text);
        } else {
            property.set(null);
        }
    });
    return property;

    // Way #2: Binding - does not update
    ObjectBinding<Text> ob = Bindings.createObjectBinding(() -> {
        if (textArea.sceneProperty().get() != null) {
            textArea.applyCss();
            return (Text) textArea.lookup(".text");
        }
        return null;
    }, textArea.sceneProperty());
    return ob;
}

As far as I can tell, the logics of the listener and binding are the same. Why then is there a difference?

Community
  • 1
  • 1
  • 2
    This looks like a pretty ugly solution. You might want to describe exactly what you are trying to accomplish (and why). There may be a cleaner solution to your problem. This may be an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – jewelsea Mar 05 '16 at 06:00
  • I am generating an observable of the Text node, so that I can pass it to another class that will use it. I can achieve my goal by the listener, but that's not relevant. My interest here is in discovering specifically why the binding does not work. –  Mar 05 '16 at 06:09
  • Take a look here: http://stackoverflow.com/q/13015698/2991525 This may solve the problem without a workaround. – fabian Mar 05 '16 at 11:24
  • Both ways work the same for me. If you really want to do it this way, can you post a [MCVE]? – James_D Mar 05 '16 at 21:08

0 Answers0