在上一章中,我们创建了一个RMI应用程序的示例。 在本章中,我们将介绍如何创建一个客户端调用显示GUI窗口(基于JavaFX)的RMI应用程序。
定义远程接口
在这里,首先定义一个名称为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
}
开发实现类
在本应用程序的Implementation
类(远程对象)中,将创建一个使用JavaFX显示GUI内容的窗口。创建一个Java源代码文件:FxSample.java,其代码如下所示 -
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()
}
}
服务器程序
RMI服务器程序应实现远程接口或扩展实现类。 在这里,应该创建一个远程对象并将其绑定到RMIregistry
。
以下是本应用程序的服务器程序。在这里,我们将扩展上述创建的类,创建一个远程对象,并使用绑定名称:hello 将其注册到RMI注册表。创建一个Java源代码文件:Server.java,其代码如下所示 -
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()
}
}
}
客户端程序
以下是本应用程序的客户端程序。 在这里,我们提取远程对象并调用其animation()
方法。创建一个Java源代码文件:Client.java,其代码如下所示 -
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()
}
}
}
运行示例的步骤
以下是运行RMI示例的步骤。
第一步 - 打开存储所有程序的文件夹,并编译所有Java文件,如下所示。
F:\worksp\java_rmi\java-gui>javac *.java
F:\worksp\java_rmi\java-gui>
第二步 - 使用以下命令启动rmi注册表。
start rmiregistry
这将在单独的窗口中启动一个rmi注册表,如下所示。
第三步 - 运行服务器类文件,如下所示。
F:\worksp\java_rmi\java-gui>java Server
Server ready
第四步 - 运行客户端类文件,如下所示。
F:\worksp\java_rmi\java-gui> java Client
验证调用结果 - 当启动客户端以后,将在服务器中看到启动一个图形界面,如下所示 -