Using the observable interface

How do I use the observable interface in Java?
part of my program:

while(true)
        {
            //Accept the connection request
            //Create a thread to deal with the Client
            try{
            MessageClientThread client = new MessageClientThread(myServerSocket.accept());
            //state.addObserver(client);
            this.addObserver(client);
            client.start();
            } catch (IOException e){
             System.err.println("Error accepting client connection!");
             System.exit(-1);
            }
        }
    }

as you can see it adds observers to itself, which are threads that implement the observer interface.  The threads receive messages from clients on the network.  when they do this, i want them to tell the server code(above) that they have received a message, so that all the clients can be notified of the change and update themselves with the new message.  Basiclly i am implementing a simple messenger program that when a client sends a message to the server, it is replicated on all other clients connected screens.

How do I call the notifyObservers and pass information between the server program and the client threads?
confused!


Thanks

Ashley :-)
ashleycokerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

TimYatesCommented:
ashleycokerAuthor Commented:
so what?  I need an explanation not a web link!! no offence!

basically, i am getting confused here:  the client thread has to notify all the other client threads that it has a new message, via the server main thread??

in these examples the server notifies the clients, but in my implementation one of the clients has to notify the server so that it can notify all the other clients.

How, when you create an object from a procedure, can it let the object that created it know anything apart from in return values?, like with my threads, the clients run in a loop.  How can they talk to the server that created them?

Thanks
Ashley :-)
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

TimYatesCommented:
>  so what?  I need an explanation not a web link!! no offence!

If you click on the links, they both lead to explanations... ;-)

(j/k)

Pass the server through to the thread client (in the constructor)

MessageClientThread client = new MessageClientThread( this, myServerSocket.accept() );

Then, make the server an Observer, and in the client, do:

this.addObserver( server ) ;

then, whenever things change (in the client), you should be able to do:

this.setChanged() ;
this.notifyObservers( "I have changed!" ) ;
TimYatesCommented:
(assuming your client is Observable) :-)

Hope this helps!!

Tim
girionisCommented:
>  the client thread has to notify all the other client threads that it has a new message, via the
>server main thread??

  If the server is register to be an observer then it can observe for events from the client. When you call the method notifyObeservers() in the client then when a change is made you notify all registered observers (the server in your case). On the other hand the server can notify its own observers for changes that occured.
TimYatesCommented:
>  the client thread has to notify all the other client threads that it has a new message, via the
>server main thread??

Ahhhh...didn't read this properly...

You can still use my way above, in the server's "update" method, you can just iterate through the list of clients, and notify all of them except for the one that sent the original notification (which will be the first parameter of the update method)

So basically, the server, and the clients have to be both Observers, AND Observable...

With the server Observing all the clients, and each client observing the server...

Tim
ashleycokerAuthor Commented:
This is a problem because my clients are threads which means I would have to extend both the Thread interface and the Observable interface, but this is illigal isn't it?

      public class MessageClientThread extends Thread implements Observer{

       -------

       }

I cant also write 'extends Observable' because it causes a compiler error.  Help!

Ashley :-)
TimYatesCommented:
> which means I would have to extend both the Thread interface and the Observable interface, but this is illigal isn't it?

Nope...

Thread is a class...you extend classes

Observer and Observable are interfaces....you implement interfaces :-)

public class MessageClientThread extends Thread implements Observer, Observable {

should be fine...
ashleycokerAuthor Commented:
That doesn't work!
The compiler error is:

     JavaExamples/MessageClientThread.java [18:1] interface expected here

My other class works fine with:

     public class MessageServer extends Observable implements Observer{

Ashley
TimYatesCommented:
Ahhhh....Observable is a class...

Observer is an interface...

you can do:

public class MessageClientThread extends Observable, implements Observer, Runnable
{
}
TimYatesCommented:
extending runnable means you have to do your threading like this:

public class MessageClientThread extends Observable, implements Observer, Runnable
{
    private Thread runner = null ;

    ....

    public void start()
    {
        if( runner == null )
        {
            runner = new Thread( this ) ;
            runner.start() ;
        }
    }

    public void run()
    {
        while( runner != null )
        {
          ....
        }
    }

    public void stop()
    {
        runner = null ;
    }
}
ashleycokerAuthor Commented:
What is the runnable part, something to do with threads?
Does my class still work the same?  i.e. do i still override the run() method?
TimYatesCommented:
>  Does my class still work the same?  

you have to override the "start" method like I showed above to create a thread that will run this Runnable class

> i.e. do i still override the run() method?

Yep, the run method should be exactly the same as your Thread class :-)

(the example I gave will run until you call "stop" -- this may not be what you want, it was just an example) :-)

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ashleycokerAuthor Commented:
Thanks Tim, this all worked great!

One more quick question if you dont mind, ill give you some more points for it!  My clients need to have their GUI updated in a separate thread that runs constantly checking for messages from the server.  Here is my client code:

public class MessageGUI extends JPanel implements ActionListener{
    JButton sayButton;
    JTextField message;
    JTextArea history;
    MessageClient myClient;
    String received = null;
    /** Creates a new instance of MessageGUI */
    public MessageGUI() {
        myClient = new MessageClient();
       
        sayButton = new JButton("Say");
        message = new JTextField(20);
        history = new JTextArea(10, 20);
       
        history.setEditable(false);
       
        //This works but we are going to use messageClient class
        //as Listerner instead
        sayButton.addActionListener(this);
        //sayButton.addActionListener(myClient);
       
        add(message);
        add(sayButton);
        add(history);
    }
   
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //Create  frame
        JFrame MessageFrame = new JFrame("Message Client");
        MessageFrame.setContentPane(new MessageGUI());
       
        MessageFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MessageFrame.pack();
        MessageFrame.setVisible(true);
               
    }
   
    public void actionPerformed(ActionEvent e) {
        //this uses myClient to send messages
        //any waiting here will cause GUI to wait until it is updated
        received = myClient.sendMessage(message.getText());
       
        //This would update the screen with message but is done using another thread
        //history.append(received + '\n');
    }
   
}

How do I implement a thread that can run alongside this code and update the GUI when a new message is received?

Thanks

Ashley :-)
TimYatesCommented:
> //This would update the screen with message but is done using another thread

Can't you pass that other thread to this class (in the constructor ?), and call a method on it to update the screen?

Good luck!

Tim
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.