public class LectorScribe implements Scribe, Animate
{
private Writer out;
private Reader in;
private AnimatorThread mover;
private LectorListener ll;
            
      // make a LectorScribe from a Writer and a Reader
      public LectorScribe( Writer out, Reader in )
{
    this.out = out;
    this.in = in;
    this.mover = new AnimatorThread( this );
    this.mover.start();
}
      
      //...from an OutputStream and an InputStream, by decorating them
      public LectorScribe( OutputStream out, InputStream in )
{
    this( new OutputStreamWriter( out ),
          new InputStreamReader( in ) );
}
      
      //...from a Socket, by accessing its streams
      public LectorScribe( Socket sock ) throws IOException
{
    this( sock.getOutputStream(), sock.getInputStream() );
}
      
      //...from a hostname and port to connect to
      public LectorScribe( String hostname, int port ) throws IOException
{
    this( new Socket( hostname, port ) );
}
      
      //...from a ServerSocket, by accepting a connection
      public LectorScribe( ServerSocket serv ) throws IOException
{
    this( serv.accept() );
}
      
      //...from a port, by listening on it
      public LectorScribe( int port ) throws IOException
{
    this( new ServerSocket( port ) );
}
      
public void act()
{
    try
    {
        this.ll.messageRead( this.in.read() );
    } 
    catch (IOException e)
    {
        System.err.println( "Oops, I couldn't read a line!" );
    }
}
      
public void send( String m )
{
    try
    {
        this.out.write( m );
        this.out.flush();    // (maybe)
    } 
    catch (IOException e)
    {
        System.err.println( "Oops, I couldn't write a line!" );
    }
}
      
public void addLectorListener( LectorListener ll )
{
    this.ll = ll;
}
}