Akshay Bande
Akshay Bande

Reputation: 2587

How to use Observer Pattern in java to detect change in Java List?

I want to detect change in my ArrayList myList. Everytime I add, remove or update anything from ArrayList. I want to notify user about it. I have used following code for it. It notifies user when setValues function is used to set list. Is there any other way to implement it so that every time I change list user will get notified? Thank you.

// observable class which will contain my List. 
package com.psl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;

public class MyList extends Observable{

      private List<Map<String,Object>> values;    
    public List<Map<String, Object>> getValues() {
        return values;
    }

    public void setValues(List<Map<String, Object>> values) {

        if(getValues()==null && values!=null){

            setChanged();
            notifyObservers();
        }

        else if( !this.values.equals(values)){
            setChanged();
            notifyObservers();
        }

        this.values = values;
    }

    public static void main(String[] args) {

        MyList myList = new MyList();
        List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
        Notify notify = new Notify();
        myList.addObserver(notify);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("string_value", null);
        myList.setValues(values);                       
    }


}
// Observer which will notify user when list is updated. 

package com.psl;

import java.util.Observable;
import java.util.Observer;

public class Notify implements Observer{

    @Override
    public void update(Observable o, Object arg) {
            System.out.println("List has been changed");                
    }

}

Upvotes: 5

Views: 4679

Answers (2)

Marat
Marat

Reputation: 204

You can use inheritance and two own interfaces. (Because we can't extend 2 classes)

import java.util.ArrayList;
import java.util.List;

public class ObserverExample {
    public static void main(String[] args) {
        MyList<Integer> myList = new MyList<>();
        Notify notify = new Notify();
        myList.addObserver(notify);
        myList.add(1);
    }
}


interface Observable {
    void notifyObservers();
    void addObserver(Observer o);
}

interface Observer {
    void update(Observable o, Object arg);
}


class MyList<E> extends ArrayList<E> implements Observable{
    List<Observer> observers = new ArrayList<>();

    @Override
    public boolean add(E e) {
        notifyObservers();
        return super.add(e);
    }

    @Override
    public void notifyObservers() {
        for (Observer o :observers) {
            o.update(this, null);
        }
    }

    @Override
    public void addObserver(Observer o) {
        observers.add(o);
    }
}

class Notify implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("List has been changed");
    }
}

You also can override other list methods and add notifyObservers(); into each of them.

Upvotes: 2

eltabo
eltabo

Reputation: 3807

JavaFX has an implementation of ObservableList, maybe you can use it:

javafx.collections.ObservableList a = javafx.collections.FXCollections.observableArrayList();
a.addListener(new javafx.collections.ListChangeListener<String>() {
    @Override
    public void onChanged(Change<? extends String> c) {
        System.out.println(c);
    }});

a.add("aa");
a.add("bb");

Upvotes: 4

Related Questions