사용자 정의 속성을 작성하고이를 관찰 가능 목록에 추가합니다. 그러나 속성 내용이 변경되면 리스너가 호출되지 않습니다. 다음 코드 조각은 '건물'을 보여줍니다Java 8 : Observable List - 속성 변경의 경우 무효화 리스너 또는 변경 리스너가 호출됩니다.
public static final class TestObject {
private final ReadOnlyStringWrapper title = new ReadOnlyStringWrapper();
private final BooleanProperty selected = new SimpleBooleanProperty(false);
public TestObject(String title) {
this.title.set(title);
}
public String getTitle() {
return title.get();
}
public ReadOnlyStringProperty titleProperty() {
return title.getReadOnlyProperty();
}
public boolean getSelected() {
return selected.get();
}
public BooleanProperty selectedProperty() {
return selected;
}
public void setSelected(boolean selected) {
this.selected.set(selected);
}
@Override
public int hashCode() {
return Objects.hash(title.get());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final TestObject other = (TestObject) obj;
return Objects.equals(this.title.get(), other.title.get());
}
@Override
public String toString() {
return "TestObject{" +
"title=" + title.get() +
", selected=" + selected.get() +
'}';
}
}
이 이름과 선택처럼 내 내부 속성 값을 내 POJO 클래스입니다.
public static final class TestProperty extends SimpleObjectProperty<TestObject> {
public TestProperty(String name) {
super(new TestObject(name));
init();
}
public TestProperty(TestObject testObject) {
super(testObject);
init();
}
public String getTitle() {
return getValue().getTitle();
}
public void setSelected(boolean selected) {
getValue().setSelected(selected);
}
public boolean getSelected() {
return getValue().getSelected();
}
public BooleanProperty selectedProperty() {
return getValue().selectedProperty();
}
public ReadOnlyStringProperty titleProperty() {
return getValue().titleProperty();
}
@Override
public void set(TestObject testObject) {
super.set(testObject);
init();
}
@Override
public void setValue(TestObject testObject) {
super.setValue(testObject);
init();
}
private void init() {
if (get() == null)
return;
get().titleProperty().addListener((v, o, n) -> fireValueChangedEvent());
get().selectedProperty().addListener((v, o, n) -> {
fireValueChangedEvent();
});
}
}
이것은 POJO를 기반으로하는 사용자 정의 속성입니다. 모든 속성을 변경하면 내 사용자 정의 속성에 대한 변경 이벤트가 발생합니다.
@Test
public void testSimple() {
final AtomicInteger counter = new AtomicInteger(0);
final TestProperty testProperty = new TestProperty("Test");
testProperty.addListener(observable -> {
System.out.println("New state: " + testProperty.get().toString());
counter.incrementAndGet();
});
testProperty.setSelected(true);
testProperty.setSelected(false);
Assert.assertEquals(2, counter.intValue());
}
이 테스트에서 속성 변경 이벤트가 제대로 작동하는지 확인할 수 있습니다.
@Test
public void testList() {
final AtomicInteger counter = new AtomicInteger(0);
final ObservableList<TestProperty> observableList = new ObservableListWrapper<>(new ArrayList<>());
observableList.add(new TestProperty("Test 1"));
observableList.add(new TestProperty("Test 2"));
observableList.add(new TestProperty("Test 3"));
observableList.addListener(new ListChangeListener<TestProperty>() {
@Override
public void onChanged(Change<? extends TestProperty> change) {
System.out.println("**************");
}
});
observableList.addListener((Observable observable) -> {
System.out.println("New state: " + ((TestProperty) observable).get().toString());
counter.incrementAndGet();
});
observableList.get(1).setSelected(true);
observableList.get(2).setSelected(true);
observableList.get(1).setSelected(false);
observableList.get(2).setSelected(false);
Assert.assertEquals(4, counter.intValue());
}
는하지만이 코드에서 당신은 속성 값이 목록에 변경된 경우 관찰 목록은 무효화 리스너도 변경 리스너를 호출되지 것을 알 수있다.
무엇이 잘못 되었나요?
감사합니다.
(물론 질문과 밀접하게 관련되어 있음) 'ObservableListWrapper'는 공개 API의 일부가 아니며 실제로 사용되어서는 안됩니다. JavaFX의 향후 릴리스에는 이것이있을 것이라는 보장은 없습니다. 'ObservableList' (및 다른 관찰 가능한 콜렉션)를 생성하려면 ['FXCollections'] (http://docs.oracle.com/javase/8/javafx/api/javafx/collections/FXCollections.html)의 팩토리 메소드를 사용하십시오. . –