Как добавить функционал pause/resume/stop приложению на JavaFX?
Есть десктопное приложение, работающее на JavaFX (OpenJFX). Логика написана на связке Spring Boot + JavaFX с помощью FXWeaver.
Задача заключается в следующем: клиенту нужна возможность ставить приложение на паузу/возобновлять/останавливать (по нажатию соответствующей кнопки на форме). У меня есть мысль запускать сервис в отдельном потоке (унаследовавшись от Thread), и добавить такой функционал:
- Pause: вызывать
super.sleep(1)в цикле, пока не будет изменём флаг paused - Resume: ставить флаг
pausedвfalse - Stop:
this.interrupt()
Не уверен, что это корректный подход к решению такой задачи, потому и пишу сюда. Можете дать парочку подсказок, как сделать правильно?
Ответы (1 шт):
Автор решения: Alexander Pavlov
→ Ссылка
wait/notify
import java.util.EnumSet;
public class MyTask {
public static enum State {Initial, Running, Paused, Stopped};
private final Thread worker = new Thread(this::workLoop);
private final Object stateLock = new Object();
private State state = State.Initial;
private void writeState(EnumSet<State> expectedStates, State newState, Runnable onChange) {
synchronized (stateLock) {
if (expectedStates.contains(state)) {
state = newState;
onChange.run();
}
}
}
private State readState() {
synchronized (stateLock) {
if (state == State.Paused) {
try {
stateLock.wait();
} catch (InterruptedException e) {
// nothing to do
}
}
return state;
}
}
public void start() {
writeState(EnumSet.of(State.Initial), State.Running, worker::start);
}
public void stop() {
writeState(EnumSet.of(State.Running, State.Paused), State.Stopped, stateLock::notifyAll);
}
public void pause() {
writeState(EnumSet.of(State.Running), State.Paused, stateLock::notifyAll);
}
public void resume() {
writeState(EnumSet.of(State.Paused), State.Running, stateLock::notifyAll);
}
private void workLoop() {
while (readState() != State.Stopped) {
nextIteration();
}
}
private void nextIteration() {
// do some small work here and let loop to verify its state
}
}