我有一个gui服务器,首先调用joptionpanel来输入端口号。如果我单击OK按钮,它看起来运行良好。但是如果在第一次运行中我单击取消,然后单击确定我的GUI冻结。我认为课程start()
会让它冻结。
对不起,这是一个重复的问题,但也许问题与其他问题不同。
这是我的服务器代码。任何人都可以帮助我。是什么导致gui冻结?
public class server {
// Main meathod
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
server server2 = new server(PORT);
server2.start();
}
public server(int PORT)
{
sdf = new SimpleDateFormat("[HH:mm:ss]");
go();
}
public void go() {
//The GUI hidden`enter code here`...
connect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// When Exit button is pressed
if (ae.getSource() == connect) {
start();
}
}
});
}
// Add new threads when new user enters
class reader implements Runnable {
BufferedReader br;
public reader(Socket clientsocket) {
try {
sock = clientsocket;
// Getting input stream
InputStreamReader ir = new InputStreamReader(
sock.getInputStream());
br = new BufferedReader(ir);
} catch (IOException ex) {
info.append(ex + "\n");
}
}
@Override
public void run() {
String msg = null;
String n;
try{
InputStreamReader ir = new InputStreamReader(sock.getInputStream());
br = new BufferedReader(ir);
pw = new PrintWriter(sock.getOutputStream());
// If message is not empty then broadcast message
while((msg=br.readLine())!=null)
{
incoming.append(msg +"\n");
pw.println(); // send the same line back to the client.
pw.flush(); // flush the stream to ensure that the data reaches the other end.
}
}
catch(SocketException ex)
{
info.append("Client Disconnected.\n");
}
catch(IOException ex)
{
info.append(ex+"\n");
}
}
}
private static int setPortNumber()
{
String portNumber = (String) JOptionPane.showInputDialog(frame,
"Enter the Port number for server creation","Server Connection\n",
JOptionPane.OK_CANCEL_OPTION, null, null, PORT);
int PORT = Integer.parseInt(portNumber);
return PORT;
}
// Meathod to handle networking Activities
public void start(){
connected = new ArrayList<PrintWriter>();
try {
PORT = setPortNumber();
ss = new ServerSocket(PORT);
String time = sdf.format(new Date());
info.append(time + "Server Started at port : " + PORT + "\n");
keep = true;
while (keep) {
try {
// Get socket connection
Socket clientsocket = ss.accept();
InetAddress a = clientsocket.getInetAddress();
info.append(a.getHostName() + " at IP Address "
+ a.getHostAddress() + " Connected to server.\n");
// Get output steam
PrintWriter pw = new PrintWriter(
clientsocket.getOutputStream());
connected.add(pw);
// Create and start new thread
Thread t1 = new Thread(new reader(clientsocket));
t1.start();
}
catch (NullPointerException ex) {
info.append("Null pointer Exception ");
} catch (SocketException e) {
info.append("Connection Reset\n");
}
}
} catch (Exception ex) {
info.append("Server has not been connected! Please try again, click connect button.\n");
}
}
答案 0 :(得分:5)
你的start方法最终会调用阻塞Swing事件线程的while (true)
循环。解决方案是在后台线程中执行此长时间运行的代码,执行此操作的一个不错的方法是使用SwingWorker
。有关此有用构造的更多详细信息,请参阅Concurrency in Swing。
重要的是:您需要改进代码格式,特别是代码缩进。您当前的缩进是误导性的,因为您启动了一些内部类向左冲洗,这使它们看起来像是外部类。如果您可以使用IDE,请执行此操作,并允许它帮助您改进缩进。否则,请小心操作小心,因为良好的缩进可帮助您一目了然地调试代码的某些概念,并且不良缩进可能会误导您和其他人有关您的代码。
答案 1 :(得分:1)
正如HovercraftFullOfEels所说,你的while()应该在一个单独的线程中,以免停止Swings事件。也只是一个建议,但在你的代码块中,在方法go()中创建一个ActionListener,为什么要重新检查connect是否是源?