multiple web service jobs from visible blocks of an alignment.
[jalview.git] / src / jalview / gui / WebserviceInfo.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import java.util.*;\r
22 \r
23 import java.awt.*;\r
24 import java.awt.event.*;\r
25 import java.awt.image.*;\r
26 import javax.swing.*;\r
27 \r
28 import jalview.jbgui.*;\r
29 \r
30 \r
31 /**\r
32  * Base class for web service client thread and gui\r
33  *\r
34  * @author $author$\r
35  * @version $Revision$\r
36  */\r
37 public class WebserviceInfo extends GWebserviceInfo\r
38 {\r
39 \r
40     /** Job is Queued */\r
41     public static final int STATE_QUEUING = 0;\r
42 \r
43     /** Job is Running */\r
44     public static final int STATE_RUNNING = 1;\r
45 \r
46     /** Job has finished with no errors */\r
47     public static final int STATE_STOPPED_OK = 2;\r
48 \r
49     /** Job has been cancelled with no errors */\r
50     public static final int STATE_CANCELLED_OK = 3;\r
51 \r
52     /** job has stopped because of some error */\r
53     public static final int STATE_STOPPED_ERROR = 4;\r
54 \r
55     /** job has failed because of some unavoidable service interruption */\r
56     public static final int STATE_STOPPED_SERVERERROR = 5;\r
57     int currentStatus = STATE_QUEUING;\r
58     Image image;\r
59     int angle = 0;\r
60     String title = "";\r
61     jalview.ws.WSClientI thisService;\r
62     boolean serviceIsCancellable;\r
63     JInternalFrame frame;\r
64     JTabbedPane subjobs=null;\r
65     java.util.Vector jobPanes = null;\r
66     // tabbed or not\r
67     public synchronized int addJobPane() {\r
68       JScrollPane jobpane = new JScrollPane();\r
69       JTextArea progressText = new JTextArea();\r
70       progressText.setFont(new java.awt.Font("Verdana", 0, 10));\r
71       progressText.setBorder(null);\r
72       progressText.setEditable(false);\r
73       progressText.setText("WS Job");\r
74       progressText.setLineWrap(true);\r
75       progressText.setWrapStyleWord(true);\r
76       jobpane.setName("JobPane");\r
77       jobpane.getViewport().add(progressText, null);\r
78       jobpane.setBorder(null);\r
79       if (jobPanes==null) {\r
80         jobPanes = new Vector();\r
81       }\r
82       int newpane = jobPanes.size();\r
83       jobPanes.add(jobpane);\r
84 \r
85       if (newpane==0) {\r
86         this.add(jobpane, BorderLayout.CENTER);\r
87       } else {\r
88         if (newpane==1) {\r
89         // revert to a tabbed pane.\r
90         JScrollPane firstpane;\r
91         this.remove(firstpane=(JScrollPane) jobPanes.get(0));\r
92         subjobs=new JTabbedPane();\r
93           this.add(subjobs, BorderLayout.CENTER);\r
94           subjobs.add(firstpane);\r
95           subjobs.setTitleAt(0, firstpane.getName());\r
96         }\r
97         subjobs.add(jobpane);\r
98       }\r
99       return newpane; // index for accessor methods below\r
100     }\r
101     /**\r
102      * Creates a new WebserviceInfo object.\r
103      *\r
104      * @param title short name and job type\r
105      * @param info reference or other human readable description\r
106      */\r
107     public WebserviceInfo(String title, String info)\r
108     {\r
109         init(title, info, 520, 500);\r
110     }\r
111 \r
112     /**\r
113      * Creates a new WebserviceInfo object.\r
114      *\r
115      * @param title DOCUMENT ME!\r
116      * @param info DOCUMENT ME!\r
117      * @param width DOCUMENT ME!\r
118      * @param height DOCUMENT ME!\r
119      */\r
120     public WebserviceInfo(String title, String info, int width, int height)\r
121     {\r
122         init(title, info, width, height);\r
123     }\r
124 \r
125     /**\r
126      * DOCUMENT ME!\r
127      *\r
128      * @return DOCUMENT ME!\r
129      */\r
130     public jalview.ws.WSClientI getthisService()\r
131     {\r
132         return thisService;\r
133     }\r
134 \r
135     /**\r
136      * DOCUMENT ME!\r
137      *\r
138      * @param newservice DOCUMENT ME!\r
139      */\r
140     public void setthisService(jalview.ws.WSClientI newservice)\r
141     {\r
142         thisService = newservice;\r
143         serviceIsCancellable = newservice.isCancellable();\r
144     }\r
145 \r
146     /**\r
147      * DOCUMENT ME!\r
148      *\r
149      * @param title DOCUMENT ME!\r
150      * @param info DOCUMENT ME!\r
151      * @param width DOCUMENT ME!\r
152      * @param height DOCUMENT ME!\r
153      */\r
154     void init(String title, String info, int width, int height)\r
155     {\r
156         frame = new JInternalFrame();\r
157         frame.setContentPane(this);\r
158         Desktop.addInternalFrame(frame, title, width, height);\r
159         frame.setClosable(false);\r
160 \r
161         this.title = title;\r
162         setInfoText(info);\r
163 \r
164         java.net.URL url = getClass().getResource("/images/logo.gif");\r
165         image = java.awt.Toolkit.getDefaultToolkit().createImage(url);\r
166 \r
167         MediaTracker mt = new MediaTracker(this);\r
168         mt.addImage(image, 0);\r
169 \r
170         try\r
171         {\r
172             mt.waitForID(0);\r
173         }\r
174         catch (Exception ex)\r
175         {\r
176         }\r
177 \r
178         AnimatedPanel ap = new AnimatedPanel();\r
179         titlePanel.add(ap, BorderLayout.CENTER);\r
180 \r
181         Thread thread = new Thread(ap);\r
182         thread.start();\r
183     }\r
184 \r
185     /**\r
186      * DOCUMENT ME!\r
187      *\r
188      * @param status integer status from state constants\r
189      */\r
190     public void setStatus(int status)\r
191     {\r
192         currentStatus = status;\r
193     }\r
194     /**\r
195      * subjob status indicator\r
196      * @param jobpane\r
197      * @param status\r
198      */\r
199     public void setStatus(int jobpane, int status) {\r
200       if (jobpane<0 || jobpane>=jobPanes.size()) {\r
201         throw new Error("setStatus called for non-existent job pane."+jobpane);\r
202       }\r
203       switch (status) {\r
204       case STATE_QUEUING:\r
205         setProgressText(jobpane, "QUEUED");\r
206         break;\r
207       case STATE_RUNNING:\r
208         setProgressText(jobpane, "RUNNING");\r
209         break;\r
210       case STATE_STOPPED_OK:\r
211         setProgressText(jobpane, "FINISHED");\r
212       break;\r
213       case STATE_CANCELLED_OK:\r
214         setProgressText(jobpane, "CANCELLED");\r
215         break;\r
216       case STATE_STOPPED_ERROR:\r
217         setProgressText(jobpane, "BROKEN");\r
218         break;\r
219       case STATE_STOPPED_SERVERERROR:\r
220         setProgressText(jobpane, "ALERT");\r
221         break;\r
222         default:\r
223           setProgressText(jobpane, "UNKNOWN STATE");\r
224       }\r
225     }\r
226     /**\r
227      * DOCUMENT ME!\r
228      *\r
229      * @return DOCUMENT ME!\r
230      */\r
231     public String getInfoText()\r
232     {\r
233         return infoText.getText();\r
234     }\r
235 \r
236     /**\r
237      * DOCUMENT ME!\r
238      *\r
239      * @param text DOCUMENT ME!\r
240      */\r
241     public void setInfoText(String text)\r
242     {\r
243         infoText.setText(text);\r
244     }\r
245 \r
246     /**\r
247      * DOCUMENT ME!\r
248      *\r
249      * @param text DOCUMENT ME!\r
250      */\r
251     public void appendInfoText(String text)\r
252     {\r
253         infoText.append(text);\r
254     }\r
255     /**\r
256      * DOCUMENT ME!\r
257      *\r
258      * @return DOCUMENT ME!\r
259      */\r
260     public String getProgressText(int which)\r
261     {\r
262       if (jobPanes == null)\r
263         addJobPane();\r
264       return ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().\r
265               getComponent(0)).getText();\r
266     }\r
267     /**\r
268      * DOCUMENT ME!\r
269      *\r
270      * @param text DOCUMENT ME!\r
271      */\r
272     public void setProgressText(int which, String text)\r
273     {\r
274       if (jobPanes == null)\r
275         addJobPane();\r
276       ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().\r
277        getComponent(0)).setText(text);\r
278     }\r
279 \r
280     /**\r
281      * DOCUMENT ME!\r
282      *\r
283      * @param text DOCUMENT ME!\r
284      */\r
285     public void appendProgressText(int which, String text)\r
286     {\r
287       if (jobPanes == null)\r
288         addJobPane();\r
289       ( (JTextArea) ( (JScrollPane) jobPanes.get(which)).getViewport().\r
290        getComponent(0)).append(text);\r
291     }\r
292     /**\r
293      * setProgressText(0, text)\r
294      */\r
295     public void setProgressText(String text)\r
296     {\r
297       setProgressText(0, text);\r
298     }\r
299     /**\r
300      * appendProgressText(0, text)\r
301      */\r
302     public void appendProgressText(String text)\r
303     {\r
304       appendProgressText(0, text);\r
305     }\r
306     /**\r
307      * getProgressText(0)\r
308      */\r
309     public String getProgressText()\r
310     {\r
311       return getProgressText(0);\r
312     }\r
313     /**\r
314      * get the tab title for a subjob\r
315      * @param which int\r
316      * @return String\r
317      */\r
318     public String getProgressName(int which) {\r
319       if (jobPanes==null)\r
320         addJobPane();\r
321       if (subjobs!=null)\r
322         return subjobs.getTitleAt(which);\r
323       else\r
324         return ((JScrollPane) jobPanes.get(which)).getViewport().getComponent(0).getName();\r
325     }\r
326     /**\r
327      * set the tab title for a subjob\r
328      * @param name String\r
329      * @param which int\r
330      */\r
331     public void setProgressName(String name, int which) {\r
332       if (subjobs!=null)\r
333         subjobs.setTitleAt(which, name);\r
334       else\r
335         ((JScrollPane) jobPanes.get(which)).getViewport().getComponent(0).setName(name);\r
336     }\r
337 \r
338     /**\r
339      * Gui action for cancelling the current job, if possible.\r
340      *\r
341      * @param e DOCUMENT ME!\r
342      */\r
343     protected void cancel_actionPerformed(ActionEvent e)\r
344     {\r
345         if (!serviceIsCancellable)\r
346         {\r
347             JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
348                 "This job cannot be cancelled.\nJust close the window.", "Cancel job",\r
349                 JOptionPane.WARNING_MESSAGE);\r
350         }\r
351         else\r
352         {\r
353             frame.setClosable(true);\r
354             thisService.cancelJob();\r
355         }\r
356     }\r
357 \r
358     public void setResultsReady()\r
359     {\r
360       frame.setClosable(true);\r
361       buttonPanel.remove(cancel);\r
362       buttonPanel.add(showResultsNewFrame);\r
363       buttonPanel.add(mergeResults);\r
364       buttonPanel.setLayout(new GridLayout(2,1,5,5));\r
365       buttonPanel.validate();\r
366       validate();\r
367     }\r
368 \r
369 \r
370   class AnimatedPanel extends JPanel implements Runnable\r
371     {\r
372         long startTime = 0;\r
373         BufferedImage offscreen;\r
374 \r
375         public void run()\r
376         {\r
377             startTime = System.currentTimeMillis();\r
378             Graphics2D g = null;\r
379 \r
380             while (currentStatus < STATE_STOPPED_OK)\r
381             {\r
382                 try\r
383                 {\r
384                     Thread.sleep(50);\r
385 \r
386                     int units = (int) ( (System.currentTimeMillis() - startTime) /\r
387                                        10f);\r
388                     angle += units;\r
389                     angle %= 360;\r
390                     startTime = System.currentTimeMillis();\r
391 \r
392                     if (offscreen == null || offscreen.getWidth(this) != getWidth()\r
393                         || offscreen.getHeight(this) != getHeight())\r
394                     {\r
395                       offscreen = new BufferedImage(getWidth(), getHeight(),\r
396                                                     BufferedImage.TYPE_INT_ARGB);\r
397                       g = (Graphics2D) offscreen.getGraphics();\r
398                     }\r
399 \r
400                     g.setColor(Color.white);\r
401                     g.fillRect(0, 0, getWidth(), getHeight());\r
402 \r
403                     g.setFont(new Font("Arial", Font.BOLD, 12));\r
404                     g.setColor(Color.black);\r
405 \r
406                     switch (currentStatus)\r
407                     {\r
408                       case STATE_QUEUING:\r
409                         g.drawString(title.concat(" - queuing"), 60, 30);\r
410 \r
411                         break;\r
412 \r
413                       case STATE_RUNNING:\r
414                         g.drawString(title.concat(" - running"), 60, 30);\r
415 \r
416                         break;\r
417 \r
418                       case STATE_STOPPED_OK:\r
419                         g.drawString(title.concat(" - complete"), 60, 30);\r
420 \r
421                         break;\r
422 \r
423                       case STATE_CANCELLED_OK:\r
424                         g.drawString(title.concat(" - job cancelled!"), 60, 30);\r
425 \r
426                         break;\r
427 \r
428                       case STATE_STOPPED_ERROR:\r
429                         g.drawString(title.concat(" - job error!"), 60, 30);\r
430 \r
431                         break;\r
432 \r
433                       case STATE_STOPPED_SERVERERROR:\r
434                         g.drawString(title.concat(" - Server Error! (try later)"),\r
435                                      60,\r
436                                      30);\r
437 \r
438                         break;\r
439                     }\r
440 \r
441 \r
442                     if (currentStatus >= STATE_STOPPED_OK)\r
443                       angle = 0;\r
444 \r
445                     if (image != null)\r
446                     {\r
447                       g.rotate(Math.toRadians(angle), 28, 28);\r
448                       g.drawImage(image, 10, 10, this);\r
449                       g.rotate( -Math.toRadians(angle), 28, 28);\r
450                     }\r
451 \r
452 \r
453                     repaint();\r
454                 }\r
455                 catch (Exception ex)\r
456                 {\r
457                 }\r
458             }\r
459 \r
460             cancel.setEnabled(false);\r
461         }\r
462 \r
463         public void paintComponent(Graphics g1)\r
464         {\r
465             g1.drawImage(offscreen, 0,0,this);\r
466         }\r
467     }\r
468 }\r