Java Rmi 简明教程

Java RMI - GUI Application

在前面的章节中,我们创建了一个示例 RMI 应用程序。在本章中,我们将说明如何创建 RMI 应用程序,其中客户端调用显示 GUI 窗口(JavaFX)的方法。

In the previous chapter, we created a sample RMI application. In this chapter, we will explain how to create an RMI application where a client invokes a method which displays a GUI window (JavaFX).

Defining the Remote Interface

在此,我们定义一个名为 Hello 的远程接口,其中包含一个名为 animation() 的方法。

Here, we are defining a remote interface named Hello with a method named animation() in it.

import java.rmi.Remote;
import java.rmi.RemoteException;

// Creating Remote interface for our application
public interface Hello extends Remote {
   void animation() throws RemoteException;
}

Developing the Implementation Class

在此应用程序的实现类(远程对象)中,我们尝试使用 JavaFX 创建一个显示 GUI 内容的窗口。

In the Implementation class (Remote Object) of this application, we are trying to create a window which displays GUI content, using JavaFX.

import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;

import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;

import javafx.scene.shape.Box;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;

import javafx.stage.Stage;
import javafx.util.Duration;

// Implementing the remote interface
public class FxSample extends Application implements Hello {
   @Override
   public void start(Stage stage) {
      // Drawing a Box
      Box box = new Box();

      // Setting the properties of the Box
      box.setWidth(150.0);
      box.setHeight(150.0);
      box.setDepth(100.0);

      // Setting the position of the box
      box.setTranslateX(350);
      box.setTranslateY(150);
      box.setTranslateZ(50);

      // Setting the text
      Text text = new Text(
         "Type any letter to rotate the box, and click on the box to stop the rotation");

      // Setting the font of the text
      text.setFont(Font.font(null, FontWeight.BOLD, 15));

      // Setting the color of the text
      text.setFill(Color.CRIMSON);

      // Setting the position of the text
      text.setX(20);
      text.setY(50);

      // Setting the material of the box
      PhongMaterial material = new PhongMaterial();
      material.setDiffuseColor(Color.DARKSLATEBLUE);

      // Setting the diffuse color material to box
      box.setMaterial(material);

      // Setting the rotation animation to the box
      RotateTransition rotateTransition = new RotateTransition();

      // Setting the duration for the transition
      rotateTransition.setDuration(Duration.millis(1000));

      // Setting the node for the transition
      rotateTransition.setNode(box);

      // Setting the axis of the rotation
      rotateTransition.setAxis(Rotate.Y_AXIS);

      // Setting the angle of the rotation
      rotateTransition.setByAngle(360);

      // Setting the cycle count for the transition
      rotateTransition.setCycleCount(50);

      // Setting auto reverse value to false
      rotateTransition.setAutoReverse(false);

      // Creating a text filed
      TextField textField = new TextField();

      // Setting the position of the text field
      textField.setLayoutX(50);
      textField.setLayoutY(100);

      // Handling the key typed event
      EventHandler<KeyEvent> eventHandlerTextField = new EventHandler<KeyEvent>() {
         @Override
         public void handle(KeyEvent event) {
            // Playing the animation
            rotateTransition.play();
         }
      };

      // Adding an event handler to the text feld
      textField.addEventHandler(KeyEvent.KEY_TYPED, eventHandlerTextField);

      // Handling the mouse clicked event(on box)
      EventHandler<javafx.scene.input.MouseEvent> eventHandlerBox =
         new EventHandler<javafx.scene.input.MouseEvent>() {
         @Override
         public void handle(javafx.scene.input.MouseEvent e) {
            rotateTransition.stop();
         }
      };

      // Adding the event handler to the box
      box.addEventHandler(javafx.scene.input.MouseEvent.MOUSE_CLICKED, eventHandlerBox);

      // Creating a Group object
      Group root = new Group(box, textField, text);

      // Creating a scene object
      Scene scene = new Scene(root, 600, 300);

      // Setting camera
      PerspectiveCamera camera = new PerspectiveCamera(false);
      camera.setTranslateX(0);
      camera.setTranslateY(0);
      camera.setTranslateZ(0);
      scene.setCamera(camera);

      // Setting title to the Stage
      stage.setTitle("Event Handlers Example");

      // Adding scene to the stage
      stage.setScene(scene);

      // Displaying the contents of the stage
      stage.show();
   }

   // Implementing the interface method
   public void animation() {
      launch();
   }
}

Server Program

RMI 服务器程序应该实现远程界面或扩展实现类。在这里,我们应该创建一个远程对象并将它绑定到 RMIregistry

An RMI server program should implement the remote interface or extend the implementation class. Here, we should create a remote object and bind it to the RMIregistry.

以下是在这个应用程序中所用的服务器程序。在这里,我们将扩展上面所创建的类、创建一个远程对象并用 bind 名称 hello 将其注册到 RMI 注册表中。

Following is the server program of this application. Here, we will extend the above created class, create a remote object, and registered it to the RMI registry with the bind name hello.

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends FxSample {
   public Server() {}
   public static void main(String args[]) {
      try {
         // Instantiating the implementation class
         FxSample obj = new FxSample();

         // Exporting the object of implementation class
         // (here we are exporting the remote object to the stub)
         Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

         // Binding the remote object (stub) in the registry
         Registry registry = LocateRegistry.getRegistry();

         registry.bind("Hello", stub);
         System.err.println("Server ready");
      } catch (Exception e) {
         System.err.println("Server exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

Client Program

以下是在这个应用程序中所用的客户端程序。在这里,我们将获取远程对象并调用其名称为 animation() 的方法。

Following is the client program of this application. Here, we are fetching the remote object and invoking its method named animation().

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
   private Client() {}
   public static void main(String[] args) {
      try {
         // Getting the registry
         Registry registry = LocateRegistry.getRegistry(null);

         // Looking up the registry for the remote object
         Hello stub = (Hello) registry.lookup("Hello");

         // Calling the remote method using the obtained object
         stub.animation();

         System.out.println("Remote method invoked");
      } catch (Exception e) {
         System.err.println("Client exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

Steps to Run the Example

以下是运行我们的 RMI 示例所需的步骤。

Following are the steps to run our RMI Example.

Step 1 − 打开已存储所有程序的文件夹,并按以下操作编译所有 Java 文件。

Step 1 − Open the folder where you have stored all the programs and compile all the Java files as shown below.

Javac *.java
stored programs

Step 2 − 使用以下命令启动 rmi 注册表。

Step 2 − Start the rmi registry using the following command.

start rmiregistry
start execution

这会在一个单独的窗口中启动一个 rmi 注册表,如下所示。

This will start an rmi registry on a separate window as shown below.

separate window

Step 3 − 按以下操作运行服务器类文件。

Step 3 − Run the server class file as shown below.

Java Server
run server

Step 4 - 如下所示运行客户端类文件。

Step 4 − Run the client class file as shown below.

java Client
client class

Verification - 在启动客户端后,您很快就会在服务器中看到以下输出。

Verification − As soon you start the client, you would see the following output in the server.

event handler