Java:我的JFrame';当我启动服务器时,s的内容(按钮等)不可单击

Java:我的JFrame';当我启动服务器时,s的内容(按钮等)不可单击,java,swing,jframe,server,Java,Swing,Jframe,Server,我用Java创建了一个简单的HTTP服务器,它使用一个接受浏览器请求的ServerSocket。服务器工作正常,没有任何错误。我使用Swing创建了一个JForm,其中包含启动和停止服务器的按钮。 在开始按钮中,我添加了一个运行ServerMain类的ActionListener JButton btnStartServer = new JButton("Start Server"); panel.add(btnStartServer); btnStartServer.addAc

我用Java创建了一个简单的HTTP服务器,它使用一个接受浏览器请求的ServerSocket。服务器工作正常,没有任何错误。我使用Swing创建了一个JForm,其中包含启动和停止服务器的按钮。 在开始按钮中,我添加了一个运行ServerMain类的ActionListener

JButton btnStartServer = new JButton("Start Server");
    panel.add(btnStartServer);
    btnStartServer.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            try {
                ServerMain.main(new String[0]);
                } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
但是,每当我启动服务器时,我的JFrame就会变得不可访问,因此我无法单击包含以下代码的退出按钮:

JButton btnExit = new JButton("Exit");
    panel.add(btnExit);
    btnExit.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            try {
                System.exit(0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });;
通过循环侦听和接受连接的套接字肯定是导致这种情况的原因,但我不知道如何修复它。 任何建议都会很好。
提前感谢:)

由于Swing组件不是线程安全的,所有UI操作都在名为事件调度程序线程(EDT)的特殊线程中执行(这种技术称为线程限制

因此,在EDT中启动ServerMain,这就是任何后续操作都不会执行的原因

为了避免这种问题,您应该在分离的线程中运行阻塞操作。因此,您的问题的粗略解决方案:

btnStartServer.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {
        try {
            new Thread(new Runnable() {
                public void run() { 
                    ServerMain.main(new String[0]);
                }
             }).start();
            } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

我建议您阅读Java,而不是您所能阅读到的。

由于Swing组件不是线程安全的,所有UI操作都是在名为事件调度程序线程(EDT)的特殊线程中执行的(这种技术称为线程限制

因此,在EDT中启动ServerMain,这就是任何后续操作都不会执行的原因

为了避免这种问题,您应该在分离的线程中运行阻塞操作。因此,您的问题的粗略解决方案:

btnStartServer.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {
        try {
            new Thread(new Runnable() {
                public void run() { 
                    ServerMain.main(new String[0]);
                }
             }).start();
            } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

我建议您阅读Java,这是您读不到的。

除了balalaika的优秀答案(1+)之外,这类代码:
ServerMain.main(新字符串[0])
建议您可以更好地连接两个程序,并允许更干净的面向对象兼容交互。非常好的回答balalaika,非常感谢您!精彩的解释!和/或考虑A,这取决于除了巴拉莱卡的优秀答案(1 +)之外,你想做什么,这类代码:<代码> ServEng.主(新字符串[0)];
建议您可以更好地连接两个程序,并允许更干净的面向对象兼容交互。非常好的回答balalaika,非常感谢您!精彩的解释!和/或考虑A,这取决于你想做什么