Java Rmi 简明教程

Java RMI - GUI Application

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

Defining the Remote Interface

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

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 内容的窗口。

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

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

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() 的方法。

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 示例所需的步骤。

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

Javac *.java
stored programs

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

start rmiregistry
start execution

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

separate window

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

Java Server
run server

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

java Client
client class

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

event handler