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