2012-12-01 78 views
2

我的Reader類用於在服務器發送服務器消息時顯示服務器消息。當直接打印到命令行時,此代碼完美工作,我收到服務器發送的任何消息。但是,JTextArea只顯示其他每一行。我不確定這裏要做什麼。我讀了一些關於InvokeLater的內容,但我不確定這是否是使用它的正確情況。從其他類中追加到JTextArea

此外,當單擊連接按鈕時,線程從GUI類中啓動。

public class Reader implements Runnable { 

    public static Socket s = null; 
    public static JTextArea TextArea; 
    public static BufferedReader reader = null; 

    /*Takes in a Socket. Sets up a input stream. 
    * 
    */ 
    public Reader(Socket sIn, JTextArea display) { 
     TextArea=display; 
     s = sIn; 
     try { 
      reader = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     } catch (IOException ex) { 
      System.out.println("Error in constructor Reader: " + ex); 
     } 
    } 

    public void checker() { 
     try { 
      /*Sits and waits for a Server Response*/ 
      while (!reader.ready()) {} 

      System.out.println(reader.readLine()); 
      TextArea.append(reader.readLine()+"\n"); 

     } catch (Exception ex) { 
      System.out.println("checker is crying: " + ex); 
     } 
    } 


    public void run() { 
     while (true) { 
      checker(); 
     } 
    } 
} 

謝謝你的回覆和例子。我已經添加了以下的檢查()方法:

EventQueue.invokeLater(new Runnable() { 
    public void run() { 
     try { 
      TextArea.append(reader.readLine() + "\n"); 
     } catch (Exception eee) { 
      System.out.println("Error" + eee); 
     } 
    } 
}); 

存在同樣的問題(只接收所有其他服務器的消息),但現在它在所有其他消息鎖定。如果我的服務器發送4條消息,它跳過第一個獲取第二個等。 謝謝你的幫助!

+5

*「我讀了一些關於InvokeLater的內容,但我不確定這是否是正確的使用它的情況。」*是的。試試看,如果遇到困難,請回復我們。 –

+0

對於[示例](http://stackoverflow.com/a/3245805/230513)。 – trashgod

+0

感謝您的回覆。請看我編輯的帖子。 – McScotty89

回答

1

你從BufferedReader中兩次讀取:

 System.out.println(reader.readLine()); // *** here *** 
     TextArea.append(reader.readLine()+"\n"); // *** and here *** 

所以這就是爲什麼你只看到每隔一行。您的程序可能會因爲您嘗試在事件線程上致電readLine()而凍結 - 請勿這樣做。

只能從BufferedReader爲每行讀取一次。我也會改變while循環,並且會執行Runnable的緩衝讀取器的以外的

private String line = ""; // a class field 

    public void checker() { 
     try { 

     while ((line = reader.readLine()) != null) { 

      System.out.println(line); 
      SwingUtilities.invokeLater(new Runnable() { 
       TextArea.append(line + "\n"); 
      }); 
     } 

     } catch (Exception ex) { 
     System.out.println("checker is crying: " + ex); 
     } 
    } 


    public void run() { 
     checker(); 
    } 

或更好 - 使用SwingWorker對象並將行發佈/處理到JTextArea。另外,您需要了解並使您的代碼符合Java命名約定,包括所有類名都以大寫字母開頭,所有變量和方法都以小寫字母開頭。這樣做可以讓其他人更容易,更快地理解你的代碼,並可能幫助你在這裏獲得更快,更好的幫助。

+0

謝謝!問題正是你指出的。我正在按照你所說的兩次呼叫reader.readLine()。改變之後......它完美無缺! – McScotty89

+0

@ McScotty89:很高興你有它的工作! –