我编写了一个javaswing程序,它在串行端口侦听(我使用jserialcomm库)。程序应该在控制台(已经工作)、文本区域字段(也工作)和文件(不工作)中显示接收到的数据。
接收过程从按下一个按钮开始,到按下另一个按钮结束。
我使用swingworker类将gui更改放在事件调度线程中。串行端口的配置、打开和读取发生在 doInBackground()
方法。读取是一个无休止的while循环,它嵌入到另一个while循环中,while循环测试 isCancelled()
. 通过按下gui中的按钮来触发取消操作。
textarea和控制台中的输出发生在 process()
方法。这个 done()
方法只需启用/禁用gui元素并存储printwriter close()
方法。
在文件中写入时,我使用filewriter/printwriter(在 process()
方法)。
结果:我得到了文件中最后发送的一行。忽略previos发送行(仅在文件中)。e、 g.我通过终端程序通过串行连接发送“一”“二”“三”(line end=lf,cr或cr lf没有区别)。我刚收到文件里的第三行。在gui和控制台上,我收到了预期的完整的3个字符串。
我的相关缩短代码(github的完整代码,分支“logfile”):
public class SerialPrinter extends JFrame {
PrintWriter pw;
private class SerialReadTask extends SwingWorker<Boolean, String> {
protected Boolean doInBackground() {
// [Omitted code] Get values from the GUI an open serial port ....
// Reading serial data
Scanner serialScanner = new Scanner(chosenPort.getInputStream());
while (!isCancelled()) {
while (serialScanner.hasNextLine()) {
String line = serialScanner.nextLine();
publish(line);
}
}
return false; // Returns true if cannot open serial port (code not here)
}
protected void process(List<String> chunk) {
try {
pw = new PrintWriter(new FileWriter(tf_Logfile.getText()));
for (String line : chunk) {
pw.println(line); // save to file
ta_VirtualPrint.append(line + "\n"); // display in GUI => WORKS!!!
System.out.println(line); // print on console => WORKS!!!
}
} catch (IOException ex) {
}
}
protected void done() {
// [Omitted code] Disabling some GUI elemts. Usage of get()<Boolean>
if (pw != null) { // if PrintWriter bw exists
pw.close(); // Close but just get the last submitted line in the file
}
}
private void btn_OpenPortActionPerformed(ActionEvent e) [
serialReader.execute()
}
private void btn_ClosePortActionPerformed(ActionEvent e) [
serialReader.cancel()
}
}
希望你有个主意。先谢谢你,
哈尼语
2条答案
按热度按时间wlsrxk511#
你在打电话吗
publish
对于每条线:所以每次文件被一行覆盖,最后一行被写入。
您可以考虑填充
List<String>
将所有读取行,然后将列表转换为数组,并调用publish
用这个数组。或者,您可以保持代码的原样,只需创建
FileWriter
在附加模式下:hsvhsicv2#
我将file/printwriter放在后台任务中,而不是edt(progress())任务中,请参见下面的代码。添加的行标记为
// NEW
:这个
pw.close()
仍然发生在done()
方法。无论如何,正如我之前提到的,这看起来或多或少是一种解决方法,因为我还不明白为什么第一种方法不适用于文件,而适用于屏幕输出。
总之,在som重构=>github之后