The TimeClient
Home ] Up ] The Remote Interfaces ] The TimeServer ] [ The TimeClient ] Running the Example ]

 

 

Here's the TimeClient:

package rmiClient;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import rmi.Time;

import rmiServer.TimeServer;

/**
 * A Time client class
 *
 * @author Bryan Higgs
 * @version 1.0
 */
public class TimeClient
    extends JFrame
{
  /**
   * Creates a new instance of TimeClient
   */
  public TimeClient()
  {
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    
    JPanel panel = new JPanel( new BorderLayout() );
    setContentPane(panel);
    panel.add( new JScrollPane(m_textArea), BorderLayout.CENTER );
    
    JPanel buttonPanel = new JPanel();
    panel.add(buttonPanel, BorderLayout.SOUTH);
    buttonPanel.add(m_connectButton);
    m_connectButton.addActionListener( new ActionListener()
    {
      public void actionPerformed(ActionEvent event)
      {
        connect();
      }
    }
    );
    buttonPanel.add(m_clearButton);
    m_clearButton.addActionListener( new ActionListener()
    {
      public void actionPerformed(ActionEvent event)
      {
        m_textArea.setText("");
      }
    }
    );
    
    pack();
  }
  
  /**
   * Connect to the time server
   */
  private void connect()
  {
    try
    {
      String serverURL = "rmi://" + HOST + ":" + PORT + "/TimeServer" ;      
      System.out.println( "Looking up TimeService at: " + serverURL );
      Time stub = null;
      try
      {
        stub = (Time) Naming.lookup(serverURL);
      }
      catch (NotBoundException nbe)
      {
        nbe.printStackTrace();
      }
      catch (MalformedURLException mue)
      {
        mue.printStackTrace();
      }
      
      System.out.println("Exporting the TimeMonitor object");
      TimeMonitorImpl monitor = new TimeMonitorImpl(m_textArea);
      UnicastRemoteObject.exportObject(monitor, 0);
      
      // Register the time monitor
      stub.registerTimeMonitor(monitor);
      System.out.println("We are registered!");
    }
    catch ( RemoteException re )
    {
      System.out.println( "" + re );
    }
  }
  
  /**
   * Main entry point
   */
  public static void main(String[] args)
  {
    System.err.println("Setting java.security.policy ...");
    System.setProperty("java.security.policy", "policies/client.policy");
    
    // Use a security manager
    System.err.println("Setting SecurityManager ...");
    System.setSecurityManager( new SecurityManager() );
    
    JFrame frame = new TimeClient();
    frame.setVisible(true);
  }
  
  //// Private data ////
  private static final String HOST = "localhost";
  private static final int    PORT = 2002;
  
  private TimeServer m_server;
  private JTextArea  m_textArea = new JTextArea(10, 20);
  private JButton    m_connectButton = new JButton("Connect");
  private JButton    m_clearButton = new JButton("Clear");
}

/**
 * A Class that implements the TimeMonitor interface
 */
class TimeMonitorImpl implements TimeMonitor
{
  TimeMonitorImpl(JTextArea textArea)
  {
    m_textArea = textArea;
  }
  
  /**
   * The method to be called back
   */
  public void tellMeTheTime(Date time)
  {
    m_textArea.append(time + "\n" );
  }

  /// Private data ////
  private JTextArea m_textArea;
}

Note that:

  • We must use a security manager and specify a security policy.  In this case, the client security policy needed to be:
    grant
    {
      permission java.net.SocketPermission
        "localhost:1024-65535", "connect,accept";
      permission java.awt.AWTPermission
        "showWindowWithoutWarningBanner";
    };

    That is, we must specify socket connect and access permissions.

    The second permission suppresses a "Java Applet Window" label that is displayed on any part of the GUI.

  • We must export the class that implements the TimeMonitor interface, so that it may be called (back).
 
The page was last updated February 19, 2008