2014-01-18 36 views
3

我有一個叫做mainFrame的JFrame,它是使用我的程序時顯示給用戶的主要JFrame。在這種情況下應該使用什麼類型的消息傳遞? GUI向線程發送命令; Java

該程序創建一個套接字到服務器,併發送消息返回並第四它和服務器之間。

我試圖創建一個線程來處理連接。所以當用戶點擊「連接」時,線程將設置套接字以及相關的輸入和輸出流。然後,我希望線程等待,直到JFrame發送一條命令,該命令只是一個字符串,它應該打印到Socket的輸出流。線程將發送命令,讀取響應,然後等待另一個命令。

我想我可以設置一個隊列,讓我可以將命令「存入」它,然後當線程繞過它時,它可以將第一個命令從隊列中拉出來,並隨意使用它。

任何想法如何着手呢?

此外,目前我將參數this傳遞給線程,以便它可以訪問JFrame中的函數以將輸出打印到文本區域。這可以嗎?我可以允許線程調用產生它的JFrame中的方法嗎?

回答

3

建議:

  • Swing的GUI可以發送文本到插座,而且我不認爲需要任何額外的線程這一點,因爲這是非阻塞的。
  • 是需要一個單獨的線程等待的插座中,讀取輸入的數據。你可以使用Scanner或者BufferedReader來達到這個目的。
  • 然後從這個線程文本發送到GUI可能遇到的任何新行字符時。這需要在EDT上完成,也許通過SwingWorker的發佈/處理方法對與PropertyChangeListener進行。
  • ,是的,後臺線程可以調用的GUI方法,但總是通過將代碼放在一個Runnable,並通過SwingUtilities.invokeLater(...)排隊它的Swing事件隊列照顧做到這一點Swing事件線程上。

編輯
您發表評論:

什麼是 「在美國東部時間」 是什麼意思?

EDT =了Swing ëd ispatch Ť hread,執行所有擺動拉絲和用戶交互的主要Swing線程。如果您阻止此線程,則會阻止Swing的所有顯示和用戶界面,從而實質上凍結您的程序。詳情請參閱Concurrency in Swing

同時說,發送文本到套接字被阻塞,我該如何設置一個命令隊列呢?

我不明白,因爲發送插座不應來,據我瞭解的東西堵在信息這個問題。

+0

「在EDT上」是什麼意思? //也要說發送文本到套接字是被阻塞的,我該如何爲它設置一個命令隊列? – KDecker

+0

@BumSkeeter:請參閱編輯以回答。 –

+0

嗯,說我有一個線程調用一些阻塞方法,如'Socket.accept'。在接受來自套接字的新數據(它在循環中調用socket.accpet)之間,我該如何發送一個要執行的命令列表? – KDecker

0

看到這個代碼,但是你必須自己實現參數:

public class ConnectionThread extends Thread { 
    public static final HOST = "www.example.com"; 
    public static final PORT = 24239; 

    private String command; 
    private boolean lookahead = false; 
    private boolean allowChangeLookahead = true; 
    private boolean canRetrieveResult = false; 
    Private String result; 
    orivate Socket s = new Socket(HOST, PORT); 

    public void run() { 
     for(;;) { // Infinite loop 
      sleep(500); // Avoid low perfomance related problems. 

      if(lookahead) { 
       allowChangeLookahead = false; 

       try { 
        PrintWriter out = new PrintWriter(s.getOutputStream(), true); 
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
        out.println(command); 
        result = in.readLine(); 
        canRetrieveResult = true; 
       } catch(Exception e) { 
        // Something occured... 
       } 

       lookahead = false; 
       allowChangeLookAhead = true; 
      } 
     } 
    } 

    public synchronized void command(String cmd) { 
     command = cmd; 

     for(;;) { // Don't worry, not infinite 
      if(allowChangeLookahead) { 
       lookahead = true; 
       break; 
      } 
     } 
    } 

    public synchronized String getResult() { 
     for(;;) { 
      if(canRetrieveResult) { 
       return result; 
      } 
     } 
    } 
} 

同時,在主序...

ConnectionThread conThread = new ConnectionThread(); 
conThread.start(); 
// ... 
// Code of method that responds to command 
if(calledCommand) { 
    conThread.command(theCommand); 
    result = conThread.getResult(); 
} 

這就是它!記得寫服務器,問我是否需要幫助。

+0

這個'// ...'和消息一起,是否意味着你在主GUI中的回答中給出的代碼可以在任何時候運行?如點擊按鈕? – KDecker

+0

爲什麼命令不會產生無限循環?而'ConnectionThread'中的'result'沒有聲明。 //因此,我調用getResult()和command()來封鎖主GUI,直到for循環條件滿足爲止? – KDecker

+0

對不起,我修復了'結果'問題。不要擔心循環,導致服務器調用超時,所以如果提交者正確地實現了異常處理程序,代碼將會很快。請記住'command()'和'getResult()'方法是同步的,所以一切都被驗證並且獨立於情境。這裏發生的事情是,我的代碼有一個類似等候室的東西,這是命令的無限循環 – alesc3

相關問題