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

Step 2 − 使用以下命令启动 rmi 注册表。
Step 2 − Start the rmi registry using the following command.
start rmiregistry

这会在一个单独的窗口中启动一个 rmi 注册表,如下所示。
This will start an rmi registry on a separate window as shown below.

Step 3 − 按以下操作运行服务器类文件。
Step 3 − Run the server class file as shown below.
Java Server

Step 4 - 如下所示运行客户端类文件。
Step 4 − Run the client class file as shown below.
java Client

Verification - 在启动客户端后,您很快就会在服务器中看到以下输出。
Verification − As soon you start the client, you would see the following output in the server.
