Solved

Using the observable interface

Posted on 2003-11-19
16
1,099 Views
Last Modified: 2012-06-27
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 :-)
0
Comment
Question by:ashleycoker
  • 9
  • 5
  • 2
16 Comments
 
LVL 35

Expert Comment

by:TimYates
ID: 9779152
0
 
LVL 35

Expert Comment

by:girionis
ID: 9779180
0
 

Author Comment

by:ashleycoker
ID: 9779213
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 :-)
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9779239
>  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!" ) ;
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9779243
(assuming your client is Observable) :-)

Hope this helps!!

Tim
0
 
LVL 35

Expert Comment

by:girionis
ID: 9779315
>  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.
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9779353
>  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
0
 

Author Comment

by:ashleycoker
ID: 9797561
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 :-)
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 35

Expert Comment

by:TimYates
ID: 9797631
> 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...
0
 

Author Comment

by:ashleycoker
ID: 9797699
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
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9797775
Ahhhh....Observable is a class...

Observer is an interface...

you can do:

public class MessageClientThread extends Observable, implements Observer, Runnable
{
}
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9797797
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 ;
    }
}
0
 

Author Comment

by:ashleycoker
ID: 9797800
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?
0
 
LVL 35

Accepted Solution

by:
TimYates earned 125 total points
ID: 9797812
>  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) :-)
0
 

Author Comment

by:ashleycoker
ID: 9799096
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 :-)
0
 
LVL 35

Expert Comment

by:TimYates
ID: 9799262
> //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
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now