我正在尝试绑定(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/