Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 14:43:25 GMT
  2. Package jalview.gui

File WebserviceInfo.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

84
268
46
2
984
633
111
0.41
5.83
23
2.41

Classes

Class Line # Actions
WebserviceInfo 65 220 95
0.00%
WebserviceInfo.AnimatedPanel 798 48 16
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.jbgui.GWebserviceInfo;
24    import jalview.util.MessageManager;
25    import jalview.util.Platform;
26    import jalview.util.ChannelProperties;
27    import jalview.ws.WSClientI;
28   
29    import java.awt.BorderLayout;
30    import java.awt.Color;
31    import java.awt.Dimension;
32    import java.awt.Graphics;
33    import java.awt.Graphics2D;
34    import java.awt.GridLayout;
35    import java.awt.Image;
36    import java.awt.MediaTracker;
37    import java.awt.RenderingHints;
38    import java.awt.event.ActionEvent;
39    import java.awt.image.BufferedImage;
40    import java.util.Locale;
41    import java.util.Vector;
42   
43    import javax.swing.JComponent;
44    import javax.swing.JEditorPane;
45    import javax.swing.JInternalFrame;
46    import javax.swing.JPanel;
47    import javax.swing.JProgressBar;
48    import javax.swing.JScrollPane;
49    import javax.swing.JTabbedPane;
50    import javax.swing.JTextArea;
51    import javax.swing.event.HyperlinkEvent;
52    import javax.swing.event.HyperlinkListener;
53    import javax.swing.event.InternalFrameAdapter;
54    import javax.swing.event.InternalFrameEvent;
55    import javax.swing.text.html.HTMLEditorKit;
56    import javax.swing.text.html.StyleSheet;
57   
58    /**
59    * Base class for web service client thread and gui TODO: create StAX parser to
60    * extract html body content reliably when preparing html formatted job statuses
61    *
62    * @author $author$
63    * @version $Revision$
64    */
 
