我尝试制作一个在按钮单击时停止的界面。
当我在 main 中运行服务器时,我收到: Server-ul apornit...
但没有任何界面。
我应该在 Client 类中实现用于停止服务器的接口(interface)吗?
我的服务器:
public class Server extends Application
{
private final String _ip = "127.0.0.1";
private final int _port = 9001;
private ServerSocket _listener;
private Socket _socket;
private ObjectInputStream _input;
Stage window;
Button button;
public Server()
{
System.out.println("Server-ul a pornit...");
try
{
_listener = new ServerSocket(_port);
_socket = _listener.accept();
_input = new ObjectInputStream(_socket.getInputStream());
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
public void start()
{ ............}
我在 JAVAfx 接口(interface)的服务器类中的方法:
@Override
public void start(Stage primaryStrage) {
window=primaryStrage;
window.setTitle("Close the server");
button=new Button("Stop");
button.setOnAction(e -> closeProgram());
StackPane layoutPane=new StackPane();
layoutPane.getChildren().add(button);
Scene scene=new Scene(layoutPane,300,250);
window.setScene(scene);
window.show();
}
private void closeProgram() {
System.exit(0);
}
主程序:
public static void main(String[] args)
{
Server s = new Server();
s.start();
}
最佳答案
您必须首先通过在服务器类中添加 stop 方法来关闭服务器套接字:
public void stopServer(){
_listener.close();
}
我很困惑为什么你的服务器类扩展了应用程序。唯一应该扩展应用程序的是运行 GUI 的类。此外,您还重写了启动方法。因此,如果两个启动方法都在同一个类中,则覆盖启动方法将覆盖现有的启动方法,因此您的服务器将不会启动。您可以从 GUI 中重构服务器类,也可以保持原样。如果您选择后者,则必须将服务器的启动方法重命名为 serverStart()
。
不是在 main 中初始化服务器,而是在 GUI 的 start 方法中对其进行初始化:
@Override
public void start(Stage primaryStrage) {
Server s = new Server();
s.serverStart();
window=primaryStrage;
window.setTitle("Close the server");
button=new Button("Stop");
StackPane layoutPane=new StackPane();
layoutPane.getChildren().add(button);
Scene scene=new Scene(layoutPane,300,250);
button.setOnAction(e -> {
s.serverStop();
Stage stage = scene.getWindow(); // if you also want to exit the application
stage.close(); // otherwise remove it
});
window.setScene(scene);
window.show();
}
现在你的整个服务器类应该如下所示:
public class ServerTest extends Application {
Stage window;
Button button;
public class Server{
private final String _ip = "127.0.0.1";
private final int _port = 9001;
private ServerSocket _listener;
private Socket _socket;
private ObjectInputStream _input;
public Server(){
System.out.println("Server-ul a pornit...");
try
{
_listener = new ServerSocket(_port);
_socket = _listener.accept();
_input = new ObjectInputStream(_socket.getInputStream());
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
public void serverStart(){
//DO server start stuff
}
public void stopServer(){
_listener.close();
}
}
@Override
public void start(Stage primaryStrage) {
Server s = new Server();
s.serverStart();
window=primaryStrage;
window.setTitle("Close the server");
button=new Button("Stop");
StackPane layoutPane=new StackPane();
layoutPane.getChildren().add(button);
Scene scene=new Scene(layoutPane,300,250);
button.setOnAction(e -> {
s.serverStop();
Stage stage = scene.getWindow(); // if you also want to exit the application
stage.close(); // otherwise remove it
});
window.setScene(scene);
window.show();
}
public static void main(String[] args) {
launch(args);
}
一些注释:
- 您的构造函数不应真正启动服务器,而应用于初始化服务器参数,例如:
_ip
和_port
:
public Server(String ip, int port){
this._ip = ip;
this._port = posrt;
}
并且您应该将服务器启动操作委托(delegate)给 serverStart 方法:
public void serverStart(){
try {
_listener = new ServerSocket(_port);
_socket = _listener.accept();
_input = new ObjectInputStream(_socket.getInputStream());
}
catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
- 理想情况下,您应该在单独的类中重构逻辑代码,而不是直接将其包含在 GUI 类中。
关于Java 服务器在使用 Javafx 单击按钮时停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61942045/