Search code examples
javajavafxobserver-pattern

Using Observer pattern to move labels (JavaFx)


I am creating a chat program where my chat persons are a label. the labels can be moved around on the screen when the user clicks on the anchorpane now there are two senerios here:

  1. The chatperson has to locally move.

  2. the client has to send this movement to all the other connected clients.

The 2nd case is easy enough if the objects works as they should currently my ChatPerson object looks like this:

 package GUI;


public class ChatPerson {

    private String username;
    private int x;
    private int y;
    // Brugerens ID i databasen
    private int id;

    public ChatPerson(String name){
        this.username = name;
    }

    public String getUserName(){
        return username;
    }
    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }
    public int getX(){
        return x;
    }
    public int getY(){
        return y;
    }
    public int getId(){
        return id;
    }
    public void setId(int id){
        this.id = id;
    }



}

My question is how would i implement this sort of behavior. ive looked up the Observer pattern but i am finding it hard on how to put it to work in this case?

Also, do JavaFx have some sort of implementation that i could use here? Ive looked at Observablelist but i cant really get my mind through how that would help me?


Solution

  • You can use the observer pattern in this case. I assume you have a list of connected people somewhere on each client. if this is some it should be quite simple to notify the other people of the move event. Simply make the ChatPerson observable like so

    public class ChatPerson {
         //your props here :P...
        private final List<MoveListener> listeners = new ArrayList<MoveListener>();
    
        private void notifyListeners(MoveEvent e){
            for(MoveListener l : listeners){
                 l.onMoveEvent(e);
            }
        }
        public void addMoveListener(MoveListener l){
            this.listeners.add(l);
        }
        public void removeMoveListener(MoveListener l){
            this.listeners.remove(l);
        }
    
        //i would create a move method but you can do this on setX() and setY()
        public void move(int x,int y){
            this.x=x;
            this.y=y;
            this.notifyListeners(new MoveEvent(this,x,y));
        }
        //your other method...
    }
    

    Now for the MoveListener Interface.

    public interface MoveListener{
        public void onMoveEvent(MoveEvent e);
    }
    

    And the MoveEvent.

    public class MoveEvent{
        public final ChatPerson source;//i could be more generic but you get the ideea
        public final int currentX;
        public final int currentY;
        public MoveEvent(ChatPerson source, int x,int y){
            this.source = source;
            this.currentX = x;
            this.currentY = y;
        }
        //you can make the fields private and getters ofc :P
    }
    

    Now whenever the ChatPerson moves, it broadcast its position in a nice and generic way, its up to each listener to its stuff in response to this event.
    In the container class (the one with the list of connected people) simply implement a MoveListener and add it to the current ChatPerson.
    In this implementation you can iterate over the list of connected people and send the current position "over the wire" so to speak. Without more detail on how your app is implemented I can't really give a better answer.
    Hope it this helps.