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