Я пишу приложение, которое выполняет некоторый аудиоанализ (для использования в качестве гитарного тюнера с добавлением оценки аккордов и некоторых других вещей), но у меня проблемы с графическим интерфейсом. Первая проблема заключается в том, что у меня есть кнопка, которая при нажатии должна изменить отображаемый текст. При нажатии текст не меняется, но точно достигается строка кода, которая должна его изменить.
Другое дело, что мне нужно, чтобы SwingWorker выполнялся повторно (перезапуск после его завершения) и каждый раз обновлял графический интерфейс. Поскольку мой код на данный момент, у меня есть цикл while, многократно выполняющий мой SwingWorker, но это приводит к тому, что графический интерфейс перестает отвечать на запросы, поскольку он работает в EDT (предположительно). Каков наилучший способ повторного выполнения SwingWorker? Должен ли я просто создать новый поток для запуска цикла или что-то еще?
Код для моего внутреннего класса ActionListener выглядит следующим образом:
private class TunerListener implements ActionListener {
private boolean firstUpdate = true;
private volatile boolean executing = false;
private final SwingWorker<Void, Void> tunerWorker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() {
model.update();
return null;
}
@Override
protected void done() {
if (!this.isCancelled()) {
prev.setText(model.getPrev());
currentNote.setText(model.getNote());
next.setText(model.getNext());
frequency.setText(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;
}
}
}
};
@Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("tune")) {
if (!executing) {
tune.setText("Stop Tuning");
executing = true;
while (executing) {
tunerWorker.execute();
firstUpdate = false;
}
firstUpdate = true;
} else {
tune.setText("Start Tuning");
executing = false;
tunerWorker.cancel(true);
firstUpdate = true;
}
}
}
}
Редактировать: Проблема с текстом кнопки, кажется, исправлена, но я все еще не могу заставить этот SwingWorker работать должным образом. Я попытался полностью удалить цикл while и заставить его повторно выполнить себя из метода done(), но это, похоже, не помогает...