File Parsing returns Alignments, not Sequence[]
[jalview.git] / src / jalview / gui / Desktop.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 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
23 import java.awt.*;
24 import java.awt.datatransfer.*;
25 import java.awt.dnd.*;
26 import java.awt.event.*;
27 import java.util.*;
28
29 import javax.swing.*;
30
31
32 /**
33  * DOCUMENT ME!
34  *
35  * @author $author$
36  * @version $Revision$
37  */
38 public class Desktop extends jalview.jbgui.GDesktop
39     implements DropTargetListener, ClipboardOwner
40 {
41     /** DOCUMENT ME!! */
42     public static Desktop instance;
43     public static JDesktopPane desktop;
44     static int openFrameCount = 0;
45     static final int xOffset = 30;
46     static final int yOffset = 30;
47     public static jalview.ws.Discoverer discoverer;
48
49     public static Object [] jalviewClipboard;
50
51     static int fileLoadingCount= 0;
52
53     /**
54      * Creates a new Desktop object.
55      */
56     public Desktop()
57     {
58         instance = this;
59         doVamsasClientCheck();
60         Image image = null;
61
62         try
63         {
64             java.net.URL url = getClass().getResource("/images/logo.gif");
65
66             if (url != null)
67             {
68                 image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
69
70                 MediaTracker mt = new MediaTracker(this);
71                 mt.addImage(image, 0);
72                 mt.waitForID(0);
73                 setIconImage(image);
74             }
75         }
76         catch (Exception ex)
77         {
78         }
79
80         setTitle("Jalview "+jalview.bin.Cache.getProperty("VERSION"));
81         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
82         desktop = new JDesktopPane();
83         desktop.setBackground(Color.white);
84         getContentPane().setLayout(new BorderLayout());
85         getContentPane().add(desktop, BorderLayout.CENTER);
86         desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
87
88         // This line prevents Windows Look&Feel resizing all new windows to maximum
89         // if previous window was maximised
90         desktop.setDesktopManager(new DefaultDesktopManager());
91
92         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
93         String x = jalview.bin.Cache.getProperty("SCREEN_X");
94         String y = jalview.bin.Cache.getProperty("SCREEN_Y");
95         String width = jalview.bin.Cache.getProperty("SCREEN_WIDTH");
96         String height = jalview.bin.Cache.getProperty("SCREEN_HEIGHT");
97
98         if ((x != null) && (y != null) && (width != null) && (height != null))
99         {
100             setBounds(Integer.parseInt(x), Integer.parseInt(y),
101                 Integer.parseInt(width), Integer.parseInt(height));
102         }
103         else
104         {
105             setBounds((int) (screenSize.width - 900) / 2,
106                 (int) (screenSize.height - 650) / 2, 900, 650);
107         }
108
109         this.addWindowListener(new WindowAdapter()
110             {
111                 public void windowClosing(WindowEvent evt)
112                 {
113                     quit();
114                 }
115             });
116
117         this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
118
119         /////////Add a splashscreen on startup
120         /////////Add a splashscreen on startup
121         JInternalFrame frame = new JInternalFrame();
122
123         SplashScreen splash = new SplashScreen(frame, image);
124         frame.setContentPane(splash);
125         frame.setLayer(JLayeredPane.PALETTE_LAYER);
126         frame.setLocation((int) ((getWidth() - 750) / 2),
127             (int) ((getHeight() - 160) / 2));
128
129         addInternalFrame(frame, "", 750, 160, false);
130
131         discoverer=new jalview.ws.Discoverer(); // Only gets started if gui is displayed.
132     }
133
134     private void doVamsasClientCheck() {
135       if (jalview.bin.Cache.vamsasJarsPresent()) {
136         VamsasMenu.setVisible(true);
137         vamsasLoad.setVisible(true);
138       }
139
140     }
141
142     /**
143      * DOCUMENT ME!
144      *
145      * @param frame DOCUMENT ME!
146      * @param title DOCUMENT ME!
147      * @param w DOCUMENT ME!
148      * @param h DOCUMENT ME!
149      */
150     public static synchronized void addInternalFrame(final JInternalFrame frame,
151         String title, int w, int h)
152     {
153         addInternalFrame(frame, title, w, h, true);
154     }
155
156     /**
157      * DOCUMENT ME!
158      *
159      * @param frame DOCUMENT ME!
160      * @param title DOCUMENT ME!
161      * @param w DOCUMENT ME!
162      * @param h DOCUMENT ME!
163      * @param resizable DOCUMENT ME!
164      */
165     public static synchronized void addInternalFrame(final JInternalFrame frame,
166         String title, int w, int h, boolean resizable)
167     {
168
169       frame.setTitle(title);
170       if(frame.getWidth()<1 || frame.getHeight()<1)
171       {
172         frame.setSize(w, h);
173       }
174       // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
175       // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
176       // IF JALVIEW IS RUNNING HEADLESS
177       /////////////////////////////////////////////////
178       if (System.getProperty("java.awt.headless") != null
179           && System.getProperty("java.awt.headless").equals("true"))
180       {
181         return;
182       }
183
184
185         openFrameCount++;
186
187         frame.setVisible(true);
188         frame.setClosable(true);
189         frame.setResizable(resizable);
190         frame.setMaximizable(resizable);
191         frame.setIconifiable(resizable);
192         frame.setFrameIcon(null);
193
194         if (frame.getX()<1 && frame.getY()<1)
195        {
196          frame.setLocation(xOffset * openFrameCount, yOffset * ((openFrameCount-1)%10)+yOffset);
197        }
198
199         final JMenuItem menuItem = new JMenuItem(title);
200         frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
201             {
202               public void internalFrameActivated(javax.swing.event.
203                                                  InternalFrameEvent evt)
204               {
205                 JInternalFrame itf = desktop.getSelectedFrame();
206                 if (itf != null)
207                   itf.requestFocus();
208
209               }
210
211
212                 public void internalFrameClosed(
213                     javax.swing.event.InternalFrameEvent evt)
214                 {
215                     PaintRefresher.RemoveComponent(frame);
216                     openFrameCount--;
217                     windowMenu.remove(menuItem);
218                     JInternalFrame itf = desktop.getSelectedFrame();
219                        if (itf != null)
220                         itf.requestFocus();
221                 }
222                 ;
223             });
224
225         menuItem.addActionListener(new ActionListener()
226             {
227                 public void actionPerformed(ActionEvent e)
228                 {
229                     try
230                     {
231                         frame.setSelected(true);
232                         frame.setIcon(false);
233                     }
234                     catch (java.beans.PropertyVetoException ex)
235                     {
236
237                     }
238                 }
239             });
240
241         windowMenu.add(menuItem);
242
243         desktop.add(frame);
244         frame.toFront();
245         try{
246           frame.setSelected(true);
247           frame.requestFocus();
248         }catch(java.beans.PropertyVetoException ve)
249         {   }
250     }
251
252     public void lostOwnership(Clipboard clipboard, Transferable contents)
253     {
254       Desktop.jalviewClipboard = null;
255     }
256
257     public void dragEnter(DropTargetDragEvent evt)
258     {}
259
260     public void dragExit(DropTargetEvent evt)
261     {}
262
263     public void dragOver(DropTargetDragEvent evt)
264     {}
265
266     public void dropActionChanged(DropTargetDragEvent evt)
267     {}
268
269     /**
270      * DOCUMENT ME!
271      *
272      * @param evt DOCUMENT ME!
273      */
274     public void drop(DropTargetDropEvent evt)
275     {
276         Transferable t = evt.getTransferable();
277         java.util.List files = null;
278
279         try
280         {
281           DataFlavor uriListFlavor = new DataFlavor("text/uri-list;class=java.lang.String");
282           if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
283           {
284             //Works on Windows and MacOSX
285             evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
286             files = (java.util.List) t.getTransferData(DataFlavor.javaFileListFlavor);
287           }
288           else if (t.isDataFlavorSupported(uriListFlavor))
289           {
290             // This is used by Unix drag system
291             evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
292             String data = (String) t.getTransferData(uriListFlavor);
293             files = new java.util.ArrayList(1);
294             for (java.util.StringTokenizer st = new java.util.StringTokenizer(
295                 data,
296                 "\r\n");
297                  st.hasMoreTokens(); )
298             {
299               String s = st.nextToken();
300               if (s.startsWith("#"))
301               {
302                 // the line is a comment (as per the RFC 2483)
303                 continue;
304               }
305
306               java.net.URI uri = new java.net.URI(s);
307               java.io.File file = new java.io.File(uri);
308               files.add(file);
309             }
310           }
311         }
312         catch (Exception e)
313         {      }
314
315         if (files != null)
316         {
317           try
318           {
319             for (int i = 0; i < files.size(); i++)
320             {
321               String file = files.get(i).toString();
322               String protocol = FormatAdapter.FILE;
323               String format = null;
324
325               if (file.endsWith(".jar"))
326               {
327                 format = "Jalview";
328
329               }
330               else
331               {
332                 format = new IdentifyFile().Identify(file,
333                                                           protocol);
334               }
335
336
337               new FileLoader().LoadFile(file, protocol, format);
338
339             }
340           }
341           catch (Exception ex)
342           {      }
343         }
344     }
345
346     /**
347      * DOCUMENT ME!
348      *
349      * @param e DOCUMENT ME!
350      */
351     public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
352     {
353         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
354                     "LAST_DIRECTORY"),
355                 new String[]
356                 {
357                     "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",
358                     "jar"
359                 },
360                 new String[]
361                 {
362                     "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"
363                 }, jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
364
365         chooser.setFileView(new JalviewFileView());
366         chooser.setDialogTitle("Open local file");
367         chooser.setToolTipText("Open");
368
369         int value = chooser.showOpenDialog(this);
370
371         if (value == JalviewFileChooser.APPROVE_OPTION)
372         {
373             String choice = chooser.getSelectedFile().getPath();
374             jalview.bin.Cache.setProperty("LAST_DIRECTORY",
375                 chooser.getSelectedFile().getParent());
376
377             String format = null;
378             if (chooser.getSelectedFormat().equals("Jalview"))
379             {
380                 format = "Jalview";
381             }
382             else
383             {
384                 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
385             }
386
387             if (viewport != null)
388               new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE, format);
389             else
390               new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
391         }
392     }
393
394
395
396     /**
397      * DOCUMENT ME!
398      *
399      * @param e DOCUMENT ME!
400      */
401     public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
402     {
403       // This construct allows us to have a wider textfield
404       // for viewing
405       JLabel label = new JLabel("Enter URL of Input File");
406       final JComboBox history = new JComboBox();
407
408       JPanel panel = new JPanel(new GridLayout(2,1));
409       panel.add(label);
410       panel.add(history);
411       history.setPreferredSize(new Dimension(400,20));
412       history.setEditable(true);
413       history.addItem("http://www.");
414
415       String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
416
417       StringTokenizer st;
418
419       if (historyItems != null)
420       {
421         st = new StringTokenizer(historyItems, "\t");
422
423         while (st.hasMoreTokens())
424         {
425           history.addItem(st.nextElement());
426         }
427       }
428
429        int reply = JOptionPane.showInternalConfirmDialog(desktop,
430           panel, "Input Alignment From URL",
431           JOptionPane.OK_CANCEL_OPTION );
432
433
434         if (reply != JOptionPane.OK_OPTION )
435         {
436             return;
437         }
438
439         String url = history.getSelectedItem().toString();
440
441         if (url.toLowerCase().endsWith(".jar"))
442         {
443           if (viewport != null)
444             new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, "Jalview");
445           else
446             new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
447         }
448         else
449         {
450           String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
451
452           if (format.equals("URL NOT FOUND"))
453           {
454             JOptionPane.showInternalMessageDialog(Desktop.desktop,
455                                                   "Couldn't locate " + url,
456                                                   "URL not found",
457                                                   JOptionPane.WARNING_MESSAGE);
458
459             return;
460           }
461
462           if (viewport != null)
463             new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
464           else
465             new FileLoader().LoadFile(url, FormatAdapter.URL, format);
466         }
467     }
468
469     /**
470      * DOCUMENT ME!
471      *
472      * @param e DOCUMENT ME!
473      */
474     public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
475     {
476         CutAndPasteTransfer cap = new CutAndPasteTransfer();
477         cap.setForInput(viewport);
478         Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
479     }
480
481     /*
482      * Exit the program
483      */
484     public void quit()
485     {
486         jalview.bin.Cache.setProperty("SCREEN_X", getBounds().x + "");
487         jalview.bin.Cache.setProperty("SCREEN_Y", getBounds().y + "");
488         jalview.bin.Cache.setProperty("SCREEN_WIDTH", getWidth() + "");
489         jalview.bin.Cache.setProperty("SCREEN_HEIGHT", getHeight() + "");
490         System.exit(0);
491     }
492
493     /**
494      * DOCUMENT ME!
495      *
496      * @param e DOCUMENT ME!
497      */
498     public void aboutMenuItem_actionPerformed(ActionEvent e)
499     {
500       StringBuffer message = new StringBuffer("JalView version " +
501                                               jalview.bin.Cache.getProperty(
502           "VERSION") +
503                                               "; last updated: " +
504                                               jalview.bin.
505                                               Cache.getDefault("BUILD_DATE", "unknown"));
506
507       if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
508           jalview.bin.Cache.getProperty("VERSION")))
509       {
510         message.append("\n\n!! Jalview version "
511                        + jalview.bin.Cache.getProperty("LATEST_VERSION")
512                        + " is available for download from http://www.jalview.org !!\n");
513
514       }
515
516       message.append( "\nAuthors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton." +
517             "\nCurrent development managed by Andrew Waterhouse; Barton Group, University of Dundee." +
518             "\nFor all issues relating to Jalview, email help@jalview.org" +
519             "\n\nIf  you use JalView, please cite:" +
520             "\n\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"" +
521             "\nBioinformatics,  2004 20;426-7.");
522
523         JOptionPane.showInternalMessageDialog(Desktop.desktop,
524
525            message.toString(), "About Jalview",
526             JOptionPane.INFORMATION_MESSAGE);
527     }
528
529     /**
530      * DOCUMENT ME!
531      *
532      * @param e DOCUMENT ME!
533      */
534     public void documentationMenuItem_actionPerformed(ActionEvent e)
535     {
536         try
537         {
538             ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
539             java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
540             javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
541
542             javax.help.HelpBroker hb = hs.createHelpBroker();
543             hb.setCurrentID("home");
544             hb.setDisplayed(true);
545         }
546         catch (Exception ex)
547         {     }
548     }
549
550     public void closeAll_actionPerformed(ActionEvent e)
551     {
552       JInternalFrame [] frames = desktop.getAllFrames();
553       for(int i=0; i<frames.length; i++)
554       {
555         try{
556         frames[i].setClosed(true);
557       }catch(java.beans.PropertyVetoException ex){}
558       }
559     }
560
561     public void raiseRelated_actionPerformed(ActionEvent e)
562     {
563       reorderAssociatedWindows(false, false);
564     }
565
566     public void minimizeAssociated_actionPerformed(ActionEvent e)
567     {
568       reorderAssociatedWindows(true, false);
569     }
570
571     void closeAssociatedWindows()
572     {
573       reorderAssociatedWindows(false, true);
574     }
575
576     void reorderAssociatedWindows(boolean minimize, boolean close)
577     {
578       JInternalFrame[] frames = desktop.getAllFrames();
579       if (frames == null || frames.length<1)
580         return;
581
582       AlignViewport source = null, target = null;
583       if (frames[0] instanceof AlignFrame)
584         source = ( (AlignFrame) frames[0]).getCurrentView();
585       else if (frames[0] instanceof TreePanel)
586         source = ( (TreePanel) frames[0]).getViewPort();
587       else if (frames[0] instanceof PCAPanel)
588         source = ( (PCAPanel) frames[0]).av;
589       else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
590         source = ((PairwiseAlignPanel)frames[0].getContentPane()).av;
591
592
593       if (source != null)
594         for (int i = 0; i < frames.length; i++)
595         {
596           target = null;
597           if(frames[i]==null)
598           {
599             continue;
600           }
601           if (frames[i] instanceof AlignFrame)
602             target = ( (AlignFrame) frames[i]).getCurrentView();
603           else if (frames[i] instanceof TreePanel)
604             target = ( (TreePanel) frames[i]).getViewPort();
605           else if (frames[i] instanceof PCAPanel)
606             target = ( (PCAPanel) frames[i]).av;
607           else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
608             target = ( (PairwiseAlignPanel) frames[i].getContentPane()).av;
609
610           if (source == target)
611           {
612             try
613             {
614               if (close)
615                 frames[i].setClosed(true);
616               else
617               {
618                 frames[i].setIcon(minimize);
619                 if (!minimize)
620                 {
621                   frames[i].toFront();
622                 }
623               }
624
625             }
626             catch (java.beans.PropertyVetoException ex)
627             {       }
628           }
629         }
630     }
631
632
633
634     /**
635      * DOCUMENT ME!
636      *
637      * @param e DOCUMENT ME!
638      */
639     protected void preferences_actionPerformed(ActionEvent e)
640     {
641         new Preferences();
642     }
643
644     /**
645      * DOCUMENT ME!
646      *
647      * @param e DOCUMENT ME!
648      */
649     public void saveState_actionPerformed(ActionEvent e)
650     {
651         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
652                     "LAST_DIRECTORY"), new String[] { "jar" },
653                 new String[] { "Jalview Project" }, "Jalview Project");
654
655         chooser.setFileView(new JalviewFileView());
656         chooser.setDialogTitle("Save State");
657
658         int value = chooser.showSaveDialog(this);
659
660         if (value == JalviewFileChooser.APPROVE_OPTION)
661         {
662             java.io.File choice = chooser.getSelectedFile();
663             jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
664             new Jalview2XML().SaveState(choice);
665         }
666     }
667
668     /**
669      * DOCUMENT ME!
670      *
671      * @param e DOCUMENT ME!
672      */
673     public void loadState_actionPerformed(ActionEvent e)
674     {
675         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(
676                     "LAST_DIRECTORY"), new String[] { "jar" },
677                 new String[] { "Jalview Project" }, "Jalview Project");
678         chooser.setFileView(new JalviewFileView());
679         chooser.setDialogTitle("Restore state");
680
681         int value = chooser.showOpenDialog(this);
682
683         if (value == JalviewFileChooser.APPROVE_OPTION)
684         {
685             String choice = chooser.getSelectedFile().getAbsolutePath();
686             jalview.bin.Cache.setProperty("LAST_DIRECTORY",
687                 chooser.getSelectedFile().getParent());
688             new Jalview2XML().LoadJalviewAlign(choice);
689         }
690     }
691
692   /*  public void vamsasLoad_actionPerformed(ActionEvent e)
693     {
694       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
695           getProperty("LAST_DIRECTORY"));
696
697       chooser.setFileView(new JalviewFileView());
698       chooser.setDialogTitle("Load Vamsas file");
699       chooser.setToolTipText("Import");
700
701       int value = chooser.showOpenDialog(this);
702
703       if (value == JalviewFileChooser.APPROVE_OPTION)
704       {
705         jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(null);
706         vs.load(
707             chooser.getSelectedFile().getAbsolutePath()
708             );
709       }
710
711     }*/
712
713
714     public void inputSequence_actionPerformed(ActionEvent e)
715     {
716       new SequenceFetcher(null);
717     }
718
719     JPanel progressPanel;
720
721     public void startLoading(final String fileName)
722     {
723       if (fileLoadingCount == 0)
724       {
725         progressPanel = new JPanel(new BorderLayout());
726         JProgressBar progressBar = new JProgressBar();
727         progressBar.setIndeterminate(true);
728
729         progressPanel.add(new JLabel("Loading File: " + fileName + "   "),
730                           BorderLayout.WEST);
731
732         progressPanel.add(progressBar, BorderLayout.CENTER);
733
734         instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
735       }
736       fileLoadingCount++;
737       validate();
738     }
739
740     public void stopLoading()
741     {
742       fileLoadingCount--;
743       if (fileLoadingCount < 1)
744       {
745         if(progressPanel!=null)
746         {
747           this.getContentPane().remove(progressPanel);
748           progressPanel = null;
749         }
750         fileLoadingCount = 0;
751       }
752       validate();
753     }
754
755     public static int getViewCount(String viewId)
756     {
757       int count = 0;
758       JInternalFrame[] frames = Desktop.desktop.getAllFrames();
759       for (int t = 0; t < frames.length; t++)
760       {
761         if (frames[t] instanceof AlignFrame)
762         {
763           AlignFrame af = (AlignFrame) frames[t];
764           for(int a=0; a<af.alignPanels.size(); a++)
765           {
766             if(viewId.equals(
767                 ((AlignmentPanel)af.alignPanels.elementAt(a)).av.getSequenceSetId() )
768                 )
769             count ++;
770           }
771         }
772       }
773
774       return count;
775     }
776
777     public void explodeViews(AlignFrame af)
778     {
779       int size = af.alignPanels.size();
780       if(size<2)
781         return;
782
783       for(int i=0; i<size; i++)
784       {
785         AlignmentPanel ap = (AlignmentPanel)af.alignPanels.elementAt(i);
786         AlignFrame newaf = new AlignFrame(ap);
787         if(ap.av.explodedPosition!=null)
788           newaf.setBounds(ap.av.explodedPosition);
789
790         ap.av.gatherViewsHere = false;
791
792         addInternalFrame(newaf, af.getTitle(),
793                          AlignFrame.DEFAULT_WIDTH,
794                          AlignFrame.DEFAULT_HEIGHT);
795       }
796
797       af.alignPanels.clear();
798       af.closeMenuItem_actionPerformed(true);
799
800     }
801
802     public void gatherViews(AlignFrame source)
803     {
804       source.viewport.gatherViewsHere = true;
805       source.viewport.explodedPosition = source.getBounds();
806       JInternalFrame[] frames = desktop.getAllFrames();
807       String viewId = source.viewport.sequenceSetID;
808
809       for (int t = 0; t < frames.length; t++)
810       {
811         if (frames[t] instanceof AlignFrame && frames[t] != source)
812         {
813           AlignFrame af = (AlignFrame) frames[t];
814           boolean gatherThis = false;
815           for (int a = 0; a < af.alignPanels.size(); a++)
816           {
817             AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
818             if (viewId.equals(ap.av.getSequenceSetId()))
819             {
820               gatherThis = true;
821               ap.av.gatherViewsHere = false;
822               ap.av.explodedPosition = af.getBounds();
823               source.addAlignmentPanel(ap, false);
824             }
825           }
826
827           if (gatherThis)
828           {
829             af.alignPanels.clear();
830             af.closeMenuItem_actionPerformed(true);
831           }
832         }
833       }
834
835     }
836
837
838 }
839