オーディオを読み取り、このデータを分析して、結果をリアルタイムで表示するアプリケーションを作成しています。現在、SwingWorker を使用してバックグラウンド分析を開始するループを実行し、ループ内で SwingUtilities.invokeLater メソッドを呼び出して、分析が完了するたびに GUI コンポーネントを更新しています。現時点では、GUI はランダムに更新されているようで、まったく更新されないこともあります。
次のコードは、これを達成しようとしている方法を示しています。TunerListener は JPanel サブクラスの内部クラスです。PrevNote、nextNote、frequency、および light 変数はすべて、更新する JPanel サブクラスのコンポーネントです。
private class TunerListener implements ActionListener {
private boolean firstUpdate = true;
private boolean executing = false;
private TunerWorker tunerWorker = null;
private final class TunerWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() {
while (!this.isCancelled()) {
// Audio analysis in worker thread
model.update(firstUpdate);
// Update components in EDT
if (!this.isCancelled()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
prevNote.setText(model.getPrev());
currentNote.setText(model.getNote());
nextNote.setText(model.getNext());
frequency.setText("Frequency: "
+ model.getFrequency());
switch (model.getOffset()) {
case -2:
light_2.setIcon(onRed);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case -1:
light_2.setIcon(off);
light_1.setIcon(onRed);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case 0:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(onGreen);
light1.setIcon(off);
light2.setIcon(off);
break;
case 1:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(onRed);
light2.setIcon(off);
break;
case 2:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(onRed);
break;
}
firstUpdate = false;
}
});
}
}
return null;
}
@Override
protected void done() {
}
};
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("tune")) {
if (!executing) {
executing = true;
firstUpdate = true;
tune.setText("Stop Tuning");
tunerWorker = new TunerWorker();
tunerWorker.execute();
} else {
tune.setText("Start Tuning");
executing = false;
tunerWorker.cancel(true);
}
}
}
}
編集 デバッガーを使用すると、ソースが見つからないというメッセージが表示され、デバッグ ウィンドウに FutureTask$Sync.innerRun に関するメッセージが表示されることがあります。これで全然絞れますか?