好的,所以我对Java中的SwingWorker
有点陌生。
我已经构建了一个Java GUI,当按下"开始"按钮时,启动几个SwingWorker
线程。第一个线程只是跟踪运行时并适当地更新GUI。第二个程序播放一系列声音文件。第三个(也是有问题的)线程应该监视串行端口,以便稍后在路上操作传入的数据。所有这些线程都将运行一段时间,因此它们是SwingWorkers
。
我使用jSSC库(https://code.google.com/p/java-simple-serial-connector/wiki/jSSC_examples)从串行端口读取数据,它通过触发eventListener来读取数据。
我的问题:是多余的/不优雅的代码一个SwingWorker
线程内的EventListener ?如果是这样,有没有更好的方法来解决这个问题呢?
下面是我的一小段代码:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
SerialPort serialPort = findPort(); // returns a serialport I can use to read data from.
SwingWorker worker1 = new SwingWorker<Void, Void>(){
@Override
protected Void doInBackground() throws Exception {
long elapsedTime, startTime = System.currentTimeMillis();
while (true){
Thread.sleep(1000);
elapsedTime = (System.currentTimeMillis() - startTime)/1000;
jTimeField.setText(String.format("%02d:%02d:%02d", elapsedTime/3600, (elapsedTime%3600)/60, elapsedTime%60));
if (isCancelled()){} /* Check if thread has been canceled */
}
}
};
SwingWorker worker2 = new SwingWorker<Void, Void>(){
@Override
protected Void doInBackground() throws Exception {
// This Thread: Plays music files; Self terminates; On termination also terminates worker 1 and 3 via cancel().
}
};
SwingWorker worker3 = new SwingWorker<Void, Void>(){
@Override
protected Void doInBackground() throws Exception {
serialPort.addEventListener(new SerialPortReader());
return null;
}
class SerialPortReader implements SerialPortEventListener {
@Override
public void serialEvent(SerialPortEvent event) {
byte buffer[];
if (event.isRXCHAR() && event.getEventValue() > 0){
buffer = serialPort.readBytes();
for (byte b: buffer){
// Do stuff with incoming data
}
}
}
}
};
}
任何建设性的批评都是赞赏的。
在swingworker线程中添加事件监听器,然后在完成后返回是没有任何好处的。为什么不直接从EDT中添加侦听器,如果处理事件需要很长时间,那么从EDT中启动处理线程呢?监听事件不能被阻塞,否则会破坏整个观察者模式。