65    public class WebserviceInfo extends GWebserviceInfo
66    implements HyperlinkListener, IProgressIndicator
67    {
68   
69    /** Job is Queued */
70    public static final int STATE_QUEUING = 0;
71   
72    /** Job is Running */
73    public static final int STATE_RUNNING = 1;
74   
75    /** Job has finished with no errors */
76    public static final int STATE_STOPPED_OK = 2;
77   
78    /** Job has been cancelled with no errors */
79    public static final int STATE_CANCELLED_OK = 3;
80   
81    /** job has stopped because of some error */
82    public static final int STATE_STOPPED_ERROR = 4;
83   
84    /** job has failed because of some unavoidable service interruption */
85    public static final int STATE_STOPPED_SERVERERROR = 5;
86   
87    int currentStatus = STATE_QUEUING;
88   
89    Image image;
90   
91    float angle = 0f;
92   
93    String title = "";
94   
95    jalview.ws.WSClientI thisService;
96   
97    boolean serviceIsCancellable;
98   
99    JInternalFrame frame;
100   
101    private IProgressIndicator progressBar;
102   
 
103  0 toggle @Override
104    public void setVisible(boolean aFlag)
105    {
106  0 super.setVisible(aFlag);
107  0 frame.setVisible(aFlag);
108    }
109   
110    JTabbedPane subjobs = null;
111   
112    java.util.Vector jobPanes = null;
113   
114    private boolean serviceCanMergeResults = false;
115   
116    private boolean viewResultsImmediatly = true;
117   
118    /**
119    * Get
120    *
121    * @param flag
122    * to indicate if results will be shown in a new window as soon as
123    * they are available.
124    */
 
125  0 toggle public boolean isViewResultsImmediatly()
126    {
127  0 return viewResultsImmediatly;
128    }
129   
130    /**
131    * Set
132    *
133    * @param flag
134    * to indicate if results will be shown in a new window as soon as
135    * they are available.
136    */
 
137  0 toggle public void setViewResultsImmediatly(boolean viewResultsImmediatly)
138    {
139  0 this.viewResultsImmediatly = viewResultsImmediatly;
140    }
141   
 
142  0 toggle private StyleSheet getStyleSheet(HTMLEditorKit editorKit)
143    {
144   
145    // Copied blatantly from
146    // http://www.velocityreviews.com/forums/t132265-string-into-htmldocument.html
147  0 StyleSheet myStyleSheet = new StyleSheet();
148   
149  0 myStyleSheet.addStyleSheet(editorKit.getStyleSheet());
150   
151  0 editorKit.setStyleSheet(myStyleSheet);
152   
153    /*
154    * Set the style sheet rules here by reading them from the constants
155    * interface.
156    */
157    /*
158    * for (int ix=0; ix<CSS_RULES.length; ix++) {
159    *
160    * myStyleSheet.addRule(CSS_RULES[ix]);
161    *
162    * }
163    */
164  0 return myStyleSheet;
165   
166    }
167   
168    // tabbed or not
 
169  0 toggle public synchronized int addJobPane()
170    {
171  0 JScrollPane jobpane = new JScrollPane();
172  0 JComponent _progressText;
173  0 if (renderAsHtml)
174    {
175  0 JEditorPane progressText = new JEditorPane("text/html", "");
176  0 progressText.addHyperlinkListener(this);
177  0 _progressText = progressText;
178    // progressText.setFont(new java.awt.Font("Verdana", 0, 10));
179    // progressText.setBorder(null);
180  0 progressText.setEditable(false);
181    /*
182    * HTMLEditorKit myEditorKit = new HTMLEditorKit();
183    *
184    * StyleSheet myStyleSheet = getStyleSheet(myEditorKit);
185    *
186    * HTMLDocument tipDocument = (HTMLDocument)
187    * (myEditorKit.createDefaultDocument());
188    *
189    * progressText.setDocument(tipDocument);
190  0 */progressText.setText("<html><h1>WS Job</h1></html>");
191    }
192    else
193    {
194  0 JTextArea progressText = new JTextArea();
195  0 _progressText = progressText;
196   
197  0 progressText.setFont(new java.awt.Font("Verdana", 0, 10));
198  0 progressText.setBorder(null);
199  0 progressText.setEditable(false);
200  0 progressText.setText("WS Job");
201  0 progressText.setLineWrap(true);
202  0 progressText.setWrapStyleWord(true);
203    }
204  0 jobpane.setName("JobPane");
205  0 jobpane.getViewport().add(_progressText, null);
206  0 jobpane.setBorder(null);
207  0 if (jobPanes == null)
208    {
209  0 jobPanes = new Vector();
210    }
211  0 int newpane = jobPanes.size();
212  0 jobPanes.add(jobpane);
213   
214  0 if (newpane == 0)
215    {
216  0 this.add(jobpane, BorderLayout.CENTER);
217    }
218    else
219    {
220  0 if (newpane == 1)
221    {
222    // revert to a tabbed pane.
223  0 JScrollPane firstpane;
224  0 this.remove(firstpane = (JScrollPane) jobPanes.get(0));
225  0 subjobs = new JTabbedPane();
226  0 this.add(subjobs, BorderLayout.CENTER);
227  0 subjobs.add(firstpane);
228  0 subjobs.setTitleAt(0, firstpane.getName());
229    }
230  0 subjobs.add(jobpane);
231    }
232  0 return newpane; // index for accessor methods below
233    }
234   
235    /**
236    * Creates a new WebserviceInfo object.
237    *
238    * @param title
239    * short name and job type
240    * @param info
241    * reference or other human readable description
242    * @param makeVisible
243    * true to display the webservices window immediatly (otherwise need
244    * to call setVisible(true))
245    */
 
246  0 toggle public WebserviceInfo(String title, String info, boolean makeVisible)
247    {
248  0 init(title, info, 520, 500, makeVisible);
249    }
250   
251    /**
252    * Creates a new WebserviceInfo object.
253    *
254    * @param title
255    * DOCUMENT ME!
256    * @param info
257    * DOCUMENT ME!
258    * @param width
259    * DOCUMENT ME!
260    * @param height
261    * DOCUMENT ME!
262    */
 
263  0 toggle public WebserviceInfo(String title, String info, int width, int height,
264    boolean makeVisible)
265    {
266    // no references
267  0 init(title, info, width, height, makeVisible);
268    }
269   
270    /**
271    * DOCUMENT ME!
272    *
273    * @return DOCUMENT ME!
274    */
 
275  0 toggle public jalview.ws.WSClientI getthisService()
276    {
277  0 return thisService;
278    }
279   
280    /**
281    * Update state of GUI based on client capabilities (like whether the job is
282    * cancellable, whether the 'merge results' button is shown.
283    *
284    * @param newservice
285    * service client to query for capabilities
286    */
 
287  0 toggle public void setthisService(jalview.ws.WSClientI newservice)
288    {
289  0 thisService = newservice;
290  0 serviceIsCancellable = newservice.isCancellable();
291  0 frame.setClosable(!serviceIsCancellable);
292  0 serviceCanMergeResults = newservice.canMergeResults();
293  0 rebuildButtonPanel();
294    }
295   
 
296  0 toggle private void rebuildButtonPanel()
297    {
298  0 if (buttonPanel != null)
299    {
300  0 buttonPanel.removeAll();
301  0 if (serviceIsCancellable)
302    {
303  0 buttonPanel.add(cancel);
304  0 frame.setClosable(false);
305    }
306    else
307    {
308  0 frame.setClosable(true);
309    }
310    }
311    }
312   
313    /**
314    * DOCUMENT ME!
315    *
316    * @param title
317    * DOCUMENT ME!
318    * @param info
319    * DOCUMENT ME!
320    * @param width
321    * DOCUMENT ME!
322    * @param height
323    * DOCUMENT ME!
324    */
 
325  0 toggle void init(String title, String info, int width, int height,
326    boolean makeVisible)
327    {
328  0 frame = new JInternalFrame();
329  0 frame.setFrameIcon(null);
330  0 frame.setContentPane(this);
331  0 Desktop.addInternalFrame(frame, title, makeVisible, width, height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
332  0 frame.setClosable(false);
333   
334  0 progressBar = new ProgressBar(statusPanel, statusBar);
335   
336  0 this.title = title;
337  0 setInfoText(info);
338   
339  0 image = ChannelProperties.getImage("rotatable_logo.48");
340   
341  0 MediaTracker mt = new MediaTracker(this);
342  0 mt.addImage(image, 0);
343   
344  0 try
345    {
346  0 mt.waitForID(0);
347    } catch (Exception ex)
348    {
349    }
350   
351  0 AnimatedPanel ap = new AnimatedPanel();
352  0 ap.setPreferredSize(new Dimension(60, 60));
353  0 titlePanel.add(ap, BorderLayout.WEST);
354  0 titlePanel.add(titleText, BorderLayout.CENTER);
355  0 setStatus(currentStatus);
356   
357  0 if (!Platform.isJS())
358    {
359    // No animation for the moment//
360  0 Thread thread = new Thread(ap);
361  0 thread.start();
362    }
363  0 final WebserviceInfo thisinfo = this;
364  0 frame.addInternalFrameListener(
365    new InternalFrameAdapter()
366    {
 
367  0 toggle @Override
368    public void internalFrameClosed(InternalFrameEvent evt)
369    {
370    // jalview.bin.Console.outPrintln("Shutting down webservice client");
371  0 WSClientI service = thisinfo.getthisService();
372  0 if (service != null && service.isCancellable())
373    {
374  0 service.cancelJob();
375    }
376    }
377    });
378  0 frame.validate();
379   
380    }
381   
382    /**
383    * DOCUMENT ME!
384    *
385    * @param status
386    * integer status from state constants
387    */
 
388  0 toggle public void setStatus(int status)
389    {
390  0 currentStatus = status;
391   
392  0 String message = null;
393  0 switch (currentStatus)
394    {
395  0 case STATE_QUEUING:
396  0 message = MessageManager.getString("label.state_queueing");
397  0 break;
398   
399  0 case STATE_RUNNING:
400  0 message = MessageManager.getString("label.state_running");
401  0 break;
402   
403  0 case STATE_STOPPED_OK:
404  0 message = MessageManager.getString("label.state_completed");
405  0 break;
406   
407  0 case STATE_CANCELLED_OK:
408  0 message = MessageManager.getString("label.state_job_cancelled");
409  0 break;
410   
411  0 case STATE_STOPPED_ERROR:
412  0 message = MessageManager.getString("label.state_job_error");
413  0 break;
414   
415  0 case STATE_STOPPED_SERVERERROR:
416  0 message = MessageManager.getString("label.server_error_try_later");
417  0 break;
418    }
419  0 titleText.setText(title + (message == null ? "" : " - " + message));
420  0 titleText.repaint();
421    }
422   
423    /**
424    * subjob status indicator
425    *
426    * @param jobpane
427    * @param status
428    */
 
429  0 toggle public void setStatus(int jobpane, int status)
430    {
431  0 if (jobpane < 0 || jobpane >= jobPanes.size())
432    {
433  0 throw new Error(MessageManager.formatMessage(
434    "error.setstatus_called_non_existent_job_pane", new String[]
435    { Integer.valueOf(jobpane).toString() }));
436    }
437  0 switch (status)
438    {
439  0 case STATE_QUEUING:
440  0 setProgressName(jobpane + " - QUEUED", jobpane);
441  0 break;
442  0 case STATE_RUNNING:
443  0 setProgressName(jobpane + " - RUNNING", jobpane);
444  0 break;
445  0 case STATE_STOPPED_OK:
446  0 setProgressName(jobpane + " - FINISHED", jobpane);
447  0 break;
448  0 case STATE_CANCELLED_OK:
449  0 setProgressName(jobpane + " - CANCELLED", jobpane);
450  0 break;
451  0 case STATE_STOPPED_ERROR:
452  0 setProgressName(jobpane + " - BROKEN", jobpane);
453  0 break;
454  0 case STATE_STOPPED_SERVERERROR:
455  0 setProgressName(jobpane + " - ALERT", jobpane);
456  0 break;
457  0 default:
458  0 setProgressName(jobpane + " - UNKNOWN STATE", jobpane);
459    }
460    }
461   
462    /**
463    * DOCUMENT ME!
464    *
465    * @return DOCUMENT ME!
466    */
 
467  0 toggle public String getInfoText()
468    {
469  0 return infoText.getText();
470    }
471   
472    /**
473    * DOCUMENT ME!
474    *
475    * @param text
476    * DOCUMENT ME!
477    */
 
478  0 toggle public void setInfoText(String text)
479    {
480  0 infoText.setText(text);
481    }
482   
483    /**
484    * DOCUMENT ME!
485    *
486    * @param text
487    * DOCUMENT ME!
488    */
 
489  0 toggle public void appendInfoText(String text)
490    {
491  0 infoText.append(text);
492    }
493   
494    /**
495    * DOCUMENT ME!
496    *
497    * @return DOCUMENT ME!
498    */
 
499  0 toggle public String getProgressText(int which)
500    {
501  0 if (jobPanes == null)
502    {
503  0 addJobPane();
504    }
505  0 if (renderAsHtml)
506    {
507  0 return ((JEditorPane) ((JScrollPane) jobPanes.get(which))
508    .getViewport().getComponent(0)).getText();
509    }
510    else
511    {
512  0 return ((JTextArea) ((JScrollPane) jobPanes.get(which)).getViewport()
513    .getComponent(0)).getText();
514    }
515    }
516   
517    /**
518    * DOCUMENT ME!
519    *
520    * @param text
521    * DOCUMENT ME!
522    */
 
523  0 toggle public void setProgressText(int which, String text)
524    {
525  0 if (jobPanes == null)
526    {
527  0 addJobPane();
528    }
529  0 if (renderAsHtml)
530    {
531  0 ((JEditorPane) ((JScrollPane) jobPanes.get(which)).getViewport()
532    .getComponent(0)).setText(ensureHtmlTagged(text));
533    }
534    else
535    {
536  0 ((JTextArea) ((JScrollPane) jobPanes.get(which)).getViewport()
537    .getComponent(0)).setText(text);
538    }
539    }
540   
541    /**
542    * extract content from &lt;body&gt; content &lt;/body&gt;
543    *
544    * @param text
545    * @param leaveFirst
546    * - set to leave the initial html tag intact
547    * @param leaveLast
548    * - set to leave the final html tag intact
549    * @return
550    */
 
551  0 toggle private String getHtmlFragment(String text, boolean leaveFirst,
552    boolean leaveLast)
553    {
554  0 if (text == null)
555    {
556  0 return null;
557    }
558  0 String lowertxt = text.toLowerCase(Locale.ROOT);
559  0 int htmlpos = leaveFirst ? -1 : lowertxt.indexOf("<body");
560   
561  0 int htmlend = leaveLast ? -1 : lowertxt.indexOf("</body");
562  0 int htmlpose = lowertxt.indexOf(">", htmlpos),
563    htmlende = lowertxt.indexOf(">", htmlend);
564  0 if (htmlend == -1 && htmlpos == -1)
565    {
566  0 return text;
567    }
568  0 if (htmlend > -1)
569    {
570  0 return text.substring((htmlpos == -1 ? 0 : htmlpose + 1), htmlend);
571    }
572  0 return text.substring(htmlpos == -1 ? 0 : htmlpose + 1);
573    }
574   
575    /**
576    * very simple routine for adding/ensuring html tags are present in text.
577    *
578    * @param text
579    * @return properly html tag enclosed text
580    */
 
581  0 toggle private String ensureHtmlTagged(String text)
582    {
583  0 if (text == null)
584    {
585  0 return "";
586    }
587  0 String lowertxt = text.toLowerCase(Locale.ROOT);
588  0 int htmlpos = lowertxt.indexOf("<body");
589  0 int htmlend = lowertxt.indexOf("</body");
590  0 int doctype = lowertxt.indexOf("<!doctype");
591  0 int xmltype = lowertxt.indexOf("<?xml");
592  0 if (htmlend == -1)
593    {
594  0 text = text + "</body></html>";
595    }
596  0 if (htmlpos > -1)
597    {
598  0 if ((doctype > -1 && htmlpos > doctype)
599    || (xmltype > -1 && htmlpos > xmltype))
600    {
601  0 text = "<html><head></head><body>\n" + text.substring(htmlpos - 1);
602    }
603    }
604    else
605    {
606  0 text = "<html><head></head><body>\n" + text;
607    }
608  0 if (text.indexOf("<meta") > -1)
609    {
610  0 System.err
611    .println("HTML COntent: \n" + text + "<< END HTML CONTENT\n");
612   
613    }
614  0 return text;
615    }
616   
617    /**
618    * DOCUMENT ME!
619    *
620    * @param text
621    * DOCUMENT ME!
622    */
 
623  0 toggle public void appendProgressText(int which, String text)
624    {
625  0 if (jobPanes == null)
626    {
627  0 addJobPane();
628    }
629  0 if (renderAsHtml)
630    {
631  0 String txt = getHtmlFragment(
632    ((JEditorPane) ((JScrollPane) jobPanes.get(which))
633    .getViewport().getComponent(0)).getText(),
634    true, false);
635  0 ((JEditorPane) ((JScrollPane) jobPanes.get(which)).getViewport()
636    .getComponent(0))
637    .setText(ensureHtmlTagged(
638    txt + getHtmlFragment(text, false, true)));
639    }
640    else
641    {
642  0 ((JTextArea) ((JScrollPane) jobPanes.get(which)).getViewport()
643    .getComponent(0)).append(text);
644    }
645    }
646   
647    /**
648    * setProgressText(0, text)
649    */
 
650  0 toggle public void setProgressText(String text)
651    {
652  0 setProgressText(0, text);
653    }
654   
655    /**
656    * appendProgressText(0, text)
657    */
 
658  0 toggle public void appendProgressText(String text)
659    {
660  0 appendProgressText(0, text);
661    }
662   
663    /**
664    * getProgressText(0)
665    */
 
666  0 toggle public String getProgressText()
667    {
668  0 return getProgressText(0);
669    }
670   
671    /**
672    * get the tab title for a subjob
673    *
674    * @param which
675    * int
676    * @return String
677    */
 
678  0 toggle public String getProgressName(int which)
679    {
680  0 if (jobPanes == null)
681    {
682  0 addJobPane();
683    }
684  0 if (subjobs != null)
685    {
686  0 return subjobs.getTitleAt(which);
687    }
688    else
689    {
690  0 return ((JScrollPane) jobPanes.get(which)).getViewport()
691    .getComponent(0).getName();
692    }
693    }
694   
695    /**
696    * set the tab title for a subjob
697    *
698    * @param name
699    * String
700    * @param which
701    * int
702    */
 
703  0 toggle public void setProgressName(String name, int which)
704    {
705  0 if (subjobs != null)
706    {
707  0 subjobs.setTitleAt(which, name);
708  0 subjobs.revalidate();
709  0 subjobs.repaint();
710    }
711  0 JScrollPane c = (JScrollPane) jobPanes.get(which);
712  0 c.getViewport().getComponent(0).setName(name);
713  0 c.repaint();
714    }
715   
716    /**
717    * Gui action for cancelling the current job, if possible.
718    *
719    * @param e
720    * DOCUMENT ME!
721    */
 
722  0 toggle @Override
723    protected void cancel_actionPerformed(ActionEvent e)
724    {
725  0 if (!serviceIsCancellable)
726    {
727    // JBPNote : TODO: We should REALLY just tell the WSClientI to cancel
728    // anyhow - it has to stop threads and clean up
729    // JBPNote : TODO: Instead of a warning, we should have an optional 'Are
730    // you sure?' prompt
731  0 warnUser(
732    MessageManager.getString(
733    "warn.job_cannot_be_cancelled_close_window"),
734    MessageManager.getString("action.cancel_job"));
735    }
736    else
737    {
738  0 thisService.cancelJob();
739    }
740  0 frame.setClosable(true);
741    }
742   
743    /**
744    * Spawns a thread that pops up a warning dialog box with the given message
745    * and title.
746    *
747    * @param message
748    * @param title
749    */
 
750  0 toggle public void warnUser(final String message, final String title)
751    {
752  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
753    {
 
754  0 toggle @Override
755    public void run()
756    {
757  0 JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), message,
758    title, JvOptionPane.WARNING_MESSAGE);
759   
760    }
761    });
762    }
763   
764    /**
765    * Set up GUI for user to get at results - and possibly automatically display
766    * them if viewResultsImmediatly is set.
767    */
 
