package jalview.ws2.gui; import static java.lang.String.format; import java.util.Objects; import java.util.function.Consumer; import javax.swing.JMenu; import javax.swing.JMenuItem; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.gui.WebserviceInfo; import jalview.util.MessageManager; import jalview.ws2.WSJob; import jalview.ws2.operations.JPredOperation; import jalview.ws2.operations.JPredWorker; import jalview.ws2.operations.WebServiceWorkerI; import jalview.ws2.operations.WebServiceWorkerListener; import jalview.ws2.operations.JPredWorker.PredictionResult; public class JPredMenuBuilder implements MenuEntryProviderI { private JPredOperation operation; public JPredMenuBuilder(JPredOperation operation) { this.operation = operation; } public void buildMenu(JMenu menu, AlignFrame frame) { final JMenuItem mi = new JMenuItem(operation.getName()); mi.setToolTipText(operation.getHostName()); mi.addActionListener((event) -> { String panelInfo = String.format("%s using service hosted at %s%n%s", operation.getName(), operation.getHostName(), Objects.requireNonNullElse(operation.getDescription(), "")); var wsInfo = new WebserviceInfo(operation.getName(), panelInfo, false); var alignView = frame.gatherSeqOrMsaForSecStrPrediction(); var worker = new JPredWorker(operation, alignView, frame.getCurrentView()); var jpu = new JPredProgressUpdater(worker, wsInfo, frame); worker.setResultConsumer(jpu); worker.addListener(jpu); frame.getViewport().getWSExecutor().submit(worker); }); menu.add(mi); } } class JPredProgressUpdater implements WebServiceWorkerListener, Consumer { WebServiceWorkerI worker; WebserviceInfo wsInfo; AlignFrame frame; private final WebServiceInfoUpdater wsInfoUpdater; JPredProgressUpdater(WebServiceWorkerI worker, WebserviceInfo wsInfo, AlignFrame frame) { this.worker = worker; this.wsInfo = wsInfo; this.frame = frame; this.wsInfoUpdater = new WebServiceInfoUpdater(worker, wsInfo); } @Override public void workerStarted(WebServiceWorkerI source) { wsInfo.setVisible(true); } @Override public void workerNotStarted(WebServiceWorkerI source) { wsInfo.setVisible(true); wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); wsInfo.setStatus(0, WebserviceInfo.STATE_STOPPED_SERVERERROR); wsInfo.appendProgressText(0, MessageManager.getString( "info.failed_to_submit_sequences_for_alignment")); } @Override public void jobCreated(WebServiceWorkerI source, WSJob job) { wsInfo.addJobPane(); job.addPropertyChangeListener(wsInfoUpdater); } @Override public void pollException(WebServiceWorkerI source, WSJob job, Exception e) { wsInfo.appendProgressText(job.getJobNum(), MessageManager.formatMessage("info.server_exception", source.getOperation().getName(), e.getMessage())); } @Override public void workerCompleting(WebServiceWorkerI source) { wsInfo.setProgressBar( MessageManager.getString("status.collecting_job_results"), worker.getUID()); } @Override public void workerCompleted(WebServiceWorkerI source) { wsInfo.removeProgressBar(worker.getUID()); } @Override public void accept(PredictionResult result) { if (result != null) { wsInfo.showResultsNewFrame.addActionListener( (evt) -> displayResults(result, true)); wsInfo.mergeResults.addActionListener( (evt) -> displayResults(result, false)); wsInfo.setResultsReady(); } else { wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); wsInfo.appendInfoText("No jobs ran."); wsInfo.setFinishedNoResults(); } } private void displayResults(PredictionResult result, boolean newWindow) { if (newWindow) { Alignment alignment = new Alignment(result.getAlignment()); alignment.setSeqrep(alignment.getSequenceAt(0)); for (var annot : alignment.getSeqrep().getAnnotation()) { alignment.addAnnotation(annot); } AlignFrame frame = new AlignFrame(alignment, result.getHiddenCols(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); Desktop.addInternalFrame(frame, frame.getTitle(), AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } } }