Splash screen is not added using normal method, prevents null paint bug
[jalview.git] / src / jalview / gui / Desktop.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 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 jalview.io.*;
22 import java.awt.*;
23 import java.awt.datatransfer.*;
24 import java.awt.dnd.*;
25 import java.awt.event.*;
26 import java.lang.reflect.Constructor;
27 import java.util.*;
28
29 import javax.swing.*;
30
31 /**
32  * DOCUMENT ME!
33  *
34  * @author $author$
35  * @version $Revision$
36  */
37 public class Desktop
38     extends jalview.jbgui.GDesktop implements DropTargetListener,
39     ClipboardOwner
40 {
41   /** DOCUMENT ME!! */
42   public static Desktop instance;
43
44   //Need to decide if the Memory Usage is to be included in
45   //Next release or not.
46  // public static MyDesktopPane desktop;
47    public static JDesktopPane desktop;
48
49
50   static int openFrameCount = 0;
51   static final int xOffset = 30;
52   static final int yOffset = 30;
53   public static jalview.ws.Discoverer discoverer;
54
55   public static Object[] jalviewClipboard;
56   public static boolean internalCopy = false;
57
58   static int fileLoadingCount = 0;
59
60   /**
61    * Creates a new Desktop object.
62    */
63   public Desktop()
64   {
65     instance = this;
66     doVamsasClientCheck();
67     doGroovyCheck();
68
69
70     setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
71     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
72
73     desktop = new JDesktopPane();
74     desktop.setBackground(Color.white);
75     getContentPane().setLayout(new BorderLayout());
76     getContentPane().add(desktop, BorderLayout.CENTER);
77     desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
78
79     // This line prevents Windows Look&Feel resizing all new windows to maximum
80     // if previous window was maximised
81     desktop.setDesktopManager(new DefaultDesktopManager());
82
83     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
84     String x = jalview.bin.Cache.getProperty("SCREEN_X");
85     String y = jalview.bin.Cache.getProperty("SCREEN_Y");
86     String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");
87     String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");
88
89     if ( (x != null) && (y != null) && (width != null) && (height != null))
90     {
91       setBounds(Integer.parseInt(x), Integer.parseInt(y),
92                 Integer.parseInt(width), Integer.parseInt(height));
93     }
94     else
95     {
96       setBounds( (int) (screenSize.width - 900) / 2,
97                 (int) (screenSize.height - 650) / 2, 900, 650);
98     }
99
100     this.addWindowListener(new WindowAdapter()
101     {
102       public void windowClosing(WindowEvent evt)
103       {
104         quit();
105       }
106     });
107
108     this.addMouseListener(new MouseAdapter()
109         {
110           public void mousePressed(MouseEvent evt)
111           {
112             if(SwingUtilities.isRightMouseButton(evt))
113             {
114               showPasteMenu(evt.getX(), evt.getY());
115             }
116           }
117         });
118
119
120     this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
121
122     /////////Add a splashscreen on startup
123     /////////Add a splashscreen on startup
124     new SplashScreen();
125
126
127     discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
128   }
129
130   private void doVamsasClientCheck()
131   {
132     if (jalview.bin.Cache.vamsasJarsPresent())
133     {
134       VamsasMenu.setVisible(true);
135       vamsasLoad.setVisible(true);
136     }
137   }
138
139   void showPasteMenu(int x, int y)
140   {
141     JPopupMenu popup = new JPopupMenu();
142     JMenuItem item = new JMenuItem("Paste To New Window");
143     item.addActionListener(new ActionListener()
144     {
145       public void actionPerformed(ActionEvent evt)
146       {
147         paste();
148       }
149     });
150
151     popup.add(item);
152     popup.show(this, x, y);
153   }
154
155   public void paste()
156   {
157     try
158     {
159       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
160       Transferable contents = c.getContents(this);
161
162       if (contents != null)
163       {
164         String file = (String) contents
165             .getTransferData(DataFlavor.stringFlavor);
166
167         String format = new IdentifyFile().Identify(file,
168                                                     FormatAdapter.PASTE);
169
170         new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
171
172       }
173     }
174     catch (Exception ex)
175     {
176       System.out.println("Unable to paste alignment from system clipboard:\n"
177                          + ex);
178     }
179   }
180
181   /**
182    * DOCUMENT ME!
183    *
184    * @param frame DOCUMENT ME!
185    * @param title DOCUMENT ME!
186    * @param w DOCUMENT ME!
187    * @param h DOCUMENT ME!
188    */
189   public static synchronized void addInternalFrame(final JInternalFrame frame,
190       String title, int w, int h)
191   {
192     addInternalFrame(frame, title, w, h, true);
193   }
194
195   /**
196    * DOCUMENT ME!
197    *
198    * @param frame DOCUMENT ME!
199    * @param title DOCUMENT ME!
200    * @param w DOCUMENT ME!
201    * @param h DOCUMENT ME!
202    * @param resizable DOCUMENT ME!
203    */
204   public static synchronized void addInternalFrame(final JInternalFrame frame,
205       String title, int w, int h, boolean resizable)
206   {
207
208     frame.setTitle(title);
209     if (frame.getWidth() < 1 || frame.getHeight() < 1)
210     {
211       frame.setSize(w, h);
212     }
213     // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
214     // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
215     // IF JALVIEW IS RUNNING HEADLESS
216     /////////////////////////////////////////////////
217     if (System.getProperty("java.awt.headless") != null
218         && System.getProperty("java.awt.headless").equals("true"))
219     {
220       return;
221     }
222
223     openFrameCount++;
224
225     frame.setVisible(true);
226     frame.setClosable(true);
227     frame.setResizable(resizable);
228     frame.setMaximizable(resizable);
229     frame.setIconifiable(resizable);
230     frame.setFrameIcon(null);
231
232     if (frame.getX() < 1 && frame.getY() < 1)
233     {
234       frame.setLocation(xOffset * openFrameCount,
235                         yOffset * ( (openFrameCount - 1) % 10) + yOffset);
236     }
237
238     final JMenuItem menuItem = new JMenuItem(title);
239     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
240     {
241       public void internalFrameActivated(javax.swing.event.
242                                          InternalFrameEvent evt)
243       {
244         JInternalFrame itf = desktop.getSelectedFrame();
245         if (itf != null)
246         {
247           itf.requestFocus();
248         }
249
250       }
251
252       public void internalFrameClosed(
253           javax.swing.event.InternalFrameEvent evt)
254       {
255         PaintRefresher.RemoveComponent(frame);
256         openFrameCount--;
257         windowMenu.remove(menuItem);
258         JInternalFrame itf = desktop.getSelectedFrame();
259         if (itf != null)
260         {
261           itf.requestFocus();
262         }
263         System.gc();
264       }
265       ;
266     });
267
268     menuItem.addActionListener(new ActionListener()
269     {
270       public void actionPerformed(ActionEvent e)
271       {
272         try
273         {
274           frame.setSelected(true);
275           frame.setIcon(false);
276         }
277         catch (java.beans.PropertyVetoException ex)
278         {
279
280         }
281       }
282     });
283
284     windowMenu.add(menuItem);
285
286     desktop.add(frame);
287     frame.toFront();
288     try
289     {
290       frame.setSelected(true);
291       frame.requestFocus();
292     }
293     catch (java.beans.PropertyVetoException ve)
294     {}
295   }
296
297   public void lostOwnership(Clipboard clipboard, Transferable contents)
298   {
299     if (!internalCopy)
300     {
301       Desktop.jalviewClipboard = null;
302     }
303
304     internalCopy = false;
305   }
306
307   public void dragEnter(DropTargetDragEvent evt)
308   {}
309
310   public void dragExit(DropTargetEvent evt)
311   {}
312
313   public void dragOver(DropTargetDragEvent evt)
314   {}
315
316   public void dropActionChanged(DropTargetDragEvent evt)
317   {}
318
319   /**
320    * DOCUMENT ME!
321    *
322    * @param evt DOCUMENT ME!
323    */
324   public void drop(DropTargetDropEvent evt)
325   {
326     Transferable t = evt.getTransferable();
327     java.util.List files = null;
328
329     try
330     {
331       DataFlavor uriListFlavor = new DataFlavor(
332           "text/uri-list;class=java.lang.String");
333       if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
334       {
335         //Works on Windows and MacOSX
336         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
337         files = (java.util.List) t.getTransferData(DataFlavor.
338             javaFileListFlavor);
339       }
340       else if (t.isDataFlavorSupported(uriListFlavor))
341       {
342         // This is used by Unix drag system
343         evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
344         String data = (String) t.getTransferData(uriListFlavor);
345         files = new java.util.ArrayList(1);
346         for (java.util.StringTokenizer st = new java.util.StringTokenizer(
347             data,
348             "\r\n");
349              st.hasMoreTokens(); )
350         {
351           String s = st.nextToken();
352           if (s.startsWith("#"))
353           {
354             // the line is a comment (as per the RFC 2483)
355             continue;
356           }
357
358           java.net.URI uri = new java.net.URI(s);
359           java.io.File file = new java.io.File(uri);
360           files.add(file);
361         }
362       }
363     }
364     catch (Exception e)
365     {}
366
367     if (files != null)
368     {
369       try
370       {
371         for (int i = 0; i < files.size(); i++)
372         {
373           String file = files.get(i).toString();
374           String protocol = FormatAdapter.FILE;
375           String format = null;
376
377           if (file.endsWith(".jar"))
378           {
379             format = "Jalview";
380
381           }
382           else
383           {
384             format = new IdentifyFile().Identify(file,
385                                                  protocol);
386           }
387
388           new FileLoader().LoadFile(file, protocol, format);
389
390         }
391       }
392       catch (Exception ex)
393       {}
394     }
395   }
396
397   /**
398    * DOCUMENT ME!
399    *
400    * @param e DOCUMENT ME!
401    */
402   public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
403   {
404     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
405         getProperty(
406             "LAST_DIRECTORY"),
407         new String[]
408         {
409         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
410         "jar"
411     },
412         new String[]
413         {
414         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
415     }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
416
417     chooser.setFileView(new JalviewFileView());
418     chooser.setDialogTitle("Open local file");
419     chooser.setToolTipText("Open");
420
421     int value = chooser.showOpenDialog(this);
422
423     if (value == JalviewFileChooser.APPROVE_OPTION)
424     {
425       String choice = chooser.getSelectedFile().getPath();
426       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
427                                     chooser.getSelectedFile().getParent());
428
429       String format = null;
430       if (chooser.getSelectedFormat().equals("Jalview"))
431       {
432         format = "Jalview";
433       }
434       else
435       {
436         format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
437       }
438
439       if (viewport != null)
440       {
441         new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE, format);
442       }
443       else
444       {
445         new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
446       }
447     }
448   }
449
450   /**
451    * DOCUMENT ME!
452    *
453    * @param e DOCUMENT ME!
454    */
455   public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
456   {
457     // This construct allows us to have a wider textfield
458     // for viewing
459     JLabel label = new JLabel("Enter URL of Input File");
460     final JComboBox history = new JComboBox();
461
462     JPanel panel = new JPanel(new GridLayout(2, 1));
463     panel.add(label);
464     panel.add(history);
465     history.setPreferredSize(new Dimension(400, 20));
466     history.setEditable(true);
467     history.addItem("http://www.");
468
469     String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
470
471     StringTokenizer st;
472
473     if (historyItems != null)
474     {
475       st = new StringTokenizer(historyItems, "\t");
476
477       while (st.hasMoreTokens())
478       {
479         history.addItem(st.nextElement());
480       }
481     }
482
483     int reply = JOptionPane.showInternalConfirmDialog(desktop,
484         panel, "Input Alignment From URL",
485         JOptionPane.OK_CANCEL_OPTION);
486
487     if (reply != JOptionPane.OK_OPTION)
488     {
489       return;
490     }
491
492     String url = history.getSelectedItem().toString();
493
494     if (url.toLowerCase().endsWith(".jar"))
495     {
496       if (viewport != null)
497       {
498         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, "Jalview");
499       }
500       else
501       {
502         new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
503       }
504     }
505     else
506     {
507       String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
508
509       if (format.equals("URL NOT FOUND"))
510       {
511         JOptionPane.showInternalMessageDialog(Desktop.desktop,
512                                               "Couldn't locate " + url,
513                                               "URL not found",
514                                               JOptionPane.WARNING_MESSAGE);
515
516         return;
517       }
518
519       if (viewport != null)
520       {
521         new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
522       }
523       else
524       {
525         new FileLoader().LoadFile(url, FormatAdapter.URL, format);
526       }
527     }
528   }
529
530   /**
531    * DOCUMENT ME!
532    *
533    * @param e DOCUMENT ME!
534    */
535   public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
536   {
537     CutAndPasteTransfer cap = new CutAndPasteTransfer();
538     cap.setForInput(viewport);
539     Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
540   }
541
542   /*
543    * Exit the program
544    */
545   public void quit()
546   {
547     jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");
548     jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");
549     jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");
550     jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");
551     System.exit(0);
552   }
553
554   /**
555    * DOCUMENT ME!
556    *
557    * @param e DOCUMENT ME!
558    */
559   public void aboutMenuItem_actionPerformed(ActionEvent e)
560   {
561     StringBuffer message = new StringBuffer("JalView version " +
562                                             jalview.bin.Cache.getProperty(
563                                                 "VERSION") +
564                                             "; last updated: " +
565                                             jalview.bin.
566                                             Cache.getDefault("BUILD_DATE",
567         "unknown"));
568
569     if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
570         jalview.bin.Cache.getProperty("VERSION")))
571     {
572       message.append("\n\n!! Jalview version "
573                      + jalview.bin.Cache.getProperty("LATEST_VERSION")
574                      +
575           " is available for download from http://www.jalview.org !!\n");
576
577     }
578
579     message.append("\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +
580                    "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +
581                    "\nFor all issues relating to Jalview, email help@jalview.org" +
582                    "\n\nIf  you use JalView, please cite:" +
583                    "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +
584                    "\nBioinformatics,  2004 20;426-7.");
585
586     JOptionPane.showInternalMessageDialog(Desktop.desktop,
587
588                                           message.toString(), "About Jalview",
589                                           JOptionPane.INFORMATION_MESSAGE);
590   }
591
592   /**
593    * DOCUMENT ME!
594    *
595    * @param e DOCUMENT ME!
596    */
597   public void documentationMenuItem_actionPerformed(ActionEvent e)
598   {
599     try
600     {
601       ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
602       java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
603       javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
604
605       javax.help.HelpBroker hb = hs.createHelpBroker();
606       hb.setCurrentID("home");
607       hb.setDisplayed(true);
608     }
609     catch (Exception ex)
610     {}
611   }
612
613   public void closeAll_actionPerformed(ActionEvent e)
614   {
615     JInternalFrame[] frames = desktop.getAllFrames();
616     for (int i = 0; i < frames.length; i++)
617     {
618       try
619       {
620         frames[i].setClosed(true);
621       }
622       catch (java.beans.PropertyVetoException ex)
623       {}
624     }
625     System.out.println("ALL CLOSED");
626
627   }
628
629   public void raiseRelated_actionPerformed(ActionEvent e)
630   {
631     reorderAssociatedWindows(false, false);
632   }
633
634   public void minimizeAssociated_actionPerformed(ActionEvent e)
635   {
636     reorderAssociatedWindows(true, false);
637   }
638
639   void closeAssociatedWindows()
640   {
641     reorderAssociatedWindows(false, true);
642   }
643
644   void reorderAssociatedWindows(boolean minimize, boolean close)
645   {
646     JInternalFrame[] frames = desktop.getAllFrames();
647     if (frames == null || frames.length < 1)
648     {
649       return;
650     }
651
652     AlignViewport source = null, target = null;
653     if (frames[0] instanceof AlignFrame)
654     {
655       source = ( (AlignFrame) frames[0]).getCurrentView();
656     }
657     else if (frames[0] instanceof TreePanel)
658     {
659       source = ( (TreePanel) frames[0]).getViewPort();
660     }
661     else if (frames[0] instanceof PCAPanel)
662     {
663       source = ( (PCAPanel) frames[0]).av;
664     }
665     else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
666     {
667       source = ( (PairwiseAlignPanel) frames[0].getContentPane()).av;
668     }
669
670     if (source != null)
671     {
672       for (int i = 0; i < frames.length; i++)
673       {
674         target = null;
675         if (frames[i] == null)
676         {
677           continue;
678         }
679         if (frames[i] instanceof AlignFrame)
680         {
681           target = ( (AlignFrame) frames[i]).getCurrentView();
682         }
683         else if (frames[i] instanceof TreePanel)
684         {
685           target = ( (TreePanel) frames[i]).getViewPort();
686         }
687         else if (frames[i] instanceof PCAPanel)
688         {
689           target = ( (PCAPanel) frames[i]).av;
690         }
691         else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
692         {
693           target = ( (PairwiseAlignPanel) frames[i].getContentPane()).av;
694         }
695
696         if (source == target)
697         {
698           try
699           {
700             if (close)
701             {
702               frames[i].setClosed(true);
703             }
704             else
705             {
706               frames[i].setIcon(minimize);
707               if (!minimize)
708               {
709                 frames[i].toFront();
710               }
711             }
712
713           }
714           catch (java.beans.PropertyVetoException ex)
715           {}
716         }
717       }
718     }
719   }
720
721   /**
722    * DOCUMENT ME!
723    *
724    * @param e DOCUMENT ME!
725    */
726   protected void preferences_actionPerformed(ActionEvent e)
727   {
728     new Preferences();
729   }
730
731   /**
732    * DOCUMENT ME!
733    *
734    * @param e DOCUMENT ME!
735    */
736   public void saveState_actionPerformed(ActionEvent e)
737   {
738     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
739         getProperty(
740             "LAST_DIRECTORY"), new String[]
741         {"jar"},
742         new String[]
743         {"Jalview Project"}, "Jalview Project");
744
745     chooser.setFileView(new JalviewFileView());
746     chooser.setDialogTitle("Save State");
747
748     int value = chooser.showSaveDialog(this);
749
750     if (value == JalviewFileChooser.APPROVE_OPTION)
751     {
752       java.io.File choice = chooser.getSelectedFile();
753       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
754       new Jalview2XML().SaveState(choice);
755     }
756   }
757
758   /**
759    * DOCUMENT ME!
760    *
761    * @param e DOCUMENT ME!
762    */
763   public void loadState_actionPerformed(ActionEvent e)
764   {
765     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
766         getProperty(
767             "LAST_DIRECTORY"), new String[]
768         {"jar"},
769         new String[]
770         {"Jalview Project"}, "Jalview Project");
771     chooser.setFileView(new JalviewFileView());
772     chooser.setDialogTitle("Restore state");
773
774     int value = chooser.showOpenDialog(this);
775
776     if (value == JalviewFileChooser.APPROVE_OPTION)
777     {
778       String choice = chooser.getSelectedFile().getAbsolutePath();
779       jalview.bin.Cache.setProperty("LAST_DIRECTORY",
780                                     chooser.getSelectedFile().getParent());
781       new Jalview2XML().LoadJalviewAlign(choice);
782     }
783   }
784
785   /*  public void vamsasLoad_actionPerformed(ActionEvent e)
786     {
787       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
788           getProperty("LAST_DIRECTORY"));
789
790       chooser.setFileView(new JalviewFileView());
791       chooser.setDialogTitle("Load Vamsas file");
792       chooser.setToolTipText("Import");
793
794       int value = chooser.showOpenDialog(this);
795
796       if (value == JalviewFileChooser.APPROVE_OPTION)
797       {
798         jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(null);
799         vs.load(
800             chooser.getSelectedFile().getAbsolutePath()
801             );
802       }
803
804     }*/
805
806
807   public void inputSequence_actionPerformed(ActionEvent e)
808   {
809     new SequenceFetcher(null);
810   }
811
812   JPanel progressPanel;
813
814   public void startLoading(final String fileName)
815   {
816     if (fileLoadingCount == 0)
817     {
818       progressPanel = new JPanel(new BorderLayout());
819       JProgressBar progressBar = new JProgressBar();
820       progressBar.setIndeterminate(true);
821
822       progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
823                         BorderLayout.WEST);
824
825       progressPanel.add(progressBar, BorderLayout.CENTER);
826
827       instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
828     }
829     fileLoadingCount++;
830     validate();
831   }
832
833   public void stopLoading()
834   {
835     fileLoadingCount--;
836     if (fileLoadingCount < 1)
837     {
838       if (progressPanel != null)
839       {
840         this.getContentPane().remove(progressPanel);
841         progressPanel = null;
842       }
843       fileLoadingCount = 0;
844     }
845     validate();
846   }
847
848   public static int getViewCount(String viewId)
849   {
850     int count = 0;
851     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
852     for (int t = 0; t < frames.length; t++)
853     {
854       if (frames[t] instanceof AlignFrame)
855       {
856         AlignFrame af = (AlignFrame) frames[t];
857         for (int a = 0; a < af.alignPanels.size(); a++)
858         {
859           if (viewId.equals(
860               ( (AlignmentPanel) af.alignPanels.elementAt(a)).av.
861               getSequenceSetId())
862               )
863           {
864             count++;
865           }
866         }
867       }
868     }
869
870     return count;
871   }
872
873   public void explodeViews(AlignFrame af)
874   {
875     int size = af.alignPanels.size();
876     if (size < 2)
877     {
878       return;
879     }
880
881     for (int i = 0; i < size; i++)
882     {
883       AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
884       AlignFrame newaf = new AlignFrame(ap);
885       if (ap.av.explodedPosition != null &&
886           !ap.av.explodedPosition.equals(af.getBounds()))
887       {
888         newaf.setBounds(ap.av.explodedPosition);
889       }
890
891       ap.av.gatherViewsHere = false;
892
893       addInternalFrame(newaf, af.getTitle(),
894                        AlignFrame.DEFAULT_WIDTH,
895                        AlignFrame.DEFAULT_HEIGHT);
896     }
897
898     af.alignPanels.clear();
899     af.closeMenuItem_actionPerformed(true);
900
901   }
902
903   public void gatherViews(AlignFrame source)
904   {
905     source.viewport.gatherViewsHere = true;
906     source.viewport.explodedPosition = source.getBounds();
907     JInternalFrame[] frames = desktop.getAllFrames();
908     String viewId = source.viewport.sequenceSetID;
909
910     for (int t = 0; t < frames.length; t++)
911     {
912       if (frames[t] instanceof AlignFrame && frames[t] != source)
913       {
914         AlignFrame af = (AlignFrame) frames[t];
915         boolean gatherThis = false;
916         for (int a = 0; a < af.alignPanels.size(); a++)
917         {
918           AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
919           if (viewId.equals(ap.av.getSequenceSetId()))
920           {
921             gatherThis = true;
922             ap.av.gatherViewsHere = false;
923             ap.av.explodedPosition = af.getBounds();
924             source.addAlignmentPanel(ap, false);
925           }
926         }
927
928         if (gatherThis)
929         {
930           af.alignPanels.clear();
931           af.closeMenuItem_actionPerformed(true);
932         }
933       }
934     }
935
936   }
937
938   jalview.gui.VamsasClient v_client = null;
939   public void vamsasLoad_actionPerformed(ActionEvent e)
940   {
941     if (v_client == null)
942     {
943       // Start a session.
944       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
945           getProperty("LAST_DIRECTORY"));
946
947       chooser.setFileView(new JalviewFileView());
948       chooser.setDialogTitle("Load Vamsas file");
949       chooser.setToolTipText("Import");
950
951       int value = chooser.showOpenDialog(this);
952
953       if (value == JalviewFileChooser.APPROVE_OPTION)
954       {
955         v_client = new jalview.gui.VamsasClient(this,
956                                                 chooser.getSelectedFile());
957         this.vamsasLoad.setText("Session Update");
958         this.vamsasStop.setVisible(true);
959         v_client.initial_update();
960         v_client.startWatcher();
961       }
962     }
963     else
964     {
965       // store current data in session.
966       v_client.push_update();
967     }
968   }
969
970   public void vamsasStop_actionPerformed(ActionEvent e)
971   {
972     if (v_client != null)
973     {
974       v_client.end_session();
975       v_client = null;
976       this.vamsasStop.setVisible(false);
977       this.vamsasLoad.setText("Start Vamsas Session...");
978     }
979   }
980
981   /**
982    * hide vamsas user gui bits when a vamsas document event is being handled.
983    * @param b true to hide gui, false to reveal gui
984    */
985   public void setVamsasUpdate(boolean b)
986   {
987     jalview.bin.Cache.log.debug("Setting gui for Vamsas update " +
988                                 (b ? "in progress" : "finished"));
989     vamsasLoad.setVisible(!b);
990     vamsasStop.setVisible(!b);
991
992   }
993
994   public JInternalFrame[] getAllFrames()
995   {
996     return desktop.getAllFrames();
997   }
998
999
1000   /**
1001    * Checks the given url to see if it gives a response indicating that
1002    * the user should be informed of a new questionnaire.
1003    * @param url
1004    */
1005   public void checkForQuestionnaire(String url)
1006   {
1007     UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1008     javax.swing.SwingUtilities.invokeLater(jvq);
1009   }
1010
1011   /*DISABLED
1012    class  MyDesktopPane extends JDesktopPane implements Runnable
1013   {
1014     boolean showMemoryUsage = false;
1015     Runtime runtime;
1016     java.text.NumberFormat df;
1017
1018     float maxMemory, allocatedMemory, freeMemory, totalFreeMemory, percentUsage;
1019
1020     public MyDesktopPane(boolean showMemoryUsage)
1021     {
1022       showMemoryUsage(showMemoryUsage);
1023     }
1024
1025     public void showMemoryUsage(boolean showMemoryUsage)
1026     {
1027       this.showMemoryUsage = showMemoryUsage;
1028       if (showMemoryUsage)
1029       {
1030         Thread worker = new Thread(this);
1031         worker.start();
1032       }
1033     }
1034
1035     public void run()
1036     {
1037       df = java.text.NumberFormat.getNumberInstance();
1038       df.setMaximumFractionDigits(2);
1039       runtime = Runtime.getRuntime();
1040
1041       while (showMemoryUsage)
1042       {
1043         try
1044         {
1045           Thread.sleep(3000);
1046           maxMemory = runtime.maxMemory() / 1048576f;
1047           allocatedMemory = runtime.totalMemory() / 1048576f;
1048           freeMemory = runtime.freeMemory() / 1048576f;
1049           totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1050
1051           percentUsage = (totalFreeMemory / maxMemory) * 100;
1052
1053         //  if (percentUsage < 20)
1054           {
1055             //   border1 = BorderFactory.createMatteBorder(12, 12, 12, 12, Color.red);
1056             //    instance.set.setBorder(border1);
1057           }
1058           repaint();
1059
1060         }
1061         catch (Exception ex)
1062         {
1063           ex.printStackTrace();
1064         }
1065       }
1066     }
1067
1068     public void paintComponent(Graphics g)
1069     {
1070       if(showMemoryUsage)
1071       {
1072         if (percentUsage < 20)
1073           g.setColor(Color.red);
1074
1075         g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1076                      + "MB; Max Memory: " + df.format(maxMemory)
1077                      + "MB; " + df.format(percentUsage) + "%", 10,
1078                      getHeight() - g.getFontMetrics().getHeight());
1079       }
1080     }
1081   }*/
1082   protected JMenuItem groovyShell;
1083   public void doGroovyCheck() {
1084     if (jalview.bin.Cache.groovyJarsPresent())
1085     {
1086       groovyShell = new JMenuItem();
1087       groovyShell.setText("Groovy Shell...");
1088       groovyShell.addActionListener(new ActionListener()
1089       {
1090           public void actionPerformed(ActionEvent e) {
1091               groovyShell_actionPerformed(e);
1092           }
1093       });
1094       toolsMenu.add(groovyShell);
1095       groovyShell.setVisible(true);
1096     }
1097   }
1098   /**
1099    * Accessor method to quickly get all the AlignmentFrames
1100    * loaded.
1101    */
1102   protected AlignFrame[] getAlignframes() {
1103     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1104
1105     if (frames == null)
1106     {
1107       return null;
1108       }
1109       Vector avp=new Vector();
1110       try
1111       {
1112           //REVERSE ORDER
1113           for (int i = frames.length - 1; i > -1; i--)
1114           {
1115               if (frames[i] instanceof AlignFrame)
1116               {
1117                   AlignFrame af = (AlignFrame) frames[i];
1118                   avp.addElement(af);
1119               }
1120           }
1121       }
1122       catch (Exception ex)
1123       {
1124           ex.printStackTrace();
1125       }
1126       if (avp.size()==0)
1127       {
1128           return null;
1129       }
1130       AlignFrame afs[] = new AlignFrame[avp.size()];
1131       for (int i=0,j=avp.size(); i<j; i++) {
1132           afs[i] = (AlignFrame) avp.elementAt(i);
1133       }
1134       avp.clear();
1135       return afs;
1136   }
1137
1138   /**
1139     * Add Groovy Support to Jalview
1140     */
1141   public void groovyShell_actionPerformed(ActionEvent e) {
1142     // use reflection to avoid creating compilation dependency.
1143     if (!jalview.bin.Cache.groovyJarsPresent())
1144     {
1145       throw new Error("Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1146     }
1147     try {
1148     Class gcClass = Desktop.class.getClassLoader().loadClass("groovy.ui.Console");
1149     Constructor gccons = gcClass.getConstructor(null);
1150     java.lang.reflect.Method setvar = gcClass.getMethod("setVariable", new Class[] { String.class, Object.class} );
1151     java.lang.reflect.Method run = gcClass.getMethod("run", null);
1152     Object gc = gccons.newInstance(null);
1153     setvar.invoke(gc, new Object[] { "Jalview", this});
1154     run.invoke(gc, null);
1155     }
1156     catch (Exception ex)
1157     {
1158       jalview.bin.Cache.log.error("Groovy Shell Creation failed.",ex);
1159       JOptionPane.showInternalMessageDialog(Desktop.desktop,
1160
1161               "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.", "Jalview Groovy Support Failed",
1162               JOptionPane.ERROR_MESSAGE);
1163     }
1164   }
1165 }