<div dir="ltr"><div>When I need to combine observable values I usually do something like:</div><div><br></div>Bindings.createDoubleBinding(() ->
width.get() / height.get(), height, width);<div><br></div><div>which is much less cumbersome than subclassing (although a bit less performant I think). It works for an arbitrary number of observables (including) observable lists/sets/maps too:</div><div><br></div><div>Bindings.createDoubleBinding(() -> list.getFirst() / height.get() * map.get("A"), height, list, map); // assume this makes sense somehow</div><div><br></div><div>ReactFX, which is the go-to library for such extension, has a 'combine' method that work like this:</div><div><br></div><div>Val.combine(height, width, (h, w) -> w / h);</div><div><br></div><div>with overloads for up to 6 observables (with a hexafunction). For an arbitrary number, you need the 'create' method that works very much like the JavaFX Bindings one:</div><div><br></div><div>Val.create(() -> a.get() * b.get() * c.get(), a, b, c);</div><div><br></div><div><br></div><div>To assess the proposal, I tried to write your JEP examples with the current JavaFX.</div><div><br></div>Multi-stage chain (not sure how you mapped to a Point3D from a Point2D and a number):<div><br></div>ObjectBinding<Point2D> point2d = Bindings.createObjectBinding(() -> new Point2D(x.get(), y.get()), x, y);<br>ObjectBinding<Point3D> point3d = Bindings.createObjectBinding(() -> new Point3D(point2d.get().getX(), point2d.get().getY(), z.get()), point2d, z);<div><br>Combining chains:</div><div><div style="padding:0px 2px"><div style=""><p style="margin:0px"><br>ObjectBinding<Point2D> point1 = Bindings.createObjectBinding(() -> new Point2D(x.get(), y.get()), x, y);</p><p style="margin:0px">ObjectBinding<Point2D> point2 = Bindings.createObjectBinding(() -> new Point2D(x.get(), y.get()), x, y);<br>ObjectBinding<Line2D> line = Bindings.createObjectBinding(() -> new Line2D(point1, point2), point1, point2); // Line2D is not a JavaFX class</p><br>Using a default value:</div><div style=""><br></div>ObservableValue<Point2D> point1 = Bindings.createObjectBinding(() -> new Point2D(x.get(), y.get()), x, y).orElse(Point2D.ZERO);</div></div><div style="padding:0px 2px"><br></div><div style="padding:0px 2px"><br></div><div style="padding:0px 2px">Some observations:</div><div style="padding:0px 2px">Bindings returns a Binding rather than an ObservableValue and also has primitive specialization versions that have their unique methods (add, subtract...). These methods, however, can be replicated with fluent bindings and they also have the "known" subtle GC issue for the intermediary values.</div><div style="padding:0px 2px">Also, static imports can make these calls less ceremonious: createObjectBinding(() -> new Point2D(x.get(), y.get()), x, y);</div><div style="padding:0px 2px"><br></div><div style="padding:0px 2px">The proposal is more ergonomic with its fluency for a couple of values, but I'm not sure it solves enough problems that the current mechanism can't.</div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sun, Oct 26, 2025 at 11:59 AM John Hendrikx <<a href="mailto:john.hendrikx@gmail.com">john.hendrikx@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">JEP: <a href="https://gist.github.com/hjohn/611acb65769b68a845b8919c62a3e99a" rel="noreferrer" target="_blank">https://gist.github.com/hjohn/611acb65769b68a845b8919c62a3e99a</a><br>
<br>
Hi everyone,<br>
<br>
I'd like to propose an extension to the fluent bindings API on<br>
ObservableValue (map, flatMap, orElse) which were introduced in JavaFX<br>
19 over 3 years ago.<br>
<br>
The API currently is very powerful when dealing with a single<br>
observable, but lacks support when dealing with multiple observables. <br>
For example, let's say you want to compute a width/height ratio. You<br>
could write this:<br>
<br>
ObservableValue<Double> ratio = width.map(w -> w / height.get());<br>
<br>
... but you'll quickly find that such an observable will not update<br>
itself when height changes, only when width changes.<br>
<br>
The go-to solution for this is currently:<br>
<br>
DoubleBinding ratio = new DoubleBinding() {<br>
{ bind(width, height); }<br>
<br>
protected double computeValue() { return width.get() /<br>
height.get(); }<br>
}<br>
<br>
My proposal would extend ObservableValue with a new `with` method that<br>
returns an intermediate stage that can be easily converted back to an<br>
ObservableValue:<br>
<br>
ObservableValue<Double> ratio = width.with(height).map((w, h) -> w /<br>
h); // yields a ratio that updates whenever w or h changes<br>
<br>
Or for example:<br>
<br>
ObservableValue<Point> point = x.with(y).map(Point::new); //<br>
yields a Point that updates whenever x or y changes<br>
<br>
The intermediate stage would not be an observable value itself. This<br>
limits the API surface, and makes this proposal fairly lightweight and<br>
much easier to implement.<br>
<br>
Please see the JEP for the full proposal. I look forward to your feedback!<br>
<br>
--John<br>
<br>
<br>
</blockquote></div>