Обработка потоков при отображении списка изображений в Javafx и паузаJAVA

Программисты JAVA общаются здесь
Anonymous
Обработка потоков при отображении списка изображений в Javafx и пауза

Сообщение Anonymous »

У меня есть приложение Javafx. Один элемент пользовательского интерфейса на сцене - изображение. Я хочу показать последовательность упражнений, каждые 60 секунд, пользователю. Каждое упражнение имеет среди других атрибутов, изображение, которое должно быть показано в изображении, и ссылка на файл wav, с текстом объяснения, который должен быть воспроизведен после показа изображения. Я хочу, чтобы приложение оставалось отзывчивым, в то время как изображение показано в случае, когда пользователь нажимает кнопку остановки. При уменьшении реальной сложности между различными упражнениями и во время отображения каждого упражнения есть разрывы (пауза метода). Каждый перерыв показывает новую посвященную сцену, которая отсчитывает время перерыва. During a break time the current image display shall disappear and re-appear after the break finalized.
The respective runImageExercise method is called on the Java Application Thread: 11:58:48 [DEBUG] [JavaFX Application Thread] d.l.c.MainCtrl.runImageExercise, 1226: entering runImageExercise: Calf left
Моя проблема заключается в комбинации обработки потоков между показом упражнения и паузы.
Если я помесчу потоку. Sleep (1000) в метод RunimageExcise напрямую, изображение упражнения никогда не отображается, и объяснение воспроизводится только в том случае, если вызывает паузу. Это эта версия: < /p>
protected void runImageExercise(Exercise exercise) {

debugLogger.debug("V1) entering runImageExercise: " + exercise.getName());

imageView.setVisible(true);
exerciseLabel.setText(exercise.getName());
Image image = exercise.getPreviewImage();
imageView.setImage(image);

Task exerciseSoundTask = getExerciseSoundTask(exercise); // Play explanation wav file
Thread exerciseSoundThread = new Thread(exerciseSoundTask);
exerciseSoundThread.start();

currentImageDisplayTime = 0;
while (currentImageDisplayTime < 60) { // show the image for 60 secs
currentImageDisplayTime++;

if(currentImageDisplayTime % 30 == 0) { // pause every 30 secs
imageView.setVisible(false);
pause(PauseType.EXERCISE_PAUSE, exercise.getBreakBetweenSetsInSecs(), "Break", exercise, false);
imageView.setVisible(true);
}

try {
Thread.sleep(1000);
} catch (InterruptedException interrupted) {
break;
}
}

imageView.setVisible(false);

pause(PauseType.EXERCISE_PAUSE, exercise.getBreakBetweenSetsInSecs(), "Exercise done", exercise, false);
}
< /code>
Ни одна из моих попыток с Thread.join или Lock и уведомление о синхронизации двух сработанных потоков.
Так что, если я помещаю нить. Sleep (1000) в выделенную ветку, изображение отображается, а объяснение сыграно, но применение паузы на применение CAUSE. Platform.Runlater () Блок. Теперь пауза открывается с небольшой задержкой, но цикл CurrentImagedIsplayTime не прерывается и продолжает рассчитывать. Это эта версия: < /p>
protected void runImageExercise(Exercise exercise, List exercises, boolean switchSide) {

debugLogger.debug("V2) entering runImageExercise: " + exercise.getName());

imageView.setVisible(true);
exerciseLabel.setText(exercise.getName());
setLabel.setText("1");
Image image = exercise.getPreviewImage();
imageView.setImage(image);

Task exerciseSoundTask = getExerciseSoundTask(exercise, switchSide);
Task imageDisplayTask = getImageDisplayTask(exercise, exercises, switchSide);
repLabel.textProperty().bind(imageDisplayTask.messageProperty());

Thread imageDisplayThread = new Thread(imageDisplayTask);
Thread exerciseSoundThread = new Thread(exerciseSoundTask);

imageDisplayThread.start();
exerciseSoundThread.start();

debugLogger.debug("leaving runImageExercise: ");
}
< /code>
Вот определение задачи: < /p>
protected Task getImageDisplayTask(Exercise exercise, List exercises, boolean switchSide) {
Task imageWaitTask = new Task() {
@Override
protected Void call() throws Exception {

debugLogger.debug("entering imageWaitTask: " + exercise.getName());

currentImageDisplayTime = 0;
while (currentImageDisplayTime < 60) { // show the image for 30 secs
currentImageDisplayTime++;
debugLogger.debug("------------------ imageWaitTask time:" + currentImageDisplayTime);

if(currentImageDisplayTime % 30 == 0) {
Platform.runLater(() -> {
imageView.setVisible(false);
pause(PauseType.EXERCISE_PAUSE, exercise.getBreakBetweenSetsInSecs(), "Break", exercise, false);
imageView.setVisible(true);
});
}

try {
Thread.sleep(1000);
} catch (InterruptedException interrupted) {
break;
}
}

debugLogger.debug("leaving imageWaitTask");
return null;
}
};

imageWaitTask.setOnSucceeded(e -> {
debugLogger.debug("imageWaitTask succeded");

imageView.setVisible(false);
pause(PauseType.EXERCISE_PAUSE, exercise.getBreakBetweenSetsInSecs(), "Exercise done", exercise, false);
});

return imageWaitTask;
}
< /code>
И, возможно, вы хотите получить некоторое представление о методе паузы: < /p>
protected void pause(PauseType pauseType, int seconds, String message, Exercise exercise, boolean switchSide) {

URL url = getClass().getResource("/sifuSays/ui/PauseScene.fxml");
try {
debugLogger.debug("entering pause:" + seconds + " sec");

FXMLLoader fxmlLoader = new FXMLLoader(url);
Parent parent = fxmlLoader.load();
Stage stage = new Stage(StageStyle.UNDECORATED);
stage.initOwner(mediaPane.getScene().getWindow());

pauseCtrl = fxmlLoader.
getController();

debugLogger.debug("pauseType: " + pauseType.toString());
switch (pauseType) {
case SESSION_START: // Beginning of session
pauseCtrl.configure(stage, seconds);

debugLogger.debug("SESSION_START: getReady");
pauseCtrl.getReady();
break;
case EXERCISE_PAUSE: // Change between exercises
debugLogger.debug("EXERCISE_PAUSE: configure");
pauseCtrl.configure(stage, seconds, message, exercise, switchSide);

debugLogger.debug("EXERCISE_PAUSE: exercisePause");
pauseCtrl.exercisePause();
break;
case SESSION_END: // End of session
debugLogger.debug("SESSION_END: configure");
pauseCtrl.configure(stage, seconds);

debugLogger.debug("SESSION_END: done");
pauseCtrl.done();
break;
case SETS_PAUSE:
debugLogger.debug("SETS_PAUSE: configure");
pauseCtrl.configure(stage, seconds, message, exercise, switchSide);

debugLogger.debug("SETS_PAUSE: setsPause");
pauseCtrl.setsPause();
break;
default:
debugLogger.debug("Uncovered case option");
return; // This should not happen
}

Scene scene = new Scene(parent);

if(seconds > 0) {
stage.setScene(scene);
debugLogger.debug("Calling showAndWait");
stage.showAndWait();
}

pauseCtrl = null;

debugLogger.debug("Pause ended. Continue");

} catch (Exception e) {
e.printStackTrace();
}
}
< /code>
Я знаю, что один из способов решить проблему было бы добавить продолжительность паузы к продолжительности отображения изображения в счетчике цикла. Но поскольку в реальном алгоритме время отображения упражнения плюс, если вообще нет многократных перерывов и как долго они продлятся, гораздо сложнее, плюс я хотел бы понять предполагаемый дизайн и узнать, как настроить метод (ы), чтобы получить описанный синхронизированный бахавиур применения, не нарушая ограничения Javafx, касающиеся тем, и U -обновлены? Заранее спасибо.


Подробнее здесь: https://stackoverflow.com/questions/795 ... -and-pause

Вернуться в «JAVA»