背景信息:我正在从115.2 Kbaud的串口读取数据。使用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输出(所有这些都是字符串)。
我不确定我在这里做错了什么。执行此代码时,Java进程将无限期冻结。
我是否正确地假设在任何VerifierTask线程中创建的VerifierReader都绑定到该线程,因此我的thread.sleep和while(true)语句不再构成问题?
答案 0 :(得分:2)
不要在主Swing事件线程EDT上调用Thread.sleep或while(true)。永远。而是在后台线程中执行此类操作,例如通过SwingWorker提供的线程。您可以使用发布/处理方法对来获得JTextArea的中间结果。
有关详情,请查看教程:Concurrency in Swing。