ashleycoker
asked on
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(myServ erSocket.a ccept());
//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 :-)
part of my program:
while(true)
{
//Accept the connection request
//Create a thread to deal with the Client
try{
MessageClientThread client = new MessageClientThread(myServ
//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 :-)
ASKER
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 :-)
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 :-)
> 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!" ) ;
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!" ) ;
(assuming your client is Observable) :-)
Hope this helps!!
Tim
Hope this helps!!
Tim
> 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.
>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.
> 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
>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
ASKER
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 :-)
public class MessageClientThread extends Thread implements Observer{
-------
}
I cant also write 'extends Observable' because it causes a compiler error. Help!
Ashley :-)
> 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...
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...
ASKER
That doesn't work!
The compiler error is:
JavaExamples/MessageClient Thread.jav a [18:1] interface expected here
My other class works fine with:
public class MessageServer extends Observable implements Observer{
Ashley
The compiler error is:
JavaExamples/MessageClient
My other class works fine with:
public class MessageServer extends Observable implements Observer{
Ashley
Ahhhh....Observable is a class...
Observer is an interface...
you can do:
public class MessageClientThread extends Observable, implements Observer, Runnable
{
}
Observer is an interface...
you can do:
public class MessageClientThread extends Observable, implements Observer, Runnable
{
}
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 ;
}
}
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 ;
}
}
ASKER
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?
Does my class still work the same? i.e. do i still override the run() method?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.addActionListene r(this);
//sayButton.addActionListe ner(myClie nt);
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.setContentPan e(new MessageGUI());
MessageFrame.setDefaultClo seOperatio n(JFrame.E XIT_ON_CLO SE);
MessageFrame.pack();
MessageFrame.setVisible(tr ue);
}
public void actionPerformed(ActionEven t e) {
//this uses myClient to send messages
//any waiting here will cause GUI to wait until it is updated
received = myClient.sendMessage(messa ge.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 :-)
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.addActionListene
//sayButton.addActionListe
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.setContentPan
MessageFrame.setDefaultClo
MessageFrame.pack();
MessageFrame.setVisible(tr
}
public void actionPerformed(ActionEven
//this uses myClient to send messages
//any waiting here will cause GUI to wait until it is updated
received = myClient.sendMessage(messa
//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 :-)
> //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
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
http://javaalmanac.com/egs/java.util/Obs.html?l=find