Изменение узлов JavaFX в Firebase onDataChange не работает

#firebase #javafx #firebase-realtime-database

# #firebase #javafx #firebase-база данных в реальном времени

Вопрос:

Я работаю над приложением администратора JavaFX, которое работает с базой данных Firebase в реальном времени. Я создал ValueEventListener, который получает нужные мне данные в onDataChange. С этими данными я хочу вызвать вызов метода, который что-то делает с этими данными. Проблема, с которой я столкнулся, заключается в том, что изменение элементов JavaFX изнутри этого метода onDataChange вообще не работает.

Я попытался сузить проблему, поместив все в один класс и поместив всю функциональность в метод onDataChange, но это тоже не сработало.

Что меня больше всего смущает в этом, так это то, что чтение этих элементов работает просто отлично, в то время как их изменение ни к чему не приводит. Это работает, когда я выполняю этот код извне onDataChange.

Код в вспомогательном классе базы данных:

     public void startDropsListener() {
        dropsRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                OverviewController.getInstance().changeNodes();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("Reading from database failed: "   databaseError.getCode());
            }
        });
    }
 

Способ изменения узлов:

     public void changeNodes() {
        System.out.println(title.getText()); // This does return the node's text.
        title.setText("New title"); // Does not update the node's text.
    }
 

Обновить:
Печать заголовка после изменения, похоже, работает, поэтому значение обновляется, несмотря на то, что оно не отображается. Вот код, связанный с экземпляром, на случай, если это может быть проблемой:

     private static OverviewController instance;
    
    public OverviewController() {
        instance = this;
    }

    public static OverviewController getInstance() {
        if(instance == null){
            instance = new OverviewController();
        }
        return instance;
    }
 

Ответ №1:

Не делайте контроллер одноэлементным. и сделайте вот так…

 public class OverviewController implements Initializable{
@FXML
public Label label;

@Override
public void initialize(URL location, ResourceBundle bundle){

DatabaseReference dropsRef = FirbaseDatabase.DatabaseReference("Node");
dropsRef.addValueEventListener(valueEventListener);
}

ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Plateform.runLater(()->label.setText(dataSnashot.getValue(SomeClass.class).getLabel());
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            System.out.println("Reading from database failed: "   databaseError.getCode());
        }
    });
}