Java 服务器在使用 Javafx 单击按钮时停止

标签 java javafx server client

我尝试制作一个在按钮单击时停止的界面。 当我在 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);
        }

一些注释:

  1. 您的构造函数不应真正启动服务器,而应用于初始化服务器参数,例如:_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/

    相关文章:

    Javafx 喜欢回调但没有返回

    java - 二维数组,其单元格可以在索引处保存超过 1 个值

    java - org.jboss.resteasy.client.ClientResponseFailure : Unable to find a MessageBodyReader of content-type text/plain and type class java. lang.String

    java - 如何在 Java 中插入动画 gif

    java - 转换 Java 函数式接口(interface)

    gnome 上的 javafx 应用程序名称

    JavaFX 应用程序不会因 swing 内容而关闭

    Node.js 服务器请求/通知

    android - Android Service在后台数据丢失时运行

    Git - 服务器上的 ssh-key