forked from j62/ctbrec
Add possibility to suspend the recording for model
This makes it possible to stop the recording without loosing track of the model. The user can pause/unpause recordings in the recorded models tab. There is also an new column "Paused", which indicates, if the recording is suspended for a model.
This commit is contained in:
parent
6b16a637f0
commit
efc4719018
|
@ -16,6 +16,7 @@ public abstract class AbstractModel implements Model {
|
||||||
private String description;
|
private String description;
|
||||||
private List<String> tags = new ArrayList<>();
|
private List<String> tags = new ArrayList<>();
|
||||||
private int streamUrlIndex = -1;
|
private int streamUrlIndex = -1;
|
||||||
|
private boolean suspended = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOnline() throws IOException, ExecutionException, InterruptedException {
|
public boolean isOnline() throws IOException, ExecutionException, InterruptedException {
|
||||||
|
@ -92,6 +93,16 @@ public abstract class AbstractModel implements Model {
|
||||||
// noop default implementation, can be overriden by concrete models
|
// noop default implementation, can be overriden by concrete models
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuspended() {
|
||||||
|
return suspended;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSuspended(boolean suspended) {
|
||||||
|
this.suspended = suspended;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
|
@ -38,4 +38,7 @@ public interface Model {
|
||||||
public Site getSite();
|
public Site getSite();
|
||||||
public void writeSiteSpecificData(JsonWriter writer) throws IOException;
|
public void writeSiteSpecificData(JsonWriter writer) throws IOException;
|
||||||
public void readSiteSpecificData(JsonReader reader) throws IOException;
|
public void readSiteSpecificData(JsonReader reader) throws IOException;
|
||||||
|
public boolean isSuspended();
|
||||||
|
public void setSuspended(boolean suspended);
|
||||||
|
|
||||||
}
|
}
|
|
@ -32,6 +32,7 @@ public class ModelJsonAdapter extends JsonAdapter<Model> {
|
||||||
String url = null;
|
String url = null;
|
||||||
String type = null;
|
String type = null;
|
||||||
int streamUrlIndex = -1;
|
int streamUrlIndex = -1;
|
||||||
|
boolean suspended = false;
|
||||||
|
|
||||||
Model model = null;
|
Model model = null;
|
||||||
while(reader.hasNext()) {
|
while(reader.hasNext()) {
|
||||||
|
@ -55,6 +56,9 @@ public class ModelJsonAdapter extends JsonAdapter<Model> {
|
||||||
} else if(key.equals("streamUrlIndex")) {
|
} else if(key.equals("streamUrlIndex")) {
|
||||||
streamUrlIndex = reader.nextInt();
|
streamUrlIndex = reader.nextInt();
|
||||||
model.setStreamUrlIndex(streamUrlIndex);
|
model.setStreamUrlIndex(streamUrlIndex);
|
||||||
|
} else if(key.equals("suspended")) {
|
||||||
|
suspended = reader.nextBoolean();
|
||||||
|
model.setSuspended(suspended);
|
||||||
} else if(key.equals("siteSpecific")) {
|
} else if(key.equals("siteSpecific")) {
|
||||||
reader.beginObject();
|
reader.beginObject();
|
||||||
model.readSiteSpecificData(reader);
|
model.readSiteSpecificData(reader);
|
||||||
|
@ -87,6 +91,7 @@ public class ModelJsonAdapter extends JsonAdapter<Model> {
|
||||||
writeValueIfSet(writer, "description", model.getDescription());
|
writeValueIfSet(writer, "description", model.getDescription());
|
||||||
writeValueIfSet(writer, "url", model.getUrl());
|
writeValueIfSet(writer, "url", model.getUrl());
|
||||||
writer.name("streamUrlIndex").value(model.getStreamUrlIndex());
|
writer.name("streamUrlIndex").value(model.getStreamUrlIndex());
|
||||||
|
writer.name("suspended").value(model.isSuspended());
|
||||||
writer.name("siteSpecific");
|
writer.name("siteSpecific");
|
||||||
writer.beginObject();
|
writer.beginObject();
|
||||||
model.writeSiteSpecificData(writer);
|
model.writeSiteSpecificData(writer);
|
||||||
|
|
|
@ -112,7 +112,12 @@ public class LocalRecorder implements Recorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRecordingProcess(Model model) throws IOException {
|
private void startRecordingProcess(Model model) throws IOException {
|
||||||
LOG.debug("Restart recording for model {}", model.getName());
|
if(model.isSuspended()) {
|
||||||
|
LOG.info("Recording for model {} is suspended.", model);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Starting recording for model {}", model.getName());
|
||||||
if (recordingProcesses.containsKey(model)) {
|
if (recordingProcesses.containsKey(model)) {
|
||||||
LOG.error("A recording for model {} is already running", model);
|
LOG.error("A recording for model {} is already running", model);
|
||||||
return;
|
return;
|
||||||
|
@ -315,7 +320,7 @@ public class LocalRecorder implements Recorder {
|
||||||
while (running) {
|
while (running) {
|
||||||
for (Model model : getModelsRecording()) {
|
for (Model model : getModelsRecording()) {
|
||||||
try {
|
try {
|
||||||
if (!recordingProcesses.containsKey(model)) {
|
if (!model.isSuspended() && !recordingProcesses.containsKey(model)) {
|
||||||
boolean isOnline = model.isOnline(IGNORE_CACHE);
|
boolean isOnline = model.isOnline(IGNORE_CACHE);
|
||||||
LOG.trace("Checking online state for {}: {}", model, (isOnline ? "online" : "offline"));
|
LOG.trace("Checking online state for {}: {}", model, (isOnline ? "online" : "offline"));
|
||||||
if (isOnline) {
|
if (isOnline) {
|
||||||
|
@ -529,4 +534,42 @@ public class LocalRecorder implements Recorder {
|
||||||
stopRecordingProcess(model);
|
stopRecordingProcess(model);
|
||||||
tryRestartRecording(model);
|
tryRestartRecording(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void suspendRecording(Model model) {
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
if (models.contains(model)) {
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
models.get(index).setSuspended(true);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
Download download = recordingProcesses.get(model);
|
||||||
|
if(download != null) {
|
||||||
|
download.stop();
|
||||||
|
recordingProcesses.remove(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resumeRecording(Model model) throws IOException {
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
if (models.contains(model)) {
|
||||||
|
int index = models.indexOf(model);
|
||||||
|
Model m = models.get(index);
|
||||||
|
m.setSuspended(false);
|
||||||
|
startRecordingProcess(m);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,4 +28,7 @@ public interface Recorder {
|
||||||
public void delete(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
public void delete(Recording recording) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
||||||
|
|
||||||
public void shutdown();
|
public void shutdown();
|
||||||
|
|
||||||
|
public void suspendRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
||||||
|
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class RemoteRecorder implements Recorder {
|
||||||
|
|
||||||
if("start".equals(action)) {
|
if("start".equals(action)) {
|
||||||
models.add(model);
|
models.add(model);
|
||||||
} else {
|
} else if("stop".equals(action)) {
|
||||||
models.remove(model);
|
models.remove(model);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,4 +276,14 @@ public class RemoteRecorder implements Recorder {
|
||||||
public void switchStreamSource(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
|
public void switchStreamSource(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
|
||||||
sendRequest("switch", model);
|
sendRequest("switch", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void suspendRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, IOException {
|
||||||
|
sendRequest("suspend", model);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resumeRecording(Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
|
||||||
|
sendRequest("resume", model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,18 @@ public class RecorderServlet extends AbstractCtbrecServlet {
|
||||||
response = "{\"status\": \"success\", \"msg\": \"Resolution switched\"}";
|
response = "{\"status\": \"success\", \"msg\": \"Resolution switched\"}";
|
||||||
resp.getWriter().write(response);
|
resp.getWriter().write(response);
|
||||||
break;
|
break;
|
||||||
|
case "suspend":
|
||||||
|
LOG.debug("Suspend recording for model {} - {}", request.model.getName(), request.model.getUrl());
|
||||||
|
recorder.suspendRecording(request.model);
|
||||||
|
response = "{\"status\": \"success\", \"msg\": \"Recording suspended\"}";
|
||||||
|
resp.getWriter().write(response);
|
||||||
|
break;
|
||||||
|
case "resume":
|
||||||
|
LOG.debug("Resume recording for model {} - {}", request.model.getName(), request.model.getUrl());
|
||||||
|
recorder.resumeRecording(request.model);
|
||||||
|
response = "{\"status\": \"success\", \"msg\": \"Recording resumed\"}";
|
||||||
|
resp.getWriter().write(response);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
resp.setStatus(SC_BAD_REQUEST);
|
resp.setStatus(SC_BAD_REQUEST);
|
||||||
response = "{\"status\": \"error\", \"msg\": \"Unknown action\"}";
|
response = "{\"status\": \"error\", \"msg\": \"Unknown action\"}";
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.iheartradio.m3u8.PlaylistException;
|
||||||
import com.squareup.moshi.JsonReader;
|
import com.squareup.moshi.JsonReader;
|
||||||
import com.squareup.moshi.JsonWriter;
|
import com.squareup.moshi.JsonWriter;
|
||||||
|
|
||||||
import ctbrec.AbstractModel;
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.recorder.download.StreamSource;
|
import ctbrec.recorder.download.StreamSource;
|
||||||
import ctbrec.sites.Site;
|
import ctbrec.sites.Site;
|
||||||
|
@ -19,14 +18,16 @@ import javafx.beans.property.SimpleBooleanProperty;
|
||||||
/**
|
/**
|
||||||
* Just a wrapper for Model, which augments it with JavaFX value binding properties, so that UI widgets get updated proeprly
|
* Just a wrapper for Model, which augments it with JavaFX value binding properties, so that UI widgets get updated proeprly
|
||||||
*/
|
*/
|
||||||
public class JavaFxModel extends AbstractModel {
|
public class JavaFxModel implements Model {
|
||||||
private transient BooleanProperty onlineProperty = new SimpleBooleanProperty();
|
private transient BooleanProperty onlineProperty = new SimpleBooleanProperty();
|
||||||
|
private transient BooleanProperty pausedProperty = new SimpleBooleanProperty();
|
||||||
private Model delegate;
|
private Model delegate;
|
||||||
|
|
||||||
public JavaFxModel(Model delegate) {
|
public JavaFxModel(Model delegate) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
try {
|
try {
|
||||||
onlineProperty.set(delegate.isOnline());
|
onlineProperty.set(delegate.isOnline());
|
||||||
|
pausedProperty.set(delegate.isSuspended());
|
||||||
} catch (IOException | ExecutionException | InterruptedException e) {}
|
} catch (IOException | ExecutionException | InterruptedException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +90,10 @@ public class JavaFxModel extends AbstractModel {
|
||||||
return onlineProperty;
|
return onlineProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BooleanProperty getPausedProperty() {
|
||||||
|
return pausedProperty;
|
||||||
|
}
|
||||||
|
|
||||||
Model getDelegate() {
|
Model getDelegate() {
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
@ -157,4 +162,35 @@ public class JavaFxModel extends AbstractModel {
|
||||||
public void writeSiteSpecificData(JsonWriter writer) throws IOException {
|
public void writeSiteSpecificData(JsonWriter writer) throws IOException {
|
||||||
delegate.writeSiteSpecificData(writer);
|
delegate.writeSiteSpecificData(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return delegate.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDescription(String description) {
|
||||||
|
delegate.setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStreamUrlIndex() {
|
||||||
|
return delegate.getStreamUrlIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStreamUrlIndex(int streamUrlIndex) {
|
||||||
|
delegate.setStreamUrlIndex(streamUrlIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSuspended() {
|
||||||
|
return delegate.isSuspended();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSuspended(boolean suspended) {
|
||||||
|
delegate.setSuspended(suspended);
|
||||||
|
pausedProperty.set(suspended);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
ScrollPane scrollPane = new ScrollPane();
|
ScrollPane scrollPane = new ScrollPane();
|
||||||
TableView<JavaFxModel> table = new TableView<JavaFxModel>();
|
TableView<JavaFxModel> table = new TableView<JavaFxModel>();
|
||||||
ObservableList<JavaFxModel> observableModels = FXCollections.observableArrayList();
|
ObservableList<JavaFxModel> observableModels = FXCollections.observableArrayList();
|
||||||
ContextMenu popup = createContextMenu();
|
ContextMenu popup;
|
||||||
|
|
||||||
Label modelLabel = new Label("Model");
|
Label modelLabel = new Label("Model");
|
||||||
TextField model = new TextField();
|
TextField model = new TextField();
|
||||||
|
@ -104,11 +104,17 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
online.setCellValueFactory((cdf) -> cdf.getValue().getOnlineProperty());
|
online.setCellValueFactory((cdf) -> cdf.getValue().getOnlineProperty());
|
||||||
online.setCellFactory(CheckBoxTableCell.forTableColumn(online));
|
online.setCellFactory(CheckBoxTableCell.forTableColumn(online));
|
||||||
online.setPrefWidth(60);
|
online.setPrefWidth(60);
|
||||||
table.getColumns().addAll(name, url, online);
|
TableColumn<JavaFxModel, Boolean> paused = new TableColumn<>("Paused");
|
||||||
|
paused.setCellValueFactory((cdf) -> cdf.getValue().getPausedProperty());
|
||||||
|
paused.setCellFactory(CheckBoxTableCell.forTableColumn(paused));
|
||||||
|
paused.setPrefWidth(60);
|
||||||
|
table.getColumns().addAll(name, url, online, paused);
|
||||||
table.setItems(observableModels);
|
table.setItems(observableModels);
|
||||||
table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> {
|
table.addEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, event -> {
|
||||||
popup = createContextMenu();
|
popup = createContextMenu();
|
||||||
popup.show(table, event.getScreenX(), event.getScreenY());
|
if(popup != null) {
|
||||||
|
popup.show(table, event.getScreenX(), event.getScreenY());
|
||||||
|
}
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
table.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
|
table.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
|
||||||
|
@ -194,6 +200,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
threadPool.submit(() -> {
|
threadPool.submit(() -> {
|
||||||
try {
|
try {
|
||||||
javaFxModel.getOnlineProperty().set(javaFxModel.isOnline());
|
javaFxModel.getOnlineProperty().set(javaFxModel.isOnline());
|
||||||
|
javaFxModel.setSuspended(model.isSuspended());
|
||||||
} catch (IOException | ExecutionException | InterruptedException e) {}
|
} catch (IOException | ExecutionException | InterruptedException e) {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -253,26 +260,37 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContextMenu createContextMenu() {
|
private ContextMenu createContextMenu() {
|
||||||
MenuItem stop = new MenuItem("Stop Recording");
|
JavaFxModel selectedModel = table.getSelectionModel().getSelectedItem();
|
||||||
|
if(selectedModel == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
MenuItem stop = new MenuItem("Remove Model");
|
||||||
stop.setOnAction((e) -> stopAction());
|
stop.setOnAction((e) -> stopAction());
|
||||||
|
|
||||||
MenuItem copyUrl = new MenuItem("Copy URL");
|
MenuItem copyUrl = new MenuItem("Copy URL");
|
||||||
copyUrl.setOnAction((e) -> {
|
copyUrl.setOnAction((e) -> {
|
||||||
Model selected = table.getSelectionModel().getSelectedItem();
|
Model selected = selectedModel;
|
||||||
final Clipboard clipboard = Clipboard.getSystemClipboard();
|
final Clipboard clipboard = Clipboard.getSystemClipboard();
|
||||||
final ClipboardContent content = new ClipboardContent();
|
final ClipboardContent content = new ClipboardContent();
|
||||||
content.putString(selected.getUrl());
|
content.putString(selected.getUrl());
|
||||||
clipboard.setContent(content);
|
clipboard.setContent(content);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MenuItem pauseRecording = new MenuItem("Pause Recording");
|
||||||
|
pauseRecording.setOnAction((e) -> pauseRecording());
|
||||||
|
MenuItem resumeRecording = new MenuItem("Resume Recording");
|
||||||
|
resumeRecording.setOnAction((e) -> resumeRecording());
|
||||||
MenuItem openInBrowser = new MenuItem("Open in Browser");
|
MenuItem openInBrowser = new MenuItem("Open in Browser");
|
||||||
openInBrowser.setOnAction((e) -> DesktopIntergation.open(table.getSelectionModel().getSelectedItem().getUrl()));
|
openInBrowser.setOnAction((e) -> DesktopIntergation.open(selectedModel.getUrl()));
|
||||||
MenuItem openInPlayer = new MenuItem("Open in Player");
|
MenuItem openInPlayer = new MenuItem("Open in Player");
|
||||||
openInPlayer.setOnAction((e) -> Player.play(table.getSelectionModel().getSelectedItem().getUrl()));
|
openInPlayer.setOnAction((e) -> Player.play(selectedModel.getUrl()));
|
||||||
MenuItem switchStreamSource = new MenuItem("Switch resolution");
|
MenuItem switchStreamSource = new MenuItem("Switch resolution");
|
||||||
switchStreamSource.setOnAction((e) -> switchStreamSource(table.getSelectionModel().getSelectedItem()));
|
switchStreamSource.setOnAction((e) -> switchStreamSource(selectedModel));
|
||||||
|
|
||||||
return new ContextMenu(stop, copyUrl, openInBrowser, switchStreamSource);
|
ContextMenu menu = new ContextMenu(stop);
|
||||||
|
menu.getItems().add(selectedModel.isSuspended() ? resumeRecording : pauseRecording);
|
||||||
|
menu.getItems().addAll(copyUrl, openInBrowser, switchStreamSource);
|
||||||
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void switchStreamSource(JavaFxModel fxModel) {
|
private void switchStreamSource(JavaFxModel fxModel) {
|
||||||
|
@ -345,4 +363,60 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private void pauseRecording() {
|
||||||
|
JavaFxModel model = table.getSelectionModel().getSelectedItem();
|
||||||
|
Model delegate = table.getSelectionModel().getSelectedItem().getDelegate();
|
||||||
|
if (delegate != null) {
|
||||||
|
table.setCursor(Cursor.WAIT);
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
recorder.suspendRecording(delegate);
|
||||||
|
Platform.runLater(() -> model.setSuspended(true));
|
||||||
|
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) {
|
||||||
|
LOG.error("Couldn't pause recording", e1);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't pause recording");
|
||||||
|
alert.setContentText("Error while pausing the recording: " + e1.getLocalizedMessage());
|
||||||
|
alert.showAndWait();
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
table.setCursor(Cursor.DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void resumeRecording() {
|
||||||
|
JavaFxModel model = table.getSelectionModel().getSelectedItem();
|
||||||
|
Model delegate = table.getSelectionModel().getSelectedItem().getDelegate();
|
||||||
|
if (delegate != null) {
|
||||||
|
table.setCursor(Cursor.WAIT);
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
recorder.resumeRecording(delegate);
|
||||||
|
Platform.runLater(() -> model.setSuspended(false));
|
||||||
|
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) {
|
||||||
|
LOG.error("Couldn't resume recording", e1);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Error");
|
||||||
|
alert.setHeaderText("Couldn't resume recording");
|
||||||
|
alert.setContentText("Error while resuming the recording: " + e1.getLocalizedMessage());
|
||||||
|
alert.showAndWait();
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
table.setCursor(Cursor.DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue