取消按钮后GUI冻结

时间:2014-01-04 17:41:04

标签: java swing sockets jbutton

我有一个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");        
    }   
}

2 个答案:

答案 0 :(得分:5)

你的start方法最终会调用阻塞Swing事件线程的while (true)循环。解决方案是在后台线程中执行此长时间运行的代码,执行此操作的一个不错的方法是使用SwingWorker。有关此有用构造的更多详细信息,请参阅Concurrency in Swing

重要的是:您需要改进代码格式,特别是代码缩进。您当前的缩进是误导性的,因为您启动了一些内部类向左冲洗,这使它们看起来像是外部类。如果您可以使用IDE,请执行此操作,并允许它帮助您改进缩进。否则,请小心操作小心,因为良好的缩进可帮助您一目了然地调试代码的某些概念,并且不良缩进可能会误导您和其他人有关您的代码。

答案 1 :(得分:1)

正如HovercraftFullOfEels所说,你的while()应该在一个单独的线程中,以免停止Swings事件。也只是一个建议,但在你的代码块中,在方法go()中创建一个ActionListener,为什么要重新检查connect是否是源?