Я создаю игру жизни на 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
JavaBeanBooleanProperty не обновляется при запуске события PropertyChangeSupport ⇐ JAVA
Программисты JAVA общаются здесь
1736601087
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 и консультировался со своим профессором, но мне все еще не хватает ответа.[b]ДЛЯ ПРОЯСНОСТИ[/b] Я не ищу обходного пути или какого-либо другого решения, поскольку я уже просто делаю то, что 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;
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79348150/javabeanbooleanproperty-doesnt-update-when-propertychangesupport-event-is-fired[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия