2011-11-18 45 views
0

上下文:我正從115.2 Kbaud的串口讀取數據。讀取的數據使用PrintWriter進行打印,然後附加到JTextArea。PrintWriter到JTextArea,在被調用的方法關閉之前什麼也沒有顯示

一切正常,但直到從串口發送流到我的PrintWriter的方法結束時,JTextArea中的文本纔會出現。我希望它更接近實時顯示,因爲我有時一次可以接收20-30 MB的文本,並且程序執行時文本的一般流程如何變化將很有價值。

我正在使用PrintWriter來JTextArea方法here。我認爲解決方案可能與Threads和PipedWriter/PipedReader有關,但我爲實現這個目的所做的每一次嘗試都失敗了。

謝謝你的幫助。

//code calling method; VerifierReader does not inherit from Reader 
//or any such class. it's wholly homegrown. I send it the PrintWriter 
//as out, telling it to output there 


verifierInstance=new VerifierReader("COM3", verifierOutputLocString.getText()); 
verifierInstance.setSysOutWriter(out); 
verifierInstance.readVerifierStream(); 

// and the relevant code from VerifierReader 

public void setSysOutWriter (PrintWriter outWriter) { 
     sysOutWriter=new PrintWriter(outWriter);    

    } 
public void readVerifierStream() throws SerialPortException, 
InterruptedException{ 

    try{ 
     sysOutWriter.println("Listening for verifier..."); 
        //sysOutWriter.flush(); 

     verifierPort.addEventListener(new verifierListener()); 

     lastReadTimer=System.currentTimeMillis(); 

     while(verifierPort.isOpened()) { 

      Thread.sleep(1000); 
      //System.out.println(timeOut); 
      if(((long)(System.currentTimeMillis()-lastReadTimer))>timeOut){ 
       sysOutWriter.println("Finished"); 
       verifierPort.removeEventListener(); 
       verifierPort.closePort(); 

      } 
     } 
    } 

    finally { 

     if (verifierPort.isOpened()) { 
      verifierPort.closePort(); 
     } 

     bfrFile.close(); 

    } 
} 








private class verifierListener implements SerialPortEventListener{ 

    String outBuffer; 




    public void serialEvent(SerialPortEvent event) { 
     if(event.isRXCHAR()){//If data is available 
      timeOut=200; 
      lastReadTimer=System.currentTimeMillis(); 
      if(event.getEventValue() > 0){//Check bytes count in the input buffer 

       try { 
        byte[] buffer = verifierPort.readBytes(event.getEventValue()); 
        outBuffer=new String(buffer); 

        bfrFile.print(outBuffer); 
        sysOutWriter.print(outBuffer); 
         //bfrFile.flush(); 
         //sysOutWriter.flush(); 
       } 
       catch (SerialPortException ex) { 
        sysOutWriter.println(ex); 
       } 

      } 
     } 



    } 
} 

編輯:

我已經嘗試了以下建議是什麼,並進行了如下修改:

private class VerifierTask extends SwingWorker<Void, String> { 



    public VerifierTask() throws IOException, SerialPortException, InterruptedException{ 
     verifierInstance= new VerifierReader(streamReader); 
     verifierInstance.setReaderIO("COM3", verifierOutputLocString.getText()); 
     verifierInstance.readVerifierStream(); 

    } 


    @Override 
    protected Void doInBackground() throws IOException{ 
     int charItem; 
     char[] charBuff = new char[10]; 
     String passString; 

     while ((charItem = streamReader.read(charBuff, 0, 10)) !=-1) { 

      passString = new String(charBuff); 
      publish(passString); 
     } 


     return null; 
    } 

    @Override 
    protected void process(List<String> outList) { 

     for (String output : outList) { 
      outputArea.append(output); 
     } 

    } 



} 

加入,我改變了我的按鈕,立即調用一個新的實例的VerifierTask類,除了使VerifierReader實現一個PipedWriter來輸出(所有這些都是Strings)。

我不知道我在做什麼錯在這裏。當這個代碼執行時,Java進程只能無限期地凍結。

我是否正確地假設在任何VerifierTask線程中創建的VerifierReader都與該線程綁定,因此我的thread.sleep和while(true)語句不再構成問題?

回答

2

不要在主Swing事件線程EDT上調用Thread.sleep或者while(true)。永遠。而是在後臺線程中執行此類事情,例如通過SwingWorker提供的後臺線程。您可以使用發佈/過程方法對將中間結果傳遞給您的JTextArea。

欲瞭解更多信息,請查看教程:Concurrency in Swing

+0

比我的+1更快更好 – mKorbel

+0

謝謝指點。關閉到教程土地我去。 – Sheriff

相關問題