2014-09-03 53 views
0

我正在編寫一個Java GUI多人遊戲。 我有一個GUI,用戶可以輸入端口號並點擊「啓動服務器」,它將啓動遊戲服務器並調出另一個GUI框架。但是,當點擊按鈕時,我的程序會凍結。 可以用這種方式啓動服務器嗎?或者我怎麼編碼,以便服務器啓動並等待玩家連接,同時顯示另一個GUI框架(用單獨的課程編寫)?提前致謝。多人Java遊戲 - 通過GUI啓動服務器時程序凍結

// part of GUI code 

start = new JButton ("Start Game Server"); 
     start.addActionListener (new ActionListener() { 

      public void actionPerformed (ActionEvent event) { 
       DEFAULT_PORT = Integer.parseInt(port.getText()); 
       fgServer.run(); 
       fgServerFrame = new FishingGameServerFrame(); 
       //frame.dispose(); 
      } 
     }); 

-

// server code 

public class FishingGameServer { 

    private static int DEFAULT_PORT = 0; 

    public void run() 
    { 

     int port = DEFAULT_PORT; 

     port = Integer.parseInt(FishingGameConnectServerFrame.portNumber()); 
     System.out.println("port #: " + port); 

     //setup server socket 
     ServerSocket reception_socket = null; 

     try { 
      reception_socket = new ServerSocket (port); 
      System.out.println("Started server on port " + port); 
     } 
     catch (IOException e) { 
      //to get text in GUI frame 
      System.out.println("Cannot create server"); 
      System.exit(0); 
     } 

     for (;;) { 
      Socket client_socket = null; 

      try { 
       client_socket = reception_socket.accept(); 
       System.out.println("Accepting requests from:" + client_socket.getInetAddress()); 
      } 
      catch (IOException i) { 
       System.out.println ("Problem accepting client socket"); 
      } 

      new FishingGameThreadedServer(client_socket); 
     } 
    } 

    public static void main (String[] args) { 

    new FishingGameServer().run(); 
    } 
+2

您有一個無限'for'循環創建'FishingGameThreadedServer'實例,這些實例會阻塞事件分派線程。 – kiheru 2014-09-03 07:07:18

回答

1

你叫fgServer.run();,最終死循環中調用client_socket = reception_socket.accept();

這防止事件指派線程從能夠由(無休止for-loop內一次,一次使用accept時)阻擋運行,它不能處理該事件隊列,這是負責,除其他外,處理塗料要求。

Swing是一個單線程環境,它也不是線程安全的。這意味着:

  • 你永遠不應該在EDT的背景和
  • 所有的更新和交互與用戶界面中執行任何長時間運行或阻塞操作必須從的EDT
的範圍內提出

看看Concurrency in Swing更多細節

你可以使用一個Thread代替或SwingWorker它提供的功能,以更方便地發佈更新回EDT ...

+0

謝謝。 :)我嘗試使用線程,它現在工作正常。 – user23 2014-09-03 08:00:07

+1

請注意,如果您需要更新UI,則需要確保更新與EDT同步,例如使用'SwingUtilities.invokeLater'等... – MadProgrammer 2014-09-03 08:01:49