我使用接受浏览器请求的ServerSocket在Java中创建了一个简单的HTTP服务器。服务器运行正常,没有任何错误。我使用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();
}
}
});;
通过循环监听和接受连接的套接字必须是导致此问题但我不知道如何修复它。 任何建议都会很精彩。 提前谢谢你:)
答案 0 :(得分:4)
由于 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 concurrency的内容,而不是关于concurrency model in Swing的内容。