copy order maintained
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /********************\r
2  * 2004 Jalview Reengineered\r
3  * Barton Group\r
4  * Dundee University\r
5  *\r
6  * AM Waterhouse\r
7  *******************/\r
8 \r
9 \r
10 \r
11 \r
12 package jalview.gui;\r
13 \r
14 import jalview.jbgui.GAlignFrame;\r
15 import jalview.schemes.*;\r
16 import jalview.datamodel.*;\r
17 import jalview.analysis.*;\r
18 import jalview.io.*;\r
19 import jalview.ws.*;\r
20 import java.awt.*;\r
21 import java.awt.event.*;\r
22 import java.awt.print.*;\r
23 import javax.swing.*;\r
24 import javax.swing.event.*;\r
25 import java.util.*;\r
26 import java.awt.datatransfer.*;\r
27 \r
28 \r
29 public class AlignFrame extends GAlignFrame\r
30 {\r
31   final AlignmentPanel alignPanel;\r
32   final AlignViewport viewport;\r
33   public static final int NEW_WINDOW_WIDTH = 700;\r
34   public static final int NEW_WINDOW_HEIGHT = 500;\r
35   public String currentFileFormat = "Jalview";\r
36 \r
37   public AlignFrame(AlignmentI al)\r
38   {\r
39     viewport = new AlignViewport(al);\r
40 \r
41     alignPanel = new AlignmentPanel(this, viewport);\r
42     alignPanel.annotationPanel.adjustPanelHeight();\r
43     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
44     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
45     alignPanel.setAnnotationVisible( viewport.getShowAnnotation() );\r
46 \r
47     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
48 \r
49     addInternalFrameListener(new InternalFrameAdapter()\r
50    {\r
51      public void internalFrameActivated(InternalFrameEvent evt)\r
52      {\r
53           javax.swing.SwingUtilities.invokeLater(new Runnable()\r
54           {\r
55             public void run()\r
56             {      alignPanel.requestFocus();    }\r
57           });\r
58 \r
59      }\r
60    });\r
61 \r
62   }\r
63 \r
64   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
65   {\r
66     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty("LAST_DIRECTORY")\r
67         ,  new String[]{"fa, fasta, fastq", "aln",  "pfam", "msf", "pir","blc","jar"},\r
68           new String[]{"Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"},\r
69           currentFileFormat);\r
70 \r
71     chooser.setAcceptAllFileFilterUsed(false);\r
72     chooser.setFileView(new JalviewFileView());\r
73     chooser.setDialogTitle("Save Alignment to file");\r
74     chooser.setToolTipText("Save");\r
75     int value = chooser.showSaveDialog(this);\r
76     if(value == JalviewFileChooser.APPROVE_OPTION)\r
77     {\r
78       currentFileFormat  = chooser.getSelectedFormat();\r
79 \r
80       if (currentFileFormat.equals("Jalview"))\r
81       {\r
82         String shortName = title.replace('/', '_');\r
83         title = title.replace('\\', '_');\r
84         String choice = chooser.getSelectedFile().getPath();\r
85         Jalview2XML.SaveState(this, System.currentTimeMillis(), shortName,\r
86                               choice);\r
87         // USE Jalview2XML to save this file\r
88         return;\r
89       }\r
90 \r
91       String choice =  chooser.getSelectedFile().getPath();\r
92       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
93       String output = FormatAdapter.formatSequences(currentFileFormat, viewport.getAlignment().getSequences());\r
94       try{\r
95         java.io.PrintWriter out = new java.io.PrintWriter( new java.io.FileWriter( choice )  );\r
96         out.println(output);\r
97         out.close();\r
98       }\r
99       catch(Exception ex){}\r
100     }\r
101 \r
102   }\r
103 \r
104   protected void outputText_actionPerformed(ActionEvent e)\r
105   {\r
106      CutAndPasteTransfer cap = new CutAndPasteTransfer(false);\r
107      JInternalFrame frame = new JInternalFrame();\r
108      cap.formatForOutput();\r
109      frame.setContentPane(cap);\r
110      Desktop.addInternalFrame(frame, "Alignment output - "+e.getActionCommand(), 600, 500);\r
111      cap.setText( FormatAdapter.formatSequences(e.getActionCommand(), viewport.getAlignment().getSequences()));\r
112   }\r
113 \r
114   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
115   {\r
116     HTMLOutput htmlOutput = new HTMLOutput(viewport);\r
117     htmlOutput = null;\r
118   }\r
119 \r
120   protected void createPNG_actionPerformed(ActionEvent e)\r
121   {\r
122     alignPanel.makePNG();\r
123   }\r
124 \r
125   protected void epsFile_actionPerformed(ActionEvent e)\r
126   {\r
127     alignPanel.makeEPS();\r
128   }\r
129 \r
130 \r
131   public void printMenuItem_actionPerformed(ActionEvent e)\r
132   {\r
133     //Putting in a thread avoids Swing painting problems\r
134     PrintThread thread = new PrintThread();\r
135     thread.start();\r
136   }\r
137 \r
138   class PrintThread extends Thread\r
139   {\r
140     public void run()\r
141     {\r
142       PrinterJob printJob = PrinterJob.getPrinterJob();\r
143       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
144       printJob.setPrintable(alignPanel, pf);\r
145       if (printJob.printDialog())\r
146       {\r
147         try\r
148         {\r
149           printJob.print();\r
150         }\r
151         catch (Exception PrintException)\r
152         {\r
153           PrintException.printStackTrace();\r
154         }\r
155       }\r
156     }\r
157 \r
158   }\r
159 \r
160 \r
161 \r
162 \r
163   public void closeMenuItem_actionPerformed(ActionEvent e)\r
164   {\r
165     try{\r
166       this.setClosed(true);\r
167     }catch(Exception ex){}\r
168   }\r
169 \r
170   Stack historyList = new Stack();\r
171   Stack redoList = new Stack();\r
172 \r
173   void updateEditMenuBar()\r
174   {\r
175     if(historyList.size()>0)\r
176      {\r
177        undoMenuItem.setEnabled(true);\r
178        Object [] history = (Object[])historyList.get(0);\r
179        undoMenuItem.setText("Undo "+history[0]);\r
180      }\r
181     else\r
182     {\r
183       undoMenuItem.setEnabled(false);\r
184       undoMenuItem.setText("Undo");\r
185     }\r
186 \r
187     if(redoList.size()>0)\r
188      {\r
189        redoMenuItem.setEnabled(true);\r
190        Object [] history = (Object[])redoList.get(0);\r
191        redoMenuItem.setText("Redo "+history[0]);\r
192      }\r
193     else\r
194     {\r
195       redoMenuItem.setEnabled(false);\r
196       redoMenuItem.setText("Redo");\r
197     }\r
198   }\r
199 \r
200   public void addHistoryItem(String type)\r
201   {\r
202     // must make sure we add new sequence objects her, not refs to the existing sequences\r
203     redoList.clear();\r
204 \r
205     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
206     for(int i=0; i<viewport.getAlignment().getHeight(); i++)\r
207     {\r
208       seq[i] = new Sequence( viewport.getAlignment().getSequenceAt(i).getName(),\r
209                              viewport.getAlignment().getSequenceAt(i).getSequence());\r
210     }\r
211 \r
212 \r
213     historyList.add(0, new Object[]{type,  seq} );\r
214     updateEditMenuBar();\r
215   }\r
216 \r
217   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
218   {\r
219     Object [] history = (Object[])historyList.remove(0);\r
220     // add the redo state before continuing!!\r
221     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
222     for (int i = 0; i < viewport.getAlignment().getHeight(); i++)\r
223     {\r
224       seq[i] = new Sequence(viewport.getAlignment().getSequenceAt(i).getName(),\r
225                             viewport.getAlignment().getSequenceAt(i).\r
226                             getSequence());\r
227     }\r
228     /////////\r
229 \r
230     redoList.add(0, new Object[] {history[0], seq});\r
231 \r
232       seq = (SequenceI[]) history[1];\r
233       AlignmentAnnotation [] old = viewport.alignment.getAlignmentAnnotation();\r
234       viewport.setAlignment( new Alignment(seq) );\r
235       viewport.alignment.setGapCharacter( Preferences.gapSymbol );\r
236       updateEditMenuBar();\r
237       for(int i=0; i<old.length; i++)\r
238         viewport.alignment.addAnnotation(old[i]);\r
239       viewport.updateConsensus();\r
240       viewport.updateConservation();\r
241       alignPanel.repaint();\r
242   }\r
243 \r
244   public void moveSelectedSequences(boolean up)\r
245   {\r
246     SequenceGroup sg = viewport.getSelectionGroup();\r
247     if (sg == null)\r
248       return;\r
249 \r
250     if (up)\r
251     {\r
252       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
253       {\r
254         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
255         if (!sg.sequences.contains(seq))\r
256           continue;\r
257 \r
258         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
259         if (sg.sequences.contains(temp))\r
260           continue;\r
261 \r
262         viewport.alignment.getSequences().setElementAt(temp, i);\r
263         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
264       }\r
265     }\r
266     else\r
267     {\r
268       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
269       {\r
270         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
271         if (!sg.sequences.contains(seq))\r
272           continue;\r
273 \r
274         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
275         if (sg.sequences.contains(temp))\r
276           continue;\r
277 \r
278         viewport.alignment.getSequences().setElementAt(temp, i);\r
279         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
280       }\r
281     }\r
282 \r
283     alignPanel.repaint();\r
284   }\r
285 \r
286 \r
287 \r
288   protected void copy_actionPerformed(ActionEvent e)\r
289   {\r
290      if(viewport.getSelectionGroup()==null)\r
291        return;\r
292 \r
293      SequenceGroup sg = viewport.getSelectionGroup();\r
294 \r
295      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
296      StringBuffer buffer= new StringBuffer();\r
297 \r
298      Hashtable orderedSeqs = new Hashtable();\r
299      for(int i=0; i<sg.getSize(); i++)\r
300      {\r
301         SequenceI seq = sg.getSequenceAt(i);\r
302         int index = viewport.alignment.findIndex(seq);\r
303         orderedSeqs.put(index+"", seq);\r
304      }\r
305 \r
306      int index=0;\r
307      for(int i=0; i<sg.getSize(); i++)\r
308      {\r
309        SequenceI seq = null;\r
310        while( seq == null )\r
311        {\r
312          if(orderedSeqs.containsKey(index+""))\r
313          {\r
314            seq = (SequenceI) orderedSeqs.get(index + "");\r
315            index++;\r
316            break;\r
317          }\r
318          else\r
319            index++;\r
320        }\r
321 \r
322          buffer.append( seq.getName()+"\t"+seq.findPosition( sg.getStartRes() ) +"\t"\r
323                         +seq.findPosition( sg.getEndRes() )+ "\t"\r
324                         +sg.getSequenceAt(i).getSequence(sg.getStartRes(), sg.getEndRes()+1)+"\n");\r
325      }\r
326      c.setContents( new StringSelection( buffer.toString()) , null ) ;\r
327 \r
328   }\r
329 \r
330 \r
331   protected void pasteNew_actionPerformed(ActionEvent e)\r
332   {\r
333     paste(true);\r
334   }\r
335 \r
336   protected void pasteThis_actionPerformed(ActionEvent e)\r
337   {\r
338     addHistoryItem("Paste");\r
339     paste(false);\r
340   }\r
341 \r
342   void paste(boolean newAlignment)\r
343   {\r
344     try{\r
345       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
346       Transferable contents = c.getContents(this);\r
347       if (contents == null)\r
348         return;\r
349 \r
350       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
351       StringTokenizer st = new StringTokenizer(str);\r
352       ArrayList seqs = new ArrayList();\r
353       while (st.hasMoreElements())\r
354       {\r
355         String name = st.nextToken();\r
356         int start = Integer.parseInt(st.nextToken());\r
357         int end = Integer.parseInt(st.nextToken());\r
358         Sequence sequence = new Sequence(name,st.nextToken(), start, end);\r
359 \r
360         if(!newAlignment)\r
361           viewport.alignment.addSequence(sequence);\r
362         else\r
363           seqs.add(sequence);\r
364       }\r
365 \r
366       if(newAlignment)\r
367       {\r
368         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
369         seqs.toArray(newSeqs);\r
370         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
371         String newtitle = new String("Copied sequences");\r
372         if( title.startsWith("Copied sequences"))\r
373          newtitle = title;\r
374        else\r
375          newtitle = newtitle.concat("- from "+title);\r
376 \r
377         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
378       }\r
379       else\r
380       {\r
381         viewport.setEndSeq(viewport.alignment.getHeight());\r
382         viewport.alignment.getWidth();\r
383         viewport.updateConservation();\r
384         viewport.updateConsensus();\r
385         alignPanel.repaint();\r
386       }\r
387 \r
388     }catch(Exception ex){}// could be anything being pasted in here\r
389 \r
390   }\r
391 \r
392 \r
393   protected void cut_actionPerformed(ActionEvent e)\r
394   {\r
395     copy_actionPerformed(null);\r
396     delete_actionPerformed(null);\r
397   }\r
398 \r
399   protected void delete_actionPerformed(ActionEvent e)\r
400   {\r
401     addHistoryItem("Delete");\r
402     if (viewport.getSelectionGroup() == null)\r
403       return;\r
404 \r
405      SequenceGroup sg = viewport.getSelectionGroup();\r
406      for (int i=0;i < sg.sequences.size(); i++)\r
407      {\r
408        SequenceI seq = sg.getSequenceAt(i);\r
409        int index = viewport.getAlignment().findIndex(seq);\r
410        seq.deleteChars(sg.getStartRes(), sg.getEndRes()+1);\r
411 \r
412        if(seq.getSequence().length()<1)\r
413           viewport.getAlignment().deleteSequence(seq);\r
414       else\r
415           viewport.getAlignment().getSequences().setElementAt(seq, index);\r
416      }\r
417 \r
418      viewport.setSelectionGroup(null);\r
419      viewport.alignment.deleteGroup(sg);\r
420      viewport.resetSeqLimits( alignPanel.seqPanel.seqCanvas.getHeight());\r
421      if(viewport.getAlignment().getHeight()<1)\r
422      try\r
423      {\r
424        this.setClosed(true);\r
425      }catch(Exception ex){}\r
426    viewport.updateConservation();\r
427    viewport.updateConsensus();\r
428      alignPanel.repaint();\r
429 \r
430   }\r
431 \r
432 \r
433 \r
434   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
435   {\r
436      Object [] history = (Object[])redoList.remove(0);\r
437      SequenceI[] seq = (SequenceI[]) history[1];\r
438      viewport.setAlignment( new Alignment(seq) );\r
439      viewport.alignment.setGapCharacter( Preferences.gapSymbol );\r
440      updateEditMenuBar();\r
441      viewport.updateConsensus();\r
442      alignPanel.repaint();\r
443      alignPanel.repaint();\r
444   }\r
445 \r
446 \r
447   protected void deleteGroups_actionPerformed(ActionEvent e)\r
448   {\r
449     viewport.alignment.deleteAllGroups();\r
450     viewport.setSelectionGroup(null);\r
451     alignPanel.repaint();\r
452   }\r
453 \r
454 \r
455 \r
456   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
457   {\r
458     SequenceGroup sg = new SequenceGroup();\r
459     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
460       sg.addSequence( viewport.getAlignment().getSequenceAt(i));\r
461     sg.setEndRes(viewport.alignment.getWidth());\r
462     viewport.setSelectionGroup(sg);\r
463     PaintRefresher.Refresh(null);\r
464   }\r
465 \r
466   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
467   {\r
468     viewport.setSelectionGroup(null);\r
469     viewport.getColumnSelection().clear();\r
470     viewport.setSelectionGroup(null);\r
471     PaintRefresher.Refresh(null);\r
472   }\r
473 \r
474   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
475   {\r
476     SequenceGroup sg = viewport.getSelectionGroup();\r
477     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
478       sg.addOrRemove (viewport.getAlignment().getSequenceAt(i));\r
479 \r
480     PaintRefresher.Refresh(null);\r
481   }\r
482 \r
483   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
484   {\r
485     addHistoryItem("delete columns");\r
486     ColumnSelection colSel = viewport.getColumnSelection();\r
487     if (colSel.size() > 0)\r
488     {\r
489       int min = colSel.getMin();\r
490       viewport.getAlignment().trimLeft(min);\r
491       colSel.compensateForEdit(0,min);\r
492 \r
493       if(viewport.getSelectionGroup()!=null)\r
494         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
495 \r
496       Vector groups = viewport.alignment.getGroups();\r
497       for(int i=0; i<groups.size(); i++)\r
498       {\r
499         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
500         if(!sg.adjustForRemoveLeft(min))\r
501           viewport.alignment.deleteGroup(sg);\r
502       }\r
503 \r
504       alignPanel.repaint();\r
505     }\r
506   }\r
507 \r
508   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
509   {\r
510     addHistoryItem("delete columns");\r
511     ColumnSelection colSel = viewport.getColumnSelection();\r
512     if (colSel.size() > 0)\r
513     {\r
514       int max = colSel.getMax();\r
515       viewport.getAlignment().trimRight(max);\r
516       if(viewport.getSelectionGroup()!=null)\r
517         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
518 \r
519       Vector groups = viewport.alignment.getGroups();\r
520       for(int i=0; i<groups.size(); i++)\r
521       {\r
522         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
523         if(!sg.adjustForRemoveRight(max))\r
524           viewport.alignment.deleteGroup(sg);\r
525       }\r
526 \r
527 \r
528 \r
529       alignPanel.repaint();\r
530     }\r
531 \r
532   }\r
533 \r
534   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
535   {\r
536     addHistoryItem("delete gapped columns");\r
537     viewport.getAlignment().removeGaps();\r
538     viewport.updateConservation();\r
539     viewport.updateConsensus();\r
540     alignPanel.repaint();\r
541   }\r
542 \r
543   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
544   {\r
545     addHistoryItem("delete all gaps");\r
546     SequenceI current;\r
547     int jSize;\r
548     for (int i=0; i < viewport.getAlignment().getSequences().size();i++)\r
549     {\r
550       current = viewport.getAlignment().getSequenceAt(i);\r
551       jSize = current.getLength();\r
552       for (int j=0; j < jSize; j++)\r
553         if(jalview.util.Comparison.isGap(current.getCharAt(j)))\r
554         {\r
555           current.deleteCharAt(j);\r
556           j--;\r
557           jSize--;\r
558         }\r
559     }\r
560     viewport.updateConservation();\r
561     viewport.updateConsensus();\r
562     alignPanel.repaint();\r
563   }\r
564 \r
565 \r
566   public void findMenuItem_actionPerformed(ActionEvent e)\r
567   {\r
568     JInternalFrame frame = new JInternalFrame();\r
569     Finder finder = new Finder(viewport, alignPanel, frame);\r
570     frame.setContentPane(finder);\r
571     Desktop.addInternalFrame(frame, "Find", 340,110);\r
572     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
573 \r
574   }\r
575 \r
576 \r
577   public void font_actionPerformed(ActionEvent e)\r
578   {\r
579     FontChooser fc = new FontChooser( alignPanel );\r
580   }\r
581 \r
582   protected void fullSeqId_actionPerformed(ActionEvent e)\r
583   {\r
584     viewport.setShowFullId( fullSeqId.isSelected() );\r
585 \r
586     alignPanel.idPanel.idCanvas.setPreferredSize( alignPanel.calculateIdWidth() );\r
587     alignPanel.repaint();\r
588   }\r
589 \r
590   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
591   {\r
592       viewport.setColourText( colourTextMenuItem.isSelected() );\r
593       alignPanel.repaint();\r
594   }\r
595 \r
596   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
597   {\r
598     viewport.setWrapAlignment( wrapMenuItem.isSelected() );\r
599     alignPanel.setWrapAlignment( wrapMenuItem.isSelected() );\r
600     scaleAbove.setVisible( wrapMenuItem.isSelected() );\r
601     scaleLeft.setVisible( wrapMenuItem.isSelected() );\r
602     scaleRight.setVisible( wrapMenuItem.isSelected() );\r
603     alignPanel.repaint();\r
604   }\r
605 \r
606   protected void scaleAbove_actionPerformed(ActionEvent e)\r
607   {\r
608     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
609     alignPanel.repaint();\r
610   }\r
611 \r
612   protected void scaleLeft_actionPerformed(ActionEvent e)\r
613   {\r
614     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
615     alignPanel.repaint();\r
616   }\r
617 \r
618   protected void scaleRight_actionPerformed(ActionEvent e)\r
619   {\r
620     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
621     alignPanel.repaint();\r
622   }\r
623 \r
624 \r
625 \r
626   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
627   {\r
628     viewport.setShowBoxes( viewBoxesMenuItem.isSelected() );\r
629     alignPanel.repaint();\r
630   }\r
631 \r
632   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
633   {\r
634     viewport.setShowText( viewTextMenuItem.isSelected() );\r
635     alignPanel.repaint();\r
636   }\r
637 \r
638 \r
639   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
640   {\r
641     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
642     alignPanel.repaint();\r
643   }\r
644 \r
645   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
646   {\r
647     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
648     if(viewport.showSequenceFeatures && !((Alignment)viewport.alignment).featuresAdded)\r
649     {\r
650          SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.alignment, alignPanel);\r
651          ((Alignment)viewport.alignment).featuresAdded = true;\r
652     }\r
653     alignPanel.repaint();\r
654   }\r
655 \r
656   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
657   {\r
658     if(annotationPanelMenuItem.isSelected() && viewport.getWrapAlignment())\r
659     {\r
660       annotationPanelMenuItem.setSelected(false);\r
661       return;\r
662     }\r
663     viewport.setShowAnnotation( annotationPanelMenuItem.isSelected() );\r
664     alignPanel.setAnnotationVisible( annotationPanelMenuItem.isSelected() );\r
665   }\r
666 \r
667   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
668   {\r
669     if (alignPanel.overviewPanel != null)\r
670       return;\r
671 \r
672     JInternalFrame frame = new JInternalFrame();\r
673     OverviewPanel overview = new OverviewPanel(alignPanel);\r
674      frame.setContentPane(overview);\r
675     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
676                              frame.getWidth(), frame.getHeight());\r
677     frame.pack();\r
678     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
679     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
680     { public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
681       {\r
682             alignPanel.setOverviewPanel(null);\r
683       };\r
684     });\r
685 \r
686     alignPanel.setOverviewPanel( overview );\r
687 \r
688 \r
689   }\r
690 \r
691   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
692   {\r
693     changeColour( null );\r
694   }\r
695 \r
696 \r
697   public void clustalColour_actionPerformed(ActionEvent e)\r
698   {\r
699     abovePIDThreshold.setSelected(false);\r
700     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
701   }\r
702 \r
703   public void zappoColour_actionPerformed(ActionEvent e)\r
704   {\r
705     changeColour(new ZappoColourScheme());\r
706   }\r
707 \r
708   public void taylorColour_actionPerformed(ActionEvent e)\r
709   {\r
710     changeColour(new TaylorColourScheme());\r
711   }\r
712 \r
713 \r
714   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
715   {\r
716     changeColour( new HydrophobicColourScheme() );\r
717   }\r
718 \r
719   public void helixColour_actionPerformed(ActionEvent e)\r
720   {\r
721     changeColour(new HelixColourScheme() );\r
722   }\r
723 \r
724 \r
725   public void strandColour_actionPerformed(ActionEvent e)\r
726   {\r
727     changeColour(new StrandColourScheme());\r
728   }\r
729 \r
730 \r
731   public void turnColour_actionPerformed(ActionEvent e)\r
732   {\r
733     changeColour(new TurnColourScheme());\r
734   }\r
735 \r
736 \r
737   public void buriedColour_actionPerformed(ActionEvent e)\r
738   {\r
739     changeColour(new BuriedColourScheme() );\r
740   }\r
741 \r
742   public void nucleotideColour_actionPerformed(ActionEvent e)\r
743   {\r
744     changeColour(new NucleotideColourScheme());\r
745   }\r
746 \r
747 \r
748   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
749   {\r
750     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
751   }\r
752 \r
753 \r
754 \r
755   void changeColour(ColourSchemeI cs)\r
756   {\r
757     int threshold = 0;\r
758 \r
759     if ( viewport.getAbovePIDThreshold() )\r
760     {\r
761       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
762 \r
763       if (cs instanceof ResidueColourScheme)\r
764         ( (ResidueColourScheme) cs).setThreshold(threshold);\r
765       else if (cs instanceof ScoreColourScheme)\r
766         ( (ScoreColourScheme) cs).setThreshold(threshold);\r
767 \r
768       viewport.setGlobalColourScheme(cs);\r
769     }\r
770     else if (cs instanceof ResidueColourScheme)\r
771       ( (ResidueColourScheme) cs).setThreshold(0);\r
772     else if (cs instanceof ScoreColourScheme)\r
773       ( (ScoreColourScheme) cs).setThreshold(0);\r
774 \r
775 \r
776 \r
777     if (viewport.getConservationSelected())\r
778     {\r
779       ConservationColourScheme ccs = null;\r
780 \r
781       Alignment al = (Alignment) viewport.alignment;\r
782       Conservation c = new Conservation("All",\r
783                                         ResidueProperties.propHash, 3,\r
784                                         al.getSequences(), 0,\r
785                                         al.getWidth() - 1);\r
786 \r
787       c.calculate();\r
788       c.verdict(false, viewport.ConsPercGaps);\r
789 \r
790       ccs = new ConservationColourScheme(c, cs);\r
791 \r
792       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
793       ccs.setConsensus( viewport.vconsensus );\r
794       viewport.setGlobalColourScheme(ccs);\r
795 \r
796       SliderPanel.setConservationSlider(alignPanel, ccs, "Background");\r
797 \r
798     }\r
799     else\r
800     {\r
801         // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
802         if (cs != null)\r
803           cs.setConsensus(viewport.vconsensus);\r
804         viewport.setGlobalColourScheme(cs);\r
805     }\r
806 \r
807 \r
808     if(viewport.getColourAppliesToAllGroups())\r
809     {\r
810       Vector groups = viewport.alignment.getGroups();\r
811       for(int i=0; i<groups.size(); i++)\r
812       {\r
813         SequenceGroup sg = (SequenceGroup)groups.elementAt(i);\r
814 \r
815         if (cs instanceof ClustalxColourScheme)\r
816         {\r
817           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
818         }\r
819         else if(cs!=null)\r
820         {\r
821           try{\r
822             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
823           }catch(Exception ex){ex.printStackTrace();}\r
824         }\r
825 \r
826         if(viewport.getAbovePIDThreshold())\r
827         {\r
828           if (sg.cs instanceof ResidueColourScheme)\r
829             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);\r
830           else if (sg.cs instanceof ScoreColourScheme)\r
831             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);\r
832 \r
833            sg.cs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()) );\r
834         }\r
835 \r
836         if( viewport.getConservationSelected() )\r
837         {\r
838           Conservation c = new Conservation("Group",\r
839                                             ResidueProperties.propHash, 3,\r
840                                             sg.sequences, 0, viewport.alignment.getWidth()-1);\r
841           c.calculate();\r
842           c.verdict(false, viewport.ConsPercGaps);\r
843           ConservationColourScheme ccs = new ConservationColourScheme(c, sg.cs);\r
844 \r
845           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
846           ccs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
847           sg.cs = ccs;\r
848         }\r
849         else if(cs!=null)\r
850         {\r
851           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
852           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
853         }\r
854 \r
855       }\r
856     }\r
857 \r
858     if(alignPanel.getOverviewPanel()!=null)\r
859       alignPanel.getOverviewPanel().updateOverviewImage();\r
860     alignPanel.repaint();\r
861   }\r
862 \r
863   protected void modifyPID_actionPerformed(ActionEvent e)\r
864   {\r
865       if(viewport.getAbovePIDThreshold())\r
866       {\r
867         SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
868                                    "Background");\r
869         SliderPanel.showPIDSlider();\r
870       }\r
871   }\r
872 \r
873   protected void modifyConservation_actionPerformed(ActionEvent e)\r
874   {\r
875     if(viewport.getConservationSelected())\r
876     {\r
877       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
878                                         "Background");\r
879       SliderPanel.showConservationSlider();\r
880     }\r
881   }\r
882 \r
883 \r
884   protected  void conservationMenuItem_actionPerformed(ActionEvent e)\r
885   {\r
886     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
887 \r
888     viewport.setAbovePIDThreshold(false);\r
889     abovePIDThreshold.setSelected(false);\r
890 \r
891    ColourSchemeI cs = viewport.getGlobalColourScheme();\r
892    if(cs instanceof ConservationColourScheme )\r
893      changeColour( ((ConservationColourScheme)cs).cs );\r
894     else\r
895       changeColour( cs );\r
896 \r
897     modifyConservation_actionPerformed(null);\r
898   }\r
899 \r
900   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
901   {\r
902     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
903 \r
904     conservationMenuItem.setSelected(false);\r
905     viewport.setConservationSelected(false);\r
906 \r
907     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
908 \r
909     if(cs instanceof ConservationColourScheme )\r
910         changeColour( ((ConservationColourScheme)cs).cs );\r
911     else\r
912         changeColour( cs );\r
913 \r
914     modifyPID_actionPerformed(null);\r
915   }\r
916 \r
917 \r
918 \r
919   public void userDefinedColour_actionPerformed(ActionEvent e)\r
920   {\r
921     UserDefinedColours chooser = new UserDefinedColours( alignPanel, null);\r
922   }\r
923 \r
924   public void PIDColour_actionPerformed(ActionEvent e)\r
925   {\r
926     changeColour( new PIDColourScheme() );\r
927   }\r
928 \r
929 \r
930   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
931   {\r
932     changeColour(new Blosum62ColourScheme() );\r
933   }\r
934 \r
935 \r
936 \r
937   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
938   {\r
939     addHistoryItem("sort");\r
940     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));\r
941     alignPanel.repaint();\r
942   }\r
943 \r
944   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
945   {\r
946     addHistoryItem("sort");\r
947     AlignmentSorter.sortByID( viewport.getAlignment() );\r
948     alignPanel.repaint();\r
949   }\r
950 \r
951   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
952   {\r
953     addHistoryItem("sort");\r
954     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
955     AlignmentSorter.sortGroups(viewport.getAlignment());\r
956     alignPanel.repaint();\r
957   }\r
958 \r
959   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
960   {\r
961     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
962     JInternalFrame frame = new JInternalFrame();\r
963     frame.setContentPane(sp);\r
964     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400, 100, false);\r
965 \r
966   }\r
967 \r
968   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
969   {\r
970     if(viewport.getSelectionGroup().getSize()<2)\r
971       JOptionPane.showInternalMessageDialog(this, "You must select at least 2 sequences.", "Invalid Selection", JOptionPane.WARNING_MESSAGE);\r
972     else\r
973     {\r
974       JInternalFrame frame = new JInternalFrame();\r
975       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
976       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
977     }\r
978   }\r
979 \r
980   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
981   {\r
982 \r
983     if( (viewport.getSelectionGroup()!=null && viewport.getSelectionGroup().getSize()<4 && viewport.getSelectionGroup().getSize()>0)\r
984        || viewport.getAlignment().getHeight()<4)\r
985     {\r
986       JOptionPane.showInternalMessageDialog(this, "Principal component analysis must take\n"\r
987                                     +"at least 4 input sequences.",\r
988                                     "Sequence selection insufficient",\r
989                                     JOptionPane.WARNING_MESSAGE);\r
990       return;\r
991     }\r
992 \r
993     try{\r
994       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
995       JInternalFrame frame = new JInternalFrame();\r
996       frame.setContentPane(pcaPanel);\r
997       Desktop.addInternalFrame(frame, "Principal component analysis", 400, 400);\r
998    }catch(java.lang.OutOfMemoryError ex)\r
999    {\r
1000      JOptionPane.showInternalMessageDialog(this, "Too many sequences selected\nfor Principal Component Analysis!!",\r
1001                                    "Out of memory", JOptionPane.WARNING_MESSAGE);\r
1002    }\r
1003 \r
1004 \r
1005   }\r
1006 \r
1007   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1008   {\r
1009     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1010   }\r
1011 \r
1012   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1013   {\r
1014     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1015   }\r
1016 \r
1017 \r
1018   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1019   {\r
1020     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1021   }\r
1022 \r
1023   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1024   {\r
1025     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1026   }\r
1027 \r
1028   void NewTreePanel(String type, String pwType, String title)\r
1029   {\r
1030     //are the sequences aligned?\r
1031     if(!viewport.alignment.isAligned())\r
1032     {\r
1033       JOptionPane.showMessageDialog(Desktop.desktop, "The sequences must be aligned before creating a tree.",\r
1034                                     "Sequences not aligned", JOptionPane.WARNING_MESSAGE);\r
1035       return;\r
1036     }\r
1037 \r
1038     final TreePanel tp;\r
1039     if (viewport.getSelectionGroup() != null &&\r
1040         viewport.getSelectionGroup().getSize() > 3)\r
1041     {\r
1042       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1043                          pwType,\r
1044                          0, viewport.alignment.getWidth());\r
1045     }\r
1046     else\r
1047     {\r
1048       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1049                          type, pwType, 0, viewport.alignment.getWidth());\r
1050     }\r
1051 \r
1052    addTreeMenuItem(tp, title);\r
1053 \r
1054    Desktop.addInternalFrame(tp, title, 600, 500);\r
1055   }\r
1056 \r
1057   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1058   {\r
1059     final JMenuItem item = new JMenuItem(title);\r
1060     sortByTreeMenu.add(item);\r
1061     item.addActionListener(new java.awt.event.ActionListener()\r
1062     {\r
1063       public void actionPerformed(ActionEvent e)\r
1064       {\r
1065         addHistoryItem("sort");\r
1066         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1067         alignPanel.repaint();\r
1068       }\r
1069     });\r
1070 \r
1071     treePanel.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1072     {\r
1073       public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
1074       {\r
1075         sortByTreeMenu.remove(item);\r
1076       };\r
1077     });\r
1078 \r
1079   }\r
1080 \r
1081 \r
1082   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)\r
1083   {\r
1084      WebserviceInfo info = new WebserviceInfo("Clustal web service",\r
1085      "\"Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple"+\r
1086      " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice."\r
1087     +" Nucleic Acids Research, submitted, June 1994.",\r
1088      450, 150);\r
1089 \r
1090     ClustalThread thread = new ClustalThread(info);\r
1091     thread.start();\r
1092   }\r
1093 \r
1094     class ClustalThread extends Thread\r
1095     {\r
1096       WebserviceInfo info;\r
1097       public ClustalThread(WebserviceInfo info)\r
1098       {this.info = info; }\r
1099 \r
1100       public void run()\r
1101       {\r
1102         info.setStatus(WebserviceInfo.STATE_RUNNING);\r
1103         jalview.ws.Jemboss jemboss = new jalview.ws.Jemboss();\r
1104         Vector sv = viewport.getAlignment().getSequences();\r
1105         SequenceI[] seqs = new SequenceI[sv.size()];\r
1106 \r
1107         int i = 0;\r
1108         do\r
1109         {\r
1110           seqs[i] = (SequenceI) sv.elementAt(i);\r
1111         }\r
1112         while (++i < sv.size());\r
1113 \r
1114         SequenceI[] alignment = jemboss.clustalW(seqs); // gaps removed within method\r
1115         if (alignment != null)\r
1116         {\r
1117           AlignFrame af = new AlignFrame(new Alignment(alignment));\r
1118           Desktop.addInternalFrame(af, title.concat(" - ClustalW Alignment"),\r
1119                                    NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
1120           af.clustalColour_actionPerformed(null);\r
1121           af.clustalColour.setSelected(true);\r
1122           info.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
1123         }\r
1124         else\r
1125         {\r
1126             info.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
1127             info.appendProgressText("Problem obtaining clustal alignment");\r
1128         }\r
1129       }\r
1130     }\r
1131 \r
1132   protected void jpred_actionPerformed(ActionEvent e)\r
1133 {\r
1134 \r
1135     if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>0)\r
1136     {\r
1137       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1138       SequenceGroup seqs = viewport.getSelectionGroup();\r
1139       if (seqs.getSize() == 1 || !viewport.alignment.isAligned())\r
1140       {\r
1141         JPredClient ct = new JPredClient( (SequenceI)seqs.getSequenceAt(0));\r
1142       }\r
1143       else\r
1144       {\r
1145         int sz;\r
1146         SequenceI[] msa = new SequenceI[sz=seqs.getSize()];\r
1147         for (int i = 0; i < sz; i++)\r
1148         {\r
1149           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1150         }\r
1151 \r
1152         JPredClient ct = new JPredClient(msa);\r
1153       }\r
1154 \r
1155     }\r
1156     else\r
1157     {\r
1158       Vector seqs = viewport.getAlignment().getSequences();\r
1159 \r
1160       if (seqs.size() == 1 || !viewport.alignment.isAligned())\r
1161       {\r
1162         JPredClient ct = new JPredClient( (SequenceI)\r
1163                                          seqs.elementAt(0));\r
1164       }\r
1165       else\r
1166       {\r
1167         SequenceI[] msa = new SequenceI[seqs.size()];\r
1168         for (int i = 0; i < seqs.size(); i++)\r
1169         {\r
1170           msa[i] = (SequenceI) seqs.elementAt(i);\r
1171         }\r
1172 \r
1173         JPredClient ct = new JPredClient(msa);\r
1174       }\r
1175 \r
1176     }\r
1177   }\r
1178   protected void msaAlignMenuItem_actionPerformed(ActionEvent e)\r
1179   {\r
1180     // TODO:resolve which menu item was actually selected\r
1181     // Now, check we have enough sequences\r
1182       if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>1)\r
1183       {\r
1184         // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1185         SequenceGroup seqs = viewport.getSelectionGroup();\r
1186         int sz;\r
1187         SequenceI[] msa = new SequenceI[sz=seqs.getSize()];\r
1188         for (int i = 0; i < sz; i++)\r
1189         {\r
1190           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1191         }\r
1192 \r
1193         MsaWSClient ct = new jalview.ws.MsaWSClient(msa);\r
1194       }\r
1195       else\r
1196       {\r
1197         Vector seqs = viewport.getAlignment().getSequences();\r
1198 \r
1199         if (seqs.size() > 1) {\r
1200           SequenceI[] msa = new SequenceI[seqs.size()];\r
1201           for (int i = 0; i < seqs.size(); i++)\r
1202           {\r
1203             msa[i] = (SequenceI) seqs.elementAt(i);\r
1204           }\r
1205 \r
1206           MsaWSClient ct = new MsaWSClient(msa);\r
1207         }\r
1208 \r
1209       }\r
1210     }\r
1211 \r
1212     protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) {\r
1213     // Pick the tree file\r
1214     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
1215         getProperty("LAST_DIRECTORY"));\r
1216     chooser.setFileView(new JalviewFileView());\r
1217     chooser.setDialogTitle("Select a newick-like tree file");\r
1218     chooser.setToolTipText("Load a tree file");\r
1219     int value = chooser.showOpenDialog(null);\r
1220     if (value == JalviewFileChooser.APPROVE_OPTION)\r
1221     {\r
1222       String choice = chooser.getSelectedFile().getPath();\r
1223       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
1224       try\r
1225       {\r
1226         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice, "File");\r
1227         ShowNewickTree(fin, choice);\r
1228       }\r
1229       catch (Exception ex)\r
1230       {\r
1231         JOptionPane.showMessageDialog(Desktop.desktop,\r
1232                                       "Problem reading tree file",\r
1233                                       ex.getMessage(),\r
1234                                       JOptionPane.WARNING_MESSAGE);\r
1235         ex.printStackTrace();\r
1236       }\r
1237     }\r
1238   }\r
1239 \r
1240   public void ShowNewickTree(NewickFile nf, String title)\r
1241   {\r
1242     try{\r
1243       nf.parse();\r
1244       if (nf.getTree() != null)\r
1245       {\r
1246         TreePanel tp = new TreePanel(viewport,\r
1247                                      viewport.getAlignment().getSequences(),\r
1248                                      nf, "FromFile", title);\r
1249         Desktop.addInternalFrame(tp, title, 600, 500);\r
1250         addTreeMenuItem(tp, title);\r
1251         viewport.setCurrentTree(tp.getTree());\r
1252       }\r
1253      }catch(Exception ex){ex.printStackTrace();}\r
1254   }\r
1255 \r
1256 \r
1257 }\r