JavaFX:将 List<A> 双向绑定(bind)到 List<B> 会抛出 StackOverflowError

标签 java javafx data-binding stack-overflow

我正在尝试绑定(bind)两个 ListProperties双向。问题是,它们有不同的类型(A 和 B)。

Test4#test01()说明了我想做的事情。

Test4#test02()是我这样做的幼稚方法,但这会导致 StackOverflowError

如何绑定(bind)List<A>双向至List<B>使用给定的AB变压器和BA变压器? 这是一个 MWE:

public class Test4 {

    public Test4() {

    }

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }

    class A {
    @Override
    public boolean equals(final Object obj) {
        return obj instanceof A;
    }
    }

    class B {
    @Override
    public boolean equals(final Object obj) {
        return obj instanceof B;
    }
    }

    ListProperty<A> listA = new SimpleListProperty<>(FXCollections.observableArrayList());

    ListProperty<B> listB = new SimpleListProperty<>(FXCollections.observableArrayList());

    Function<A, B> trivialTransformerAB = a -> new B();

    Function<B, A> trivialTransformerBA = b -> new A();

    ListChangeListener<A> listAListener;

    ListChangeListener<B> listBListener;

    @Test
    public void test01() {
    // Bindings.bindContentBidirectional(listA, listB,
    // trivialTransformerAB, trivialTransformerBA);
    }

    @Test
    public void test02() {
    listAListener = c -> {
        while (c.next()) {
        if (c.wasRemoved() || c.wasUpdated()) {
            c.getList().subList(c.getFrom(), c.getTo())
                .forEach(a -> listB.remove(trivialTransformerAB.apply(a)));
        }
        if (c.wasAdded() || c.wasUpdated()) {
            c.getList().subList(c.getFrom(), c.getTo()).forEach(a -> {
            final B b = trivialTransformerAB.apply(a);
            if (!listB.contains(b)) {
                listB.add(trivialTransformerAB.apply(a));
            }
            });
        }
        }
    };
    listBListener = c -> {
        while (c.next()) {
        if (c.wasRemoved() || c.wasUpdated()) {
            c.getList().subList(c.getFrom(), c.getTo())
                .forEach(b -> listA.remove(trivialTransformerBA.apply(b)));
        }
        if (c.wasAdded() || c.wasUpdated()) {
            c.getList().subList(c.getFrom(), c.getTo()).forEach(b -> {
            final A a = trivialTransformerBA.apply(b);
            if (!listA.contains(a)) {
                listA.add(trivialTransformerBA.apply(b));
            }
            });
        }
        }
    };
    listA.addListener(listAListener);
    listB.addListener(listBListener);

    listA.add(new A());
    assertThat(listB.size(), is(1));
    }

}

错误:

java.lang.StackOverflowError
    at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031)
    at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031)
[..]

最佳答案

您设置监听器的方式创建了无限循环。

我建议在这两行中分别设置一个断点并使用调试器单步执行:

listB.add(trivialTransformerAB.apply(a));

listA.add(trivialTransformerBA.apply(b));

关于JavaFX:将 List<A> 双向绑定(bind)到 List<B> 会抛出 StackOverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45649351/

相关文章:

java - Mapstruct - 在整个项目中按名称忽略字段

java - 无法获取 Facebook ID 和电子邮件

java - 使用 xuggler 卡住应用程序

css - Javafx、css、为分割 Pane 设置背景图片?

c# - WPF ComboboxItem 绑定(bind)

javascript - 根据用户选择 knockout 更改数据绑定(bind)

javascript - 使用 applyBindingsToNode 从元素绑定(bind)调用 viewmodel 函数失败

java - 如何使数组按 Product[counter].getProductTitle() 排序?

java - 在启动时删除 gluon-mobile 对话框

java - 如何绕过 JavaFX 的 TableView "placeholder"?