768  0 toggle public void setResultsReady()
769    {
770  0 frame.setClosable(true);
771  0 buttonPanel.remove(cancel);
772  0 buttonPanel.add(showResultsNewFrame);
773  0 if (serviceCanMergeResults)
774    {
775  0 buttonPanel.add(mergeResults);
776  0 buttonPanel.setLayout(new GridLayout(2, 1, 5, 5));
777    }
778  0 buttonPanel.validate();
779  0 validate();
780  0 if (viewResultsImmediatly)
781    {
782  0 showResultsNewFrame.doClick();
783    }
784    }
785   
786    /**
787    * called when job has finished but no result objects can be passed back to
788    * user
789    */
 
790  0 toggle public void setFinishedNoResults()
791    {
792  0 frame.setClosable(true);
793  0 buttonPanel.remove(cancel);
794  0 buttonPanel.validate();
795  0 validate();
796    }
797   
 
798    class AnimatedPanel extends JPanel implements Runnable
799    {
800    long startTime = 0;
801   
802    BufferedImage offscreen;
803   
 
804  0 toggle @Override
805    public void run()
806    {
807  0 startTime = System.currentTimeMillis();
808   
809  0 float invSpeed = 15f;
810  0 float factor = 1f;
811  0 while (currentStatus < STATE_STOPPED_OK)
812    {
813  0 if (currentStatus == STATE_QUEUING)
814    {
815  0 invSpeed = 25f;
816  0 factor = 1f;
817    }
818  0 else if (currentStatus == STATE_RUNNING)
819    {
820  0 invSpeed = 10f;
821  0 factor = (float) (0.5 + 1.5
822    * (0.5 - (0.5 * Math.sin(3.14159 / 180 * (angle + 45)))));
823    }
824  0 try
825    {
826  0 Thread.sleep(50);
827   
828  0 float delta = (System.currentTimeMillis() - startTime) / invSpeed;
829  0 angle += delta * factor;
830  0 angle %= 360;
831  0 startTime = System.currentTimeMillis();
832   
833  0 if (currentStatus >= STATE_STOPPED_OK)
834    {
835  0 park();
836  0 angle = 0;
837    }
838   
839  0 repaint();
840    } catch (Exception ex)
841    {
842    }
843    }
844   
845  0 cancel.setEnabled(false);
846    }
847   
 
848  0 toggle public void park()
849    {
850  0 startTime = System.currentTimeMillis();
851   
852  0 while (angle < 360)
853    {
854  0 float invSpeed = 5f;
855  0 float factor = 1f;
856  0 try
857    {
858  0 Thread.sleep(25);
859   
860  0 float delta = (System.currentTimeMillis() - startTime) / invSpeed;
861  0 angle += delta * factor;
862  0 startTime = System.currentTimeMillis();
863   
864  0 if (angle >= 360)
865    {
866  0 angle = 360;
867    }
868   
869  0 repaint();
870    } catch (Exception ex)
871    {
872    }
873    }
874   
875    }
876   
 
877  0 toggle void drawPanel()
878    {
879  0 if (offscreen == null || offscreen.getWidth(this) != getWidth()
880    || offscreen.getHeight(this) != getHeight())
881    {
882  0 offscreen = new BufferedImage(getWidth(), getHeight(),
883    BufferedImage.TYPE_INT_RGB);
884    }
885   
886  0 Graphics2D g = (Graphics2D) offscreen.getGraphics();
887   
888  0 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
889    RenderingHints.VALUE_ANTIALIAS_ON);
890  0 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
891    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
892  0 g.setRenderingHint(RenderingHints.KEY_RENDERING,
893    RenderingHints.VALUE_RENDER_QUALITY);
894   
895  0 g.setColor(Color.white);
896  0 g.fillRect(0, 0, getWidth(), getHeight());
897   
898  0 if (image != null)
899    {
900  0 int x = image.getWidth(this) / 2, y = image.getHeight(this) / 2;
901  0 g.rotate(3.14159 / 180 * (angle), x, y);
902  0 g.drawImage(image, 0, 0, this);
903  0 g.rotate(-3.14159 / 180 * (angle), x, y);
904    }
905    }
906   
 
