JFrame 在创建 ServerSocket(或套接字)后无法关闭

JFrame can't close after ServerSocket (or socket) is created

我正在创建一个多人游戏,但是当我创建 ServerSocket 时,我无法关闭该应用程序中的任何 JFrame 运行,这是我的服务器创建代码:

private void createServer() {
        JFrame frame = new JFrame("Cow Invaders - Server");
        JTextArea console = new JTextArea();
        frame.setSize(640, 480);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        console.setFont(new Font("Times New Roman", Font.BOLD, 15));
        console.setLineWrap(true);
        frame.add(console);
        frame.setVisible(true);
        try {
            server = new ServerSocket(Integer.parseInt(port));
            System.out.println("No problems here");
        } catch (IOException e) {
            System.err.println("An error has occurred: " + e.getMessage());
            e.printStackTrace();
        }
        console.append("Started server on port " + port + " and with an IP of " + server.getInetAddress());
        try {
            socket = server.accept();
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("An error has occurred: " + e.getMessage());
        }
        console.append("\n" + "Connection from: " + socket.getInetAddress());
        try {
            out = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            System.err.println("An error has occurred: " + e.getMessage());
            e.printStackTrace();
        }
        try {
            out.writeUTF("You have successfully joined the game.");
        } catch (IOException e) {
            System.err.println("An error has occurred" + e.getMessage());
            e.printStackTrace();
        }
        System.out.println("Successfully send data.");
    }

对造成这种情况的原因有什么想法吗?

您似乎在单个线程上执行所有操作,包括使用阻塞代码,这将阻塞 Swing 事件线程,阻止它执行必要的活动。我猜测使用此代码您的 JFrames 会被冻结。建议:

  • 在 Swing 事件调度线程 (EDT) 上进行所有 Swing 调用。如果您的 GUI 在此线程上启动,那么您已经为大部分 Swing 调用做好了准备。
  • 在后台线程中进行所有长运行 任务调用。 SwingWorker 对此效果很好,但前提是您不直接从后台线程调用 Swing。
  • 如果您的应用程序正在创建多个子windows,它们应该是对话框windows,例如JDialogs,而不是JFrames。

查看 Lesson: Concurrency in Swing 了解更多信息。