Solved

Using the observable interface

Posted on 2003-11-19
16
1,100 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
topping1 challenge 7 73
firstswap challenge 20 67
for i loop in grovy 1 46
Why method in Java which is called from Runnable run() doesn't need to be 'static'? 1 22
INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

920 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

16 Experts available now in Live!

Get 1:1 Help Now