On Mon, 12 Jul 2021 22:27:12 GMT, Kevin Rushforth <k...@openjdk.org> wrote:

>> The following unit test demonstrated the *current* behavior, though maybe 
>> it's not the desired one:
>> 
>> 
>> import static org.junit.Assert.*;
>> 
>> import javafx.beans.property.IntegerProperty;
>> import javafx.beans.property.SimpleIntegerProperty;
>> 
>> import org.junit.Before;
>> import org.junit.Test;
>> 
>> public class BindingsTest {
>> 
>>      private IntegerProperty property1, property2, property3;
>> 
>>      @Before
>>      public void setup() {
>>              property1 = new SimpleIntegerProperty(1);
>>              property2 = new SimpleIntegerProperty(2);
>>              property3 = new SimpleIntegerProperty(3);
>>      }
>> 
>>      @Test
>>      public void testBidiAndThenUni() {
>>              property1.bindBidirectional(property2);
>>              assertEquals(2, property1.get());
>>              assertEquals(2, property2.get());
>>              property1.bind(property3);
>>              assertEquals(3, property1.get());
>>              assertEquals(3, property2.get());
>>              assertEquals(3, property3.get());
>>      }
>> 
>>      @Test(expected = RuntimeException.class)
>>      public void setProperty1() {
>>              property1.bindBidirectional(property2);
>>              property1.bind(property3);
>> 
>>              property1.set(4);
>>      }
>> 
>>      @Test
>>      public void setProperty2() {
>>              property1.bindBidirectional(property2);
>>              property1.bind(property3);
>> 
>>              // ignores exception (but still prints stack trace) at
>>              // 
>> com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
>>              property2.set(5);
>>              assertEquals(3, property1.get());
>>              assertEquals(3, property2.get()); // "Bidirectional binding 
>> failed, setting to the previous value"
>>              assertEquals(3, property3.get());
>>      }
>> 
>>      @Test
>>      public void setProperty3() {
>>              property1.bindBidirectional(property2);
>>              property1.bind(property3);
>> 
>>              property3.set(6);
>>              assertEquals(6, property1.get());
>>              assertEquals(6, property2.get());
>>              assertEquals(6, property3.get());
>>      }
>> 
>>      @Test(expected = RuntimeException.class)
>>      public void testUniAndThenBidiOnBound() {
>>              property1.bind(property3);
>>              property1.bindBidirectional(property2);
>>      }
>> 
>>      @Test
>>      public void testUniAndThenBidiOnUnbound() {
>>              property1.bind(property3);
>>              property2.bindBidirectional(property1);
>>              
>>              assertEquals(3, property1.get());
>>              assertEquals(3, property2.get());
>>              assertEquals(3, property3.get());
>>      }
>> }
>> 
>> 
>> My observations:
>> 
>> * `setProperty2()` is weird in that it throws an exception internally which 
>> is ignored by the JVM, and then reverts the change to the unidirectionally 
>> unbound property when it finds out that its counterpart can't be changed. It 
>> makes sense logically, but I don't see a valid use case for this.
>> * `setProperty3()` behaves as I expect it to, but this is effectively 2 
>> chained unidirectional binds: `property3` changes `property1` which changes 
>> `property2`. This is the same as `testUniAndThenBidiOnUnbound()`.
>> 
>> It would make sense to disallow this mixing of bindings on grounds that this 
>> is probably not what the developer wants to do. If we opt to let them do it 
>> but write that it should not be done, we could emit a warning. I'm leaning 
>> towards to fail-fast approach.
>
> I also like documenting it as illegal, but am hesitant to make any 
> implementation change in this area for JavaFX 17 during rampdown. So I would 
> recommend documenting as illegal, but not adding the `@throws` to the docs. 
> We could still say that an exception might be thrown or could say something 
> like "results are undefined". Then in JavaFX 18, we can add the `@throws` and 
> change the implementation to fail fast.

Fine with me.

I didn't look at the current tests, but if it helps, we can add the one I wrote.

-------------

PR: https://git.openjdk.java.net/jfx/pull/533

Reply via email to