907  0 toggle @Override
908    public void paintComponent(Graphics g1)
909    {
910  0 drawPanel();
911   
912  0 g1.drawImage(offscreen, 0, 0, this);
913    }
914    }
915   
916    boolean renderAsHtml = false;
917   
 
918  0 toggle public void setRenderAsHtml(boolean b)
919    {
920  0 renderAsHtml = b;
921    }
922   
 
923  0 toggle @Override
924    public void hyperlinkUpdate(HyperlinkEvent e)
925    {
926  0 Desktop.hyperlinkUpdate(e);
927    }
928   
929    /*
930    * (non-Javadoc)
931    *
932    * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
933    */
 
934  0 toggle @Override
935    public void setProgressBar(String message, long id)
936    {
937  0 progressBar.setProgressBar(message, id);
938    }
939   
 
940  0 toggle @Override
941    public void addProgressBar(long id, String message)
942    {
943  0 progressBar.addProgressBar(id, message);
944    }
945   
 
946  0 toggle @Override
947    public void removeProgressBar(long id)
948    {
949  0 progressBar.removeProgressBar(id);
950    }
951   
 
952  0 toggle @Override
953    public void registerHandler(final long id,
954    final IProgressIndicatorHandler handler)
955    {
956  0 progressBar.registerHandler(id, handler);
957    }
958   
959    /**
960    *
961    * @return true if any progress bars are still active
962    */
 
963  0 toggle @Override
964    public boolean operationInProgress()
965    {
966  0 return progressBar.operationInProgress();
967    }
968   
 
969  0 toggle @Override
970    public JProgressBar getProgressBar(long id)
971    {
972  0 return progressBar.getProgressBar(id);
973    }
974   
 
975  0 toggle public String getMessage(long id)
976    {
977  0 return progressBar.getMessage(id);
978    }
979   
 
980  0 toggle public void setProgressBarMessage(long id, String message)
981    {
982  0 progressBar.setProgressBarMessage(id, message);
983    }
984    }