JavaBeanBooleanProperty не обновляется при запуске события PropertyChangeSupportJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 JavaBeanBooleanProperty не обновляется при запуске события PropertyChangeSupport

Сообщение Anonymous »

Я создаю игру жизни на JavaFX и хочу двунаправленно связать Label.styleProperty() и логическое значение GameOfLifeCell. Привязка работает только в одном направлении: при обновлении пользовательского интерфейса обновляется и значение Java Bean, но не наоборот. Я сузил проблему до того, что JavaBeanBooleanProperty не обнаруживает, когда вызывается GameOfLifeCell.updateState().
Я использую JavaBeanBooleanPropertyBuilder.
private JavaBeanBooleanProperty buildAliveProperty(GameOfLifeCell modelCell) throws NoSuchMethodException {
return JavaBeanBooleanPropertyBuilder.create()
.bean(modelCell)
.name("value")
.getter("isAlive")
.setter("updateState")
.build();
}

Из того, что я узнал из документации, форумов и исходного кода JavaFX, я знаю, что для автоматического обновления встроенного свойства в JavaBean должна быть правильно реализована поддержка PropertyChangeSupport. В исходном коде JavaFX я обнаружил, что он ищет методы с именами addPropertyChangeListener и RemovePropertyChangeListener или (при условии, что name("value") указано, как указано) addValueListener и RemoveValueListener. Я попробовал использовать оба этих варианта, и это, похоже, не помогает. Вот как выглядит текущая реализация моего Java Bean:
package pl.km251578.md247645.gameoflife.board;

//... imports

public class GameOfLifeCell implements Serializable, Comparable, Cloneable {
//...

private boolean value;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

public GameOfLifeCell(boolean value) {
this.value = value;
}

public void updateState(boolean newState) {
boolean oldState = this.value;
this.value = newState;
pcs.firePropertyChange("value", oldState, newState);
}

//...

public boolean isAlive() {
return value;
}

public void addPropertyChangeListener(PropertyChangeListener listener) {
if (!Arrays.asList(pcs.getPropertyChangeListeners()).contains(listener)) {
pcs.addPropertyChangeListener(listener);
}
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}

//...
}

Я часами думал о возможных решениях, даже читал исходный код JavaFX и консультировался со своим профессором, но мне все еще не хватает ответа.ДЛЯ ПРОЯСНОСТИ Я не ищу обходного пути или какого-либо другого решения, поскольку я уже просто делаю то, что JavaBeanBooleanProperty должен делать за меня, что слушает изменения GameOfLifeCell.value. Я ищу способ заставить это конкретное решение работать так, как задумано.
modelCell.addPropertyChangeListener((event) -> {
aliveProperty.set((boolean) event.getNewValue());
});

Я создал минимальный воспроизводимый пример, чтобы показать ту же проблему, что и у меня. Для его запуска вам понадобится org.openjfx.javafx-controls
import javafx.application.Platform;
import javafx.beans.property.adapter.JavaBeanBooleanProperty;
import javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder;
import javafx.scene.control.Label;
import javafx.util.StringConverter;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Main {
public static void main(String[] args) {
Platform.startup(() -> {
Bean bean = new Bean(false);
try {
JavaBeanBooleanProperty aliveProperty = JavaBeanBooleanPropertyBuilder.create()
.bean(bean)
.name("value")
.getter("isAlive")
.setter("updateState")
.build();

Label label = new Label("");
label.setStyle(CellStateStyleConverter.getStyleForViewCell(false));
label.styleProperty().bindBidirectional(aliveProperty, new CellStateStyleConverter());
System.out.println("Both should be false");
printValues(aliveProperty, label);
System.out.println("View set to true");
label.setStyle(CellStateStyleConverter.getStyleForViewCell(true));
printValues(aliveProperty, label);
System.out.println("Model set to false");
bean.updateState(false);
printValues(aliveProperty, label);

} catch (NoSuchMethodException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
});
}

public static void printValues(JavaBeanBooleanProperty aliveProperty, Label label){
//JavaBeanBooleanProperty.get() returns Bean.isAlive(), so they'll always match
System.out.println("Current values: ");
System.out.println("model value: " + aliveProperty.get());
System.out.println("view value: " + (label.styleProperty().get().equals(CellStateStyleConverter.getStyleForViewCell(true))));
System.out.println("\n\n");
}

public static class CellStateStyleConverter extends StringConverter {
@Override
public String toString(Boolean object) {
return getStyleForViewCell(object);
}

@Override
public Boolean fromString(String string) {
return string.equals(getStyleForViewCell(true));
}

public static String getStyleForViewCell(boolean isAlive) {
StringBuilder style = new StringBuilder();
style.append("-fx-border-color: black; -fx-background-color: ");
if(isAlive) {
style.append("black;");
} else {
style.append("white;");
}
return style.toString();
}
}

public static class Bean{
private boolean value;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

public Bean(boolean value){
this.value = value;
}

public void addPropertyChangeListener(PropertyChangeListener listener){
pcs.addPropertyChangeListener(listener);
}

public void removePropertyChangeListener(PropertyChangeListener listener){
pcs.removePropertyChangeListener(listener);
}

public void updateState(boolean value){
this.value = value;
}

public boolean isAlive(){
return value;
}
}

}


Подробнее здесь: https://stackoverflow.com/questions/793 ... t-is-fired
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»