Search code examples
javamodel-view-controllerobserver-pattern

Observer doesn't call update method


Hey there I have a MVC Java Applcation which uses the observer pattern to notify my view on every change.
I have a starter class to initialize all classes and set up everything for my MVC pattern.

public static void main(String[] args) {
        FXView view = new FXView();
        JSONModel model = new JSONModel();
        model.addObserver(view);
        Controller controller = new Controller(view, model);
        view.registerController(controller);
        FXView.launch(FXView.class);
}

I have a Model which does extend from Observable and has a method to write a file. There I want to call setChanged() and notifyObserver().

public void writeFile() {
        try {
            FileWriter file = new FileWriter("C://path/to/file.json");
            file.write(obj.toJSONString());
            file.flush();
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        setChanged();
        notifyObservers(obj);
}

Every time the file gets written I want my view to know about it. My view does implement Observer and has therefore the update()method.

@Override
public void update(Observable o, Object arg) {
    JSONModel model = (JSONModel)o;
    this.obj = model.getObj();
}

Using the debugger I could not detect an invoking of my update method. When I start the program --> when I go to my Starter class and call "Run as Java Application", my model loads a default value and then calls writeFile(). The file gets created and setChanged() as well as notifyObserver() gets called but update() won't be invoked. Is there something I miss out?


Solution

  • As it seems, the call to notifyOberservers during the startup-phase is done before the Oberserver is added.

    This can be solved by creating a Contructor that takes and adds an Oberserver first, before calling update.

    Another approach would be an empty constructor and moving the init code to a different method. So you can call addObserver after creating the instance and then call the initialization method.

    Personally, I'd go for the first one, because we do not want to be able to create instances that are uninitialized (= undefined state).