2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Softwarechang
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 import java.awt.datatransfer.*;
27 import java.awt.dnd.*;
28 import java.awt.event.*;
29 import java.awt.print.*;
31 import javax.swing.event.MenuEvent;
33 import jalview.analysis.*;
34 import jalview.commands.*;
35 import jalview.datamodel.*;
37 import jalview.jbgui.*;
38 import jalview.schemes.*;
47 public class AlignFrame
48 extends GAlignFrame implements DropTargetListener
51 public static final int DEFAULT_WIDTH = 700;
54 public static final int DEFAULT_HEIGHT = 500;
55 public AlignmentPanel alignPanel;
57 AlignViewport viewport;
59 Vector alignPanels = new Vector();
63 * Last format used to load or save alignments in this window
65 String currentFileFormat = null;
67 * Current filename for this alignment
69 String fileName = null;
73 * Creates a new AlignFrame object.
75 * @param al DOCUMENT ME!
77 public AlignFrame(AlignmentI al, int width, int height)
79 this(al, null, width, height);
84 * new alignment window with hidden columns
85 * @param al AlignmentI
86 * @param hiddenColumns ColumnSelection or null
88 public AlignFrame(AlignmentI al, ColumnSelection hiddenColumns,
89 int width, int height)
91 this.setSize(width, height);
92 viewport = new AlignViewport(al, hiddenColumns);
94 alignPanel = new AlignmentPanel(this, viewport);
96 if(al.getDataset()==null)
101 addAlignmentPanel(alignPanel, true);
106 * Make a new AlignFrame from exisiting alignmentPanels
107 * @param ap AlignmentPanel
108 * @param av AlignViewport
110 public AlignFrame(AlignmentPanel ap)
114 addAlignmentPanel(ap, false);
120 if (viewport.conservation == null)
122 BLOSUM62Colour.setEnabled(false);
123 conservationMenuItem.setEnabled(false);
124 modifyConservation.setEnabled(false);
125 // PIDColour.setEnabled(false);
126 // abovePIDThreshold.setEnabled(false);
127 // modifyPID.setEnabled(false);
130 String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT", "No sort");
132 if (sortby.equals("Id"))
134 sortIDMenuItem_actionPerformed(null);
136 else if (sortby.equals("Pairwise Identity"))
138 sortPairwiseMenuItem_actionPerformed(null);
141 if (Desktop.desktop != null)
143 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
144 addServiceListeners();
145 setGUINucleotide(viewport.alignment.isNucleotide());
148 setMenusFromViewport(viewport);
149 buildSortByAnnotationScoresMenu();
150 if (viewport.wrapAlignment)
152 wrapMenuItem_actionPerformed(null);
155 if (jalview.bin.Cache.getDefault("SHOW_OVERVIEW",false))
157 this.overviewMenuItem_actionPerformed(null);
164 * Change the filename and format for the alignment, and
165 * enable the 'reload' button functionality.
166 * @param file valid filename
167 * @param format format of file
169 public void setFileName(String file, String format)
172 currentFileFormat = format;
173 reload.setEnabled(true);
176 void addKeyListener()
178 addKeyListener(new KeyAdapter()
180 public void keyPressed(KeyEvent evt)
182 if (viewport.cursorMode &&
183 ( (evt.getKeyCode() >= KeyEvent.VK_0 &&
184 evt.getKeyCode() <= KeyEvent.VK_9)
186 (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0 &&
187 evt.getKeyCode() <= KeyEvent.VK_NUMPAD9)
189 && Character.isDigit(evt.getKeyChar()))
190 alignPanel.seqPanel.numberPressed(evt.getKeyChar());
192 switch (evt.getKeyCode())
195 case 27: // escape key
196 deselectAllSequenceMenuItem_actionPerformed(null);
200 case KeyEvent.VK_DOWN:
201 if (evt.isAltDown() || !viewport.cursorMode)
202 moveSelectedSequences(false);
203 if (viewport.cursorMode)
204 alignPanel.seqPanel.moveCursor(0, 1);
208 if (evt.isAltDown() || !viewport.cursorMode)
209 moveSelectedSequences(true);
210 if (viewport.cursorMode)
211 alignPanel.seqPanel.moveCursor(0, -1);
215 case KeyEvent.VK_LEFT:
216 if (evt.isAltDown() || !viewport.cursorMode)
217 slideSequences(false,
218 alignPanel.seqPanel.getKeyboardNo1());
220 alignPanel.seqPanel.moveCursor( -1, 0);
225 case KeyEvent.VK_RIGHT:
226 if (evt.isAltDown() || !viewport.cursorMode)
228 alignPanel.seqPanel.getKeyboardNo1());
230 alignPanel.seqPanel.moveCursor(1, 0);
233 case KeyEvent.VK_SPACE:
234 if (viewport.cursorMode)
236 alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown()
242 case KeyEvent.VK_DELETE:
243 case KeyEvent.VK_BACK_SPACE:
244 if (!viewport.cursorMode)
246 cut_actionPerformed(null);
250 alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown()
258 if (viewport.cursorMode)
260 alignPanel.seqPanel.setCursorRow();
264 if (viewport.cursorMode && !evt.isControlDown())
266 alignPanel.seqPanel.setCursorColumn();
270 if (viewport.cursorMode)
272 alignPanel.seqPanel.setCursorPosition();
276 case KeyEvent.VK_ENTER:
277 case KeyEvent.VK_COMMA:
278 if (viewport.cursorMode)
280 alignPanel.seqPanel.setCursorRowAndColumn();
285 if (viewport.cursorMode)
287 alignPanel.seqPanel.setSelectionAreaAtCursor(true);
291 if (viewport.cursorMode)
293 alignPanel.seqPanel.setSelectionAreaAtCursor(false);
298 viewport.cursorMode = !viewport.cursorMode;
299 statusBar.setText("Keyboard editing mode is " +
300 (viewport.cursorMode ? "on" : "off"));
301 if (viewport.cursorMode)
303 alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
304 alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq;
306 alignPanel.seqPanel.seqCanvas.repaint();
312 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
313 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
314 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
316 javax.help.HelpBroker hb = hs.createHelpBroker();
317 hb.setCurrentID("home");
318 hb.setDisplayed(true);
322 ex.printStackTrace();
328 boolean toggleSeqs = !evt.isControlDown();
329 boolean toggleCols = !evt.isShiftDown();
331 boolean hide = false;
333 SequenceGroup sg = viewport.getSelectionGroup();
336 if (sg != null && sg.getSize() != viewport.alignment.getHeight())
338 hideSelSequences_actionPerformed(null);
341 else if (! (toggleCols &&
342 viewport.colSel.getSelected().size() > 0))
344 showAllSeqs_actionPerformed(null);
350 if (viewport.colSel.getSelected().size() > 0)
352 hideSelColumns_actionPerformed(null);
355 viewport.selectionGroup = sg;
360 showAllColumns_actionPerformed(null);
365 case KeyEvent.VK_PAGE_UP:
366 if (viewport.wrapAlignment)
368 alignPanel.scrollUp(true);
372 alignPanel.setScrollValues(viewport.startRes,
374 - viewport.endSeq + viewport.startSeq);
377 case KeyEvent.VK_PAGE_DOWN:
378 if (viewport.wrapAlignment)
380 alignPanel.scrollUp(false);
384 alignPanel.setScrollValues(viewport.startRes,
386 + viewport.endSeq - viewport.startSeq);
392 public void keyReleased(KeyEvent evt)
394 switch(evt.getKeyCode())
396 case KeyEvent.VK_LEFT:
397 if (evt.isAltDown() || !viewport.cursorMode)
398 viewport.firePropertyChange("alignment", null,
399 viewport.getAlignment().getSequences());
402 case KeyEvent.VK_RIGHT:
403 if (evt.isAltDown() || !viewport.cursorMode)
404 viewport.firePropertyChange("alignment", null,
405 viewport.getAlignment().getSequences());
413 public void addAlignmentPanel(final AlignmentPanel ap,
416 ap.alignFrame = this;
418 alignPanels.addElement(ap);
420 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
422 int aSize = alignPanels.size();
424 tabbedPane.setVisible(aSize>1 || ap.av.viewName!=null);
426 if (aSize == 1 && ap.av.viewName==null)
428 this.getContentPane().add(ap, BorderLayout.CENTER);
434 setInitialTabVisible();
437 expandViews.setEnabled(true);
438 gatherViews.setEnabled(true);
439 tabbedPane.addTab(ap.av.viewName, ap);
441 ap.setVisible(false);
448 ap.av.alignment.padGaps();
450 ap.av.updateConservation(ap);
451 ap.av.updateConsensus(ap);
455 public void setInitialTabVisible()
457 expandViews.setEnabled(true);
458 gatherViews.setEnabled(true);
459 tabbedPane.setVisible(true);
460 AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement();
461 tabbedPane.addTab(first.av.viewName,first);
462 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
466 public AlignViewport getViewport()
471 /* Set up intrinsic listeners for dynamically generated GUI bits. */
472 private void addServiceListeners()
474 final java.beans.PropertyChangeListener thisListener;
475 // Do this once to get current state
476 BuildWebServiceMenu();
477 Desktop.discoverer.addPropertyChangeListener(
478 thisListener = new java.beans.PropertyChangeListener()
480 public void propertyChange(PropertyChangeEvent evt)
482 // System.out.println("Discoverer property change.");
483 if (evt.getPropertyName().equals("services"))
485 // System.out.println("Rebuilding web service menu");
486 BuildWebServiceMenu();
491 addInternalFrameListener(new javax.swing.event.
492 InternalFrameAdapter()
494 public void internalFrameClosed(
495 javax.swing.event.InternalFrameEvent evt)
497 // System.out.println("deregistering discoverer listener");
498 Desktop.discoverer.removePropertyChangeListener(thisListener);
499 closeMenuItem_actionPerformed(true);
505 public void setGUINucleotide(boolean nucleotide)
507 showTranslation.setVisible( nucleotide );
508 conservationMenuItem.setEnabled( !nucleotide );
509 modifyConservation.setEnabled( !nucleotide );
511 //Remember AlignFrame always starts as protein
514 calculateMenu.remove(calculateMenu.getItemCount()-2);
516 setShowProductsEnabled();
522 * Need to call this method when tabs are selected for multiple views,
523 * or when loading from Jalview2XML.java
524 * @param av AlignViewport
526 void setMenusFromViewport(AlignViewport av)
528 padGapsMenuitem.setSelected(av.padGaps);
529 colourTextMenuItem.setSelected(av.showColourText);
530 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
531 conservationMenuItem.setSelected(av.getConservationSelected());
532 seqLimits.setSelected(av.getShowJVSuffix());
533 idRightAlign.setSelected(av.rightAlignIds);
534 renderGapsMenuItem.setSelected(av.renderGaps);
535 wrapMenuItem.setSelected(av.wrapAlignment);
536 scaleAbove.setVisible(av.wrapAlignment);
537 scaleLeft.setVisible(av.wrapAlignment);
538 scaleRight.setVisible(av.wrapAlignment);
539 annotationPanelMenuItem.setState(av.showAnnotation);
540 viewBoxesMenuItem.setSelected(av.showBoxes);
541 viewTextMenuItem.setSelected(av.showText);
543 setColourSelected(ColourSchemeProperty.
544 getColourName(av.getGlobalColourScheme()));
546 showSeqFeatures.setSelected(av.showSequenceFeatures);
547 hiddenMarkers.setState(av.showHiddenMarkers);
548 applyToAllGroups.setState(av.colourAppliesToAllGroups);
554 Hashtable progressBars;
555 public void setProgressBar(String message, long id)
557 if(progressBars == null)
559 progressBars = new Hashtable();
562 JPanel progressPanel;
563 GridLayout layout = (GridLayout) statusPanel.getLayout();
564 if(progressBars.get( new Long(id) )!=null)
566 progressPanel = (JPanel)progressBars.get( new Long(id) );
567 statusPanel.remove(progressPanel);
568 progressBars.remove( progressPanel );
569 progressPanel = null;
572 statusBar.setText(message);
575 layout.setRows(layout.getRows() - 1);
579 progressPanel = new JPanel(new BorderLayout(10, 5));
581 JProgressBar progressBar = new JProgressBar();
582 progressBar.setIndeterminate(true);
584 progressPanel.add(new JLabel(message), BorderLayout.WEST);
585 progressPanel.add(progressBar, BorderLayout.CENTER);
587 layout.setRows(layout.getRows() + 1);
588 statusPanel.add(progressPanel);
590 progressBars.put(new Long(id), progressPanel);
597 * @return true if any progress bars are still active
599 public boolean operationInProgress()
601 if (progressBars!=null && progressBars.size()>0)
608 Added so Castor Mapping file can obtain Jalview Version
610 public String getVersion()
612 return jalview.bin.Cache.getProperty("VERSION");
615 public FeatureRenderer getFeatureRenderer()
617 return alignPanel.seqPanel.seqCanvas.getFeatureRenderer();
621 public void fetchSequence_actionPerformed(ActionEvent e)
623 new SequenceFetcher(this);
626 public void addFromFile_actionPerformed(ActionEvent e)
628 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
631 public void reload_actionPerformed(ActionEvent e)
635 if(currentFileFormat.equals("Jalview"))
637 JInternalFrame [] frames = Desktop.desktop.getAllFrames();
638 for(int i=0; i<frames.length; i++)
640 if (frames[i] instanceof AlignFrame
642 && ( (AlignFrame) frames[i]).fileName.equals(fileName))
646 frames[i].setSelected(true);
647 Desktop.instance.closeAssociatedWindows();
649 catch (java.beans.PropertyVetoException ex)
654 Desktop.instance.closeAssociatedWindows();
656 FileLoader loader = new FileLoader();
657 String protocol = fileName.startsWith("http:")? "URL":"File";
658 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
662 Rectangle bounds = this.getBounds();
664 FileLoader loader = new FileLoader();
665 String protocol = fileName.startsWith("http:") ? "URL" : "File";
666 AlignFrame newframe =
667 loader.LoadFileWaitTillLoaded(fileName, protocol, currentFileFormat);
669 newframe.setBounds(bounds);
671 this.closeMenuItem_actionPerformed(true);
677 public void addFromText_actionPerformed(ActionEvent e)
679 Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport);
682 public void addFromURL_actionPerformed(ActionEvent e)
684 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
688 public void save_actionPerformed(ActionEvent e)
691 || currentFileFormat==null
692 || fileName.startsWith("http")
695 saveAs_actionPerformed(null);
699 saveAlignment(fileName, currentFileFormat);
706 * @param e DOCUMENT ME!
708 public void saveAs_actionPerformed(ActionEvent e)
710 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
711 getProperty( "LAST_DIRECTORY"),
712 jalview.io.AppletFormatAdapter.WRITABLE_EXTENSIONS,
713 jalview.io.AppletFormatAdapter.WRITABLE_FNAMES,
718 chooser.setFileView(new JalviewFileView());
719 chooser.setDialogTitle("Save Alignment to file");
720 chooser.setToolTipText("Save");
722 int value = chooser.showSaveDialog(this);
724 if (value == JalviewFileChooser.APPROVE_OPTION)
726 currentFileFormat = chooser.getSelectedFormat();
727 if (currentFileFormat == null)
729 JOptionPane.showInternalMessageDialog(Desktop.desktop,
730 "You must select a file format before saving!",
731 "File format not specified",
732 JOptionPane.WARNING_MESSAGE);
733 value = chooser.showSaveDialog(this);
737 fileName = chooser.getSelectedFile().getPath();
739 jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",
742 jalview.bin.Cache.setProperty("LAST_DIRECTORY", fileName);
743 if (currentFileFormat.indexOf(" ")>-1)
745 currentFileFormat = currentFileFormat.substring(0, currentFileFormat.indexOf(" "));
747 saveAlignment(fileName, currentFileFormat);
751 public boolean saveAlignment(String file, String format)
753 boolean success = true;
755 if (format.equalsIgnoreCase("Jalview"))
757 String shortName = title;
759 if (shortName.indexOf(java.io.File.separatorChar) > -1)
761 shortName = shortName.substring(shortName.lastIndexOf(
762 java.io.File.separatorChar) + 1);
765 success = new Jalview2XML().SaveAlignment(this, file, shortName);
767 statusBar.setText("Successfully saved to file: "
769 +format +" format.");
775 String[] omitHidden = null;
777 if (viewport.hasHiddenColumns)
779 int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
780 "The Alignment contains hidden columns."
781 + "\nDo you want to save only the visible alignment?",
782 "Save / Omit Hidden Columns",
783 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
785 if (reply == JOptionPane.YES_OPTION)
787 omitHidden = viewport.getViewAsString(false);
790 FormatAdapter f = new FormatAdapter();
792 String output = f.formatSequences(
794 (Alignment) viewport.alignment, // class cast exceptions will occur in the distant future
795 omitHidden, f.getCacheSuffixDefault(format), viewport.colSel);
805 java.io.PrintWriter out = new java.io.PrintWriter(
806 new java.io.FileWriter(file));
811 statusBar.setText("Successfully saved to file: "
813 + format + " format.");
818 ex.printStackTrace();
825 JOptionPane.showInternalMessageDialog(
826 this, "Couldn't save file: " + fileName,
828 JOptionPane.WARNING_MESSAGE);
837 * @param e DOCUMENT ME!
839 protected void outputText_actionPerformed(ActionEvent e)
841 String [] omitHidden = null;
843 if(viewport.hasHiddenColumns)
845 int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
846 "The Alignment contains hidden columns."
847 +"\nDo you want to output only the visible alignment?",
848 "Save / Omit Hidden Columns",
849 JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
851 if(reply==JOptionPane.YES_OPTION)
853 omitHidden = viewport.getViewAsString(false);
857 CutAndPasteTransfer cap = new CutAndPasteTransfer();
858 cap.setForInput(null);
859 Desktop.addInternalFrame(cap,
860 "Alignment output - " + e.getActionCommand(), 600,
864 cap.setText(new FormatAdapter().formatSequences(
865 e.getActionCommand(),
867 omitHidden, viewport.colSel));
873 * @param e DOCUMENT ME!
875 protected void htmlMenuItem_actionPerformed(ActionEvent e)
877 new HTMLOutput(alignPanel,
878 alignPanel.seqPanel.seqCanvas.getSequenceRenderer(),
879 alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
882 public void createImageMap(File file, String image)
884 alignPanel.makePNGImageMap(file, image);
890 * @param e DOCUMENT ME!
892 public void createPNG(File f)
894 alignPanel.makePNG(f);
900 * @param e DOCUMENT ME!
902 public void createEPS(File f)
904 alignPanel.makeEPS(f);
908 public void pageSetup_actionPerformed(ActionEvent e)
910 PrinterJob printJob = PrinterJob.getPrinterJob();
911 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
917 * @param e DOCUMENT ME!
919 public void printMenuItem_actionPerformed(ActionEvent e)
921 //Putting in a thread avoids Swing painting problems
922 PrintThread thread = new PrintThread(alignPanel);
926 public void exportFeatures_actionPerformed(ActionEvent e)
928 new AnnotationExporter().exportFeatures(alignPanel);
932 public void exportAnnotations_actionPerformed(ActionEvent e)
934 new AnnotationExporter().exportAnnotations(
936 viewport.showAnnotation ? viewport.alignment.getAlignmentAnnotation() : null,
937 viewport.alignment.getGroups(),
938 ((Alignment)viewport.alignment).alignmentProperties
943 public void associatedData_actionPerformed(ActionEvent e)
945 // Pick the tree file
946 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
949 chooser.setFileView(new JalviewFileView());
950 chooser.setDialogTitle("Load Jalview Annotations or Features File");
951 chooser.setToolTipText("Load Jalview Annotations / Features file");
953 int value = chooser.showOpenDialog(null);
955 if (value == JalviewFileChooser.APPROVE_OPTION)
957 String choice = chooser.getSelectedFile().getPath();
958 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
959 loadJalviewDataFile(choice);
968 * @param e DOCUMENT ME!
970 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
972 if(alignPanels!=null && alignPanels.size()<2)
979 if(alignPanels!=null)
983 for (int i = 0; i < alignPanels.size(); i++)
985 AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i);
986 jalview.structure.StructureSelectionManager.getStructureSelectionManager()
987 .removeStructureViewerListener(ap.seqPanel, null);
988 PaintRefresher.RemoveComponent(ap.seqPanel.seqCanvas);
989 PaintRefresher.RemoveComponent(ap.idPanel.idCanvas);
990 PaintRefresher.RemoveComponent(ap);
991 ap.av.alignment = null;
996 int index = tabbedPane.getSelectedIndex();
998 alignPanels.removeElement(alignPanel);
999 PaintRefresher.RemoveComponent(alignPanel.seqPanel.seqCanvas);
1000 PaintRefresher.RemoveComponent(alignPanel.idPanel.idCanvas);
1001 PaintRefresher.RemoveComponent(alignPanel);
1002 viewport.alignment = null;
1006 tabbedPane.removeTabAt(index);
1007 tabbedPane.validate();
1009 if(index==tabbedPane.getTabCount())
1014 this.tabSelectionChanged(index);
1020 this.setClosed(true);
1023 catch (Exception ex)
1025 ex.printStackTrace();
1033 void updateEditMenuBar()
1036 if (viewport.historyList.size() > 0)
1038 undoMenuItem.setEnabled(true);
1039 CommandI command = (CommandI) viewport.historyList.peek();
1040 undoMenuItem.setText("Undo " + command.getDescription());
1044 undoMenuItem.setEnabled(false);
1045 undoMenuItem.setText("Undo");
1048 if (viewport.redoList.size() > 0)
1050 redoMenuItem.setEnabled(true);
1052 CommandI command = (CommandI) viewport.redoList.peek();
1053 redoMenuItem.setText("Redo " + command.getDescription());
1057 redoMenuItem.setEnabled(false);
1058 redoMenuItem.setText("Redo");
1063 public void addHistoryItem(CommandI command)
1065 if(command.getSize()>0)
1067 viewport.historyList.push(command);
1068 viewport.redoList.clear();
1069 updateEditMenuBar();
1070 viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1076 * @return alignment objects for all views
1078 AlignmentI[] getViewAlignments()
1080 if (alignPanels!=null)
1082 Enumeration e = alignPanels.elements();
1083 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1084 for (int i=0; e.hasMoreElements(); i++)
1086 als[i] = ((AlignmentPanel) e.nextElement()).av.getAlignment();
1092 return new AlignmentI[] { viewport.alignment };
1099 * @param e DOCUMENT ME!
1101 protected void undoMenuItem_actionPerformed(ActionEvent e)
1103 if (viewport.historyList.empty())
1105 CommandI command = (CommandI)viewport.historyList.pop();
1106 viewport.redoList.push(command);
1107 command.undoCommand(getViewAlignments());
1109 AlignViewport originalSource = getOriginatingSource(command);
1110 updateEditMenuBar();
1112 if(originalSource!=null)
1114 originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1115 originalSource.firePropertyChange("alignment",
1117 originalSource.alignment.getSequences());
1124 * @param e DOCUMENT ME!
1126 protected void redoMenuItem_actionPerformed(ActionEvent e)
1128 if(viewport.redoList.size()<1)
1133 CommandI command = (CommandI) viewport.redoList.pop();
1134 viewport.historyList.push(command);
1135 command.doCommand(getViewAlignments());
1137 AlignViewport originalSource = getOriginatingSource(command);
1138 updateEditMenuBar();
1140 if(originalSource!=null)
1142 originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1143 originalSource.firePropertyChange("alignment",
1145 originalSource.alignment.getSequences());
1149 AlignViewport getOriginatingSource(CommandI command)
1151 AlignViewport originalSource = null;
1152 //For sequence removal and addition, we need to fire
1153 //the property change event FROM the viewport where the
1154 //original alignment was altered
1156 if (command instanceof EditCommand)
1158 EditCommand editCommand = (EditCommand) command;
1159 al = editCommand.getAlignment();
1160 Vector comps = (Vector) PaintRefresher.components
1161 .get(viewport.getSequenceSetId());
1163 for (int i = 0; i < comps.size(); i++)
1165 if (comps.elementAt(i) instanceof AlignmentPanel)
1167 if (al == ( (AlignmentPanel) comps.elementAt(i)).av.alignment)
1169 originalSource = ( (AlignmentPanel) comps.elementAt(i)).av;
1176 if (originalSource == null)
1178 //The original view is closed, we must validate
1179 //the current view against the closed view first
1182 PaintRefresher.validateSequences(al, viewport.alignment);
1185 originalSource = viewport;
1188 return originalSource;
1194 * @param up DOCUMENT ME!
1196 public void moveSelectedSequences(boolean up)
1198 SequenceGroup sg = viewport.getSelectionGroup();
1207 for (int i = 1; i < viewport.alignment.getHeight(); i++)
1209 SequenceI seq = viewport.alignment.getSequenceAt(i);
1211 if (!sg.getSequences(null).contains(seq))
1216 SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
1218 if (sg.getSequences(null).contains(temp))
1223 viewport.alignment.getSequences().setElementAt(temp, i);
1224 viewport.alignment.getSequences().setElementAt(seq, i - 1);
1229 for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
1231 SequenceI seq = viewport.alignment.getSequenceAt(i);
1233 if (!sg.getSequences(null).contains(seq))
1238 SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
1240 if (sg.getSequences(null).contains(temp))
1245 viewport.alignment.getSequences().setElementAt(temp, i);
1246 viewport.alignment.getSequences().setElementAt(seq, i + 1);
1250 alignPanel.paintAlignment(true);
1256 synchronized void slideSequences(boolean right, int size)
1258 Vector sg = new Vector();
1259 if(viewport.cursorMode)
1261 sg.addElement(viewport.alignment.getSequenceAt(
1262 alignPanel.seqPanel.seqCanvas.cursorY));
1264 else if(viewport.getSelectionGroup()!=null
1265 && viewport.getSelectionGroup().getSize()!=viewport.alignment.getHeight())
1267 sg = viewport.getSelectionGroup().getSequences(
1268 viewport.hiddenRepSequences);
1276 Vector invertGroup = new Vector();
1278 for (int i = 0; i < viewport.alignment.getHeight(); i++)
1280 if(!sg.contains(viewport.alignment.getSequenceAt(i)))
1281 invertGroup.add(viewport.alignment.getSequenceAt(i));
1284 SequenceI[] seqs1 = new SequenceI[sg.size()];
1285 for (int i = 0; i < sg.size(); i++)
1286 seqs1[i] = (SequenceI) sg.elementAt(i);
1288 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1289 for (int i = 0; i < invertGroup.size(); i++)
1290 seqs2[i] = (SequenceI) invertGroup.elementAt(i);
1292 SlideSequencesCommand ssc;
1294 ssc = new SlideSequencesCommand("Slide Sequences",
1296 viewport.getGapCharacter()
1299 ssc = new SlideSequencesCommand("Slide Sequences",
1301 viewport.getGapCharacter()
1304 int groupAdjustment = 0;
1305 if (ssc.getGapsInsertedBegin() && right)
1307 if (viewport.cursorMode)
1308 alignPanel.seqPanel.moveCursor(size, 0);
1310 groupAdjustment = size;
1312 else if (!ssc.getGapsInsertedBegin() && !right)
1314 if (viewport.cursorMode)
1315 alignPanel.seqPanel.moveCursor( -size, 0);
1317 groupAdjustment = -size;
1320 if (groupAdjustment != 0)
1322 viewport.getSelectionGroup().setStartRes(
1323 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1324 viewport.getSelectionGroup().setEndRes(
1325 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1329 boolean appendHistoryItem = false;
1330 if(viewport.historyList!=null
1331 && viewport.historyList.size()>0
1332 && viewport.historyList.peek() instanceof SlideSequencesCommand)
1334 appendHistoryItem = ssc.appendSlideCommand(
1335 (SlideSequencesCommand)viewport.historyList.peek())
1339 if(!appendHistoryItem)
1340 addHistoryItem(ssc);
1349 * @param e DOCUMENT ME!
1351 protected void copy_actionPerformed(ActionEvent e)
1354 if (viewport.getSelectionGroup() == null)
1358 // TODO: preserve the ordering of displayed alignment annotation in any internal paste (particularly sequence associated annotation)
1359 SequenceI [] seqs = viewport.getSelectionAsNewSequence();
1360 String[] omitHidden = null;
1362 if (viewport.hasHiddenColumns)
1364 omitHidden = viewport.getViewAsString(true);
1367 String output = new FormatAdapter().formatSequences(
1372 StringSelection ss = new StringSelection(output);
1376 jalview.gui.Desktop.internalCopy = true;
1377 //Its really worth setting the clipboard contents
1378 //to empty before setting the large StringSelection!!
1379 Toolkit.getDefaultToolkit().getSystemClipboard()
1380 .setContents(new StringSelection(""), null);
1382 Toolkit.getDefaultToolkit().getSystemClipboard()
1383 .setContents(ss, Desktop.instance);
1385 catch (OutOfMemoryError er)
1387 er.printStackTrace();
1388 javax.swing.SwingUtilities.invokeLater(new Runnable()
1392 javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
1393 "Out of memory copying region!!"
1395 "\nSee help files for increasing Java Virtual Machine memory."
1397 javax.swing.JOptionPane.WARNING_MESSAGE);
1404 Vector hiddenColumns = null;
1405 if(viewport.hasHiddenColumns)
1407 hiddenColumns =new Vector();
1408 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
1409 for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns().size();
1412 int[] region = (int[])
1413 viewport.getColumnSelection().getHiddenColumns().elementAt(i);
1415 hiddenColumns.addElement(new int[]
1416 {region[0] - hiddenOffset,
1417 region[1]-hiddenOffset});
1421 Desktop.jalviewClipboard = new Object[]
1424 viewport.alignment.getDataset(),
1426 statusBar.setText("Copied "+seqs.length+" sequences to clipboard.");
1432 * @param e DOCUMENT ME!
1434 protected void pasteNew_actionPerformed(ActionEvent e)
1442 * @param e DOCUMENT ME!
1444 protected void pasteThis_actionPerformed(ActionEvent e)
1452 * @param newAlignment DOCUMENT ME!
1454 void paste(boolean newAlignment)
1456 boolean externalPaste=true;
1459 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
1460 Transferable contents = c.getContents(this);
1462 if (contents == null)
1470 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
1471 if (str.length() < 1)
1476 format = new IdentifyFile().Identify(str, "Paste");
1479 catch (OutOfMemoryError er)
1481 er.printStackTrace();
1482 javax.swing.SwingUtilities.invokeLater(new Runnable()
1486 javax.swing.JOptionPane.showInternalMessageDialog(Desktop.desktop,
1487 "Out of memory pasting sequences!!"
1489 "\nSee help files for increasing Java Virtual Machine memory."
1491 javax.swing.JOptionPane.WARNING_MESSAGE);
1498 SequenceI[] sequences;
1499 boolean annotationAdded = false;
1500 AlignmentI alignment = null;
1502 if(Desktop.jalviewClipboard!=null)
1504 // The clipboard was filled from within Jalview, we must use the sequences
1505 // And dataset from the copied alignment
1506 SequenceI[] newseq = (SequenceI[])Desktop.jalviewClipboard[0];
1507 // be doubly sure that we create *new* sequence objects.
1508 sequences = new SequenceI[newseq.length];
1509 for (int i=0;i<newseq.length;i++) {
1510 sequences[i] = new Sequence(newseq[i]);
1512 alignment = new Alignment(sequences);
1513 externalPaste = false;
1517 // parse the clipboard as an alignment.
1518 alignment = new FormatAdapter().readFile(str, "Paste", format);
1519 sequences = alignment.getSequencesArray();
1527 if (Desktop.jalviewClipboard != null)
1529 // dataset is inherited
1530 alignment.setDataset( (Alignment) Desktop.jalviewClipboard[1]);
1534 // new dataset is constructed
1535 alignment.setDataset(null);
1537 alwidth = alignment.getWidth()+1;
1541 AlignmentI pastedal = alignment; // preserve pasted alignment object
1542 // Add pasted sequences and dataset into existing alignment.
1543 alignment = viewport.getAlignment();
1544 alwidth = alignment.getWidth()+1;
1545 // decide if we need to import sequences from an existing dataset
1546 boolean importDs = Desktop.jalviewClipboard != null
1547 && Desktop.jalviewClipboard[1] != alignment.getDataset();
1548 // importDs==true instructs us to copy over new dataset sequences from
1549 // an existing alignment
1550 Vector newDs = (importDs) ? new Vector() : null; // used to create
1551 // minimum dataset set
1553 for (int i = 0; i < sequences.length; i++)
1557 newDs.addElement(null);
1559 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
1561 if (importDs && ds != null)
1563 if (!newDs.contains(ds))
1565 newDs.setElementAt(ds, i);
1566 ds = new Sequence(ds);
1567 // update with new dataset sequence
1568 sequences[i].setDatasetSequence(ds);
1572 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
1577 // copy and derive new dataset sequence
1578 sequences[i] = sequences[i].deriveSequence();
1579 alignment.getDataset().addSequence(sequences[i].getDatasetSequence());
1580 // TODO: avoid creation of duplicate dataset sequences with a
1581 // 'contains' method using SequenceI.equals()/SequenceI.contains()
1583 alignment.addSequence(sequences[i]); // merges dataset
1587 newDs.clear(); // tidy up
1589 if (pastedal.getAlignmentAnnotation()!=null) {
1590 // Add any annotation attached to alignment.
1591 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
1592 for (int i=0; i<alann.length; i++)
1594 annotationAdded=true;
1595 if (alann[i].sequenceRef==null && !alann[i].autoCalculated) {
1596 AlignmentAnnotation newann = new AlignmentAnnotation(alann[i]);
1597 newann.padAnnotation(alwidth);
1598 alignment.addAnnotation(newann);
1603 if (!newAlignment) {
1607 addHistoryItem(new EditCommand(
1612 alignment.getWidth(),
1616 // Add any annotations attached to sequences
1617 for (int i = 0; i < sequences.length; i++)
1619 if (sequences[i].getAnnotation() != null)
1621 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
1623 annotationAdded=true;
1624 sequences[i].getAnnotation()[a].adjustForAlignment();
1625 sequences[i].getAnnotation()[a].padAnnotation(alwidth);
1626 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation was duplicated earlier
1627 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a], a);
1631 if (!newAlignment) {
1633 // propagate alignment changed.
1634 viewport.setEndSeq(alignment.getHeight());
1635 if (annotationAdded)
1637 // Duplicate sequence annotation in all views.
1638 AlignmentI[] alview = this.getViewAlignments();
1639 for (int i = 0; i < sequences.length; i++)
1641 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
1644 for (int avnum=0;avnum<alview.length; avnum++)
1646 if (alview[avnum]!=alignment)
1648 // duplicate in a view other than the one with input focus
1649 int avwidth = alview[avnum].getWidth()+1;
1650 // this relies on sann being preserved after we
1651 // modify the sequence's annotation array for each duplication
1652 for (int a=0; a<sann.length; a++)
1654 AlignmentAnnotation newann = new AlignmentAnnotation(sann[a]);
1655 sequences[i].addAlignmentAnnotation(newann);
1656 newann.padAnnotation(avwidth);
1657 alview[avnum].addAnnotation(newann); // annotation was duplicated earlier
1658 alview[avnum].setAnnotationIndex(newann, a);
1663 buildSortByAnnotationScoresMenu();
1665 viewport.firePropertyChange("alignment", null, alignment.getSequences());
1668 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH, DEFAULT_HEIGHT);
1669 String newtitle = new String("Copied sequences");
1671 if(Desktop.jalviewClipboard!=null && Desktop.jalviewClipboard[2]!=null)
1673 Vector hc = (Vector)Desktop.jalviewClipboard[2];
1674 for(int i=0; i<hc.size(); i++)
1676 int [] region = (int[]) hc.elementAt(i);
1677 af.viewport.hideColumns(region[0], region[1]);
1682 //>>>This is a fix for the moment, until a better solution is found!!<<<
1683 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().transferSettings(
1684 alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
1686 // TODO: maintain provenance of an alignment, rather than just make the title a concatenation of operations.
1687 if (!externalPaste) {
1688 if (title.startsWith("Copied sequences"))
1694 newtitle = newtitle.concat("- from " + title);
1697 newtitle = new String("Pasted sequences");
1700 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
1707 catch (Exception ex)
1709 ex.printStackTrace();
1710 System.out.println("Exception whilst pasting: "+ex);
1711 // could be anything being pasted in here
1720 * @param e DOCUMENT ME!
1722 protected void cut_actionPerformed(ActionEvent e)
1724 copy_actionPerformed(null);
1725 delete_actionPerformed(null);
1731 * @param e DOCUMENT ME!
1733 protected void delete_actionPerformed(ActionEvent evt)
1736 SequenceGroup sg = viewport.getSelectionGroup();
1742 Vector seqs = new Vector();
1744 for (int i = 0; i < sg.getSize(); i++)
1746 seq = sg.getSequenceAt(i);
1747 seqs.addElement(seq);
1751 // If the cut affects all sequences, remove highlighted columns
1752 if (sg.getSize() == viewport.alignment.getHeight())
1754 viewport.getColumnSelection().removeElements(sg.getStartRes(),
1755 sg.getEndRes() + 1);
1759 SequenceI [] cut = new SequenceI[seqs.size()];
1760 for(int i=0; i<seqs.size(); i++)
1762 cut[i] = (SequenceI)seqs.elementAt(i);
1769 addHistoryItem(new EditCommand("Cut Sequences",
1773 sg.getEndRes()-sg.getStartRes()+1,
1774 viewport.alignment));
1777 viewport.setSelectionGroup(null);
1778 viewport.alignment.deleteGroup(sg);
1780 viewport.firePropertyChange("alignment", null,
1781 viewport.getAlignment().getSequences());
1783 if (viewport.getAlignment().getHeight() < 1)
1787 this.setClosed(true);
1789 catch (Exception ex)
1798 * @param e DOCUMENT ME!
1800 protected void deleteGroups_actionPerformed(ActionEvent e)
1802 viewport.alignment.deleteAllGroups();
1803 viewport.sequenceColours = null;
1804 viewport.setSelectionGroup(null);
1805 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
1806 alignPanel.paintAlignment(true);
1812 * @param e DOCUMENT ME!
1814 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
1816 SequenceGroup sg = new SequenceGroup();
1818 for (int i = 0; i < viewport.getAlignment().getSequences().size();
1821 sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
1824 sg.setEndRes(viewport.alignment.getWidth() - 1);
1825 viewport.setSelectionGroup(sg);
1826 alignPanel.paintAlignment(true);
1827 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1833 * @param e DOCUMENT ME!
1835 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
1837 if(viewport.cursorMode)
1839 alignPanel.seqPanel.keyboardNo1 = null;
1840 alignPanel.seqPanel.keyboardNo2 = null;
1842 viewport.setSelectionGroup(null);
1843 viewport.getColumnSelection().clear();
1844 viewport.setSelectionGroup(null);
1845 alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
1846 alignPanel.idPanel.idCanvas.searchResults = null;
1847 alignPanel.paintAlignment(true);
1848 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1854 * @param e DOCUMENT ME!
1856 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
1858 SequenceGroup sg = viewport.getSelectionGroup();
1862 selectAllSequenceMenuItem_actionPerformed(null);
1867 for (int i = 0; i < viewport.getAlignment().getSequences().size();
1870 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
1873 alignPanel.paintAlignment(true);
1875 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1878 public void invertColSel_actionPerformed(ActionEvent e)
1880 viewport.invertColumnSelection();
1881 alignPanel.paintAlignment(true);
1888 * @param e DOCUMENT ME!
1890 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
1892 trimAlignment(true);
1898 * @param e DOCUMENT ME!
1900 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
1902 trimAlignment(false);
1905 void trimAlignment(boolean trimLeft)
1907 ColumnSelection colSel = viewport.getColumnSelection();
1910 if (colSel.size() > 0)
1914 column = colSel.getMin();
1918 column = colSel.getMax();
1922 if(viewport.getSelectionGroup()!=null)
1924 seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
1925 hiddenRepSequences);
1929 seqs = viewport.alignment.getSequencesArray();
1933 TrimRegionCommand trimRegion;
1936 trimRegion = new TrimRegionCommand("Remove Left",
1937 TrimRegionCommand.TRIM_LEFT,
1942 viewport.selectionGroup);
1943 viewport.setStartRes(0);
1947 trimRegion = new TrimRegionCommand("Remove Right",
1948 TrimRegionCommand.TRIM_RIGHT,
1953 viewport.selectionGroup);
1956 statusBar.setText("Removed "+trimRegion.getSize()+" columns.");
1959 addHistoryItem(trimRegion);
1961 Vector groups = viewport.alignment.getGroups();
1963 for (int i = 0; i < groups.size(); i++)
1965 SequenceGroup sg = (SequenceGroup) groups.get(i);
1967 if ( (trimLeft && !sg.adjustForRemoveLeft(column))
1968 || (!trimLeft && !sg.adjustForRemoveRight(column)))
1970 viewport.alignment.deleteGroup(sg);
1974 viewport.firePropertyChange("alignment", null,
1975 viewport.getAlignment().getSequences());
1982 * @param e DOCUMENT ME!
1984 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
1986 int start = 0, end = viewport.alignment.getWidth()-1;
1989 if (viewport.getSelectionGroup() != null)
1991 seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
1992 hiddenRepSequences);
1993 start = viewport.getSelectionGroup().getStartRes();
1994 end = viewport.getSelectionGroup().getEndRes();
1998 seqs = viewport.alignment.getSequencesArray();
2002 RemoveGapColCommand removeGapCols =
2003 new RemoveGapColCommand("Remove Gapped Columns",
2006 viewport.alignment);
2008 addHistoryItem(removeGapCols);
2010 statusBar.setText("Removed "+removeGapCols.getSize()+" empty columns.");
2012 //This is to maintain viewport position on first residue
2014 SequenceI seq = viewport.alignment.getSequenceAt(0);
2015 int startRes = seq.findPosition(viewport.startRes);
2016 // ShiftList shifts;
2017 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2018 // edit.alColumnChanges=shifts.getInverse();
2019 // if (viewport.hasHiddenColumns)
2020 // viewport.getColumnSelection().compensateForEdits(shifts);
2021 viewport.setStartRes(seq.findIndex(startRes)-1);
2022 viewport.firePropertyChange("alignment", null,
2023 viewport.getAlignment().getSequences());
2030 * @param e DOCUMENT ME!
2032 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2034 int start = 0, end = viewport.alignment.getWidth()-1;
2037 if (viewport.getSelectionGroup() != null)
2039 seqs = viewport.getSelectionGroup().getSequencesAsArray(viewport.
2040 hiddenRepSequences);
2041 start = viewport.getSelectionGroup().getStartRes();
2042 end = viewport.getSelectionGroup().getEndRes();
2046 seqs = viewport.alignment.getSequencesArray();
2049 //This is to maintain viewport position on first residue
2051 SequenceI seq = viewport.alignment.getSequenceAt(0);
2052 int startRes = seq.findPosition(viewport.startRes);
2054 addHistoryItem(new RemoveGapsCommand("Remove Gaps",
2057 viewport.alignment));
2059 viewport.setStartRes(seq.findIndex(startRes)-1);
2061 viewport.firePropertyChange("alignment", null,
2062 viewport.getAlignment().getSequences());
2069 * @param e DOCUMENT ME!
2071 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2073 viewport.padGaps = padGapsMenuitem.isSelected();
2075 viewport.firePropertyChange("alignment",
2077 viewport.getAlignment().getSequences());
2083 * @param e DOCUMENT ME!
2085 public void findMenuItem_actionPerformed(ActionEvent e)
2090 public void newView_actionPerformed(ActionEvent e)
2092 AlignmentPanel newap =
2093 new Jalview2XML().copyAlignPanel(alignPanel, true);
2095 newap.av.gatherViewsHere = false;
2097 if (viewport.viewName == null)
2099 viewport.viewName = "Original";
2102 newap.av.historyList = viewport.historyList;
2103 newap.av.redoList = viewport.redoList;
2105 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2106 String newViewName = "View " +index;
2108 Vector comps = (Vector) PaintRefresher.components.get(viewport.
2109 getSequenceSetId());
2110 Vector existingNames = new Vector();
2111 for(int i=0; i<comps.size(); i++)
2113 if(comps.elementAt(i) instanceof AlignmentPanel)
2115 AlignmentPanel ap = (AlignmentPanel)comps.elementAt(i);
2116 if(!existingNames.contains(ap.av.viewName))
2118 existingNames.addElement(ap.av.viewName);
2123 while(existingNames.contains(newViewName))
2125 newViewName = "View "+ (++index);
2128 newap.av.viewName = newViewName;
2130 addAlignmentPanel(newap, false);
2132 if(alignPanels.size()==2)
2134 viewport.gatherViewsHere = true;
2136 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2139 public void expandViews_actionPerformed(ActionEvent e)
2141 Desktop.instance.explodeViews(this);
2144 public void gatherViews_actionPerformed(ActionEvent e)
2146 Desktop.instance.gatherViews(this);
2154 * @param e DOCUMENT ME!
2156 public void font_actionPerformed(ActionEvent e)
2158 new FontChooser(alignPanel);
2165 * @param e DOCUMENT ME!
2167 protected void seqLimit_actionPerformed(ActionEvent e)
2169 viewport.setShowJVSuffix(seqLimits.isSelected());
2171 alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());
2172 alignPanel.paintAlignment(true);
2175 public void idRightAlign_actionPerformed(ActionEvent e)
2177 viewport.rightAlignIds = idRightAlign.isSelected();
2178 alignPanel.paintAlignment(true);
2186 * @param e DOCUMENT ME!
2188 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
2190 viewport.setColourText(colourTextMenuItem.isSelected());
2191 alignPanel.paintAlignment(true);
2197 * @param e DOCUMENT ME!
2199 public void wrapMenuItem_actionPerformed(ActionEvent e)
2201 scaleAbove.setVisible(wrapMenuItem.isSelected());
2202 scaleLeft.setVisible(wrapMenuItem.isSelected());
2203 scaleRight.setVisible(wrapMenuItem.isSelected());
2204 viewport.setWrapAlignment(wrapMenuItem.isSelected());
2205 alignPanel.setWrapAlignment(wrapMenuItem.isSelected());
2208 public void showAllSeqs_actionPerformed(ActionEvent e)
2210 viewport.showAllHiddenSeqs();
2213 public void showAllColumns_actionPerformed(ActionEvent e)
2215 viewport.showAllHiddenColumns();
2219 public void hideSelSequences_actionPerformed(ActionEvent e)
2221 viewport.hideAllSelectedSeqs();
2222 alignPanel.paintAlignment(true);
2225 public void hideSelColumns_actionPerformed(ActionEvent e)
2227 viewport.hideSelectedColumns();
2228 alignPanel.paintAlignment(true);
2231 public void hiddenMarkers_actionPerformed(ActionEvent e)
2233 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
2240 * @param e DOCUMENT ME!
2242 protected void scaleAbove_actionPerformed(ActionEvent e)
2244 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
2245 alignPanel.paintAlignment(true);
2251 * @param e DOCUMENT ME!
2253 protected void scaleLeft_actionPerformed(ActionEvent e)
2255 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
2256 alignPanel.paintAlignment(true);
2262 * @param e DOCUMENT ME!
2264 protected void scaleRight_actionPerformed(ActionEvent e)
2266 viewport.setScaleRightWrapped(scaleRight.isSelected());
2267 alignPanel.paintAlignment(true);
2273 * @param e DOCUMENT ME!
2275 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
2277 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
2278 alignPanel.paintAlignment(true);
2284 * @param e DOCUMENT ME!
2286 public void viewTextMenuItem_actionPerformed(ActionEvent e)
2288 viewport.setShowText(viewTextMenuItem.isSelected());
2289 alignPanel.paintAlignment(true);
2295 * @param e DOCUMENT ME!
2297 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
2299 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
2300 alignPanel.paintAlignment(true);
2304 public FeatureSettings featureSettings;
2305 public void featureSettings_actionPerformed(ActionEvent e)
2307 if(featureSettings !=null )
2309 featureSettings.close();
2310 featureSettings = null;
2312 featureSettings = new FeatureSettings(this);
2318 * @param evt DOCUMENT ME!
2320 public void showSeqFeatures_actionPerformed(ActionEvent evt)
2322 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
2323 alignPanel.paintAlignment(true);
2324 if (alignPanel.getOverviewPanel() != null)
2326 alignPanel.getOverviewPanel().updateOverviewImage();
2333 * @param e DOCUMENT ME!
2335 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
2337 viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());
2338 alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());
2341 public void alignmentProperties()
2343 JEditorPane editPane = new JEditorPane("text/html","");
2344 editPane.setEditable(false);
2345 StringBuffer contents = new StringBuffer("<html>");
2348 int min=Integer.MAX_VALUE, max=0;
2349 for(int i=0; i<viewport.alignment.getHeight(); i++)
2351 int size = viewport.alignment.getSequenceAt(i).getEnd()
2352 -viewport.alignment.getSequenceAt(i).getStart();
2359 avg = avg/(float)viewport.alignment.getHeight();
2361 contents.append("<br>Sequences: "+ viewport.alignment.getHeight());
2362 contents.append("<br>Minimum Sequence Length: "+min);
2363 contents.append("<br>Maximum Sequence Length: "+max);
2364 contents.append("<br>Average Length: "+(int)avg);
2366 if (((Alignment)viewport.alignment).getProperties() != null)
2368 Hashtable props = ((Alignment)viewport.alignment).getProperties();
2369 Enumeration en = props.keys();
2370 contents.append("<br><br><table border=\"1\">");
2371 while(en.hasMoreElements())
2373 String key = en.nextElement().toString();
2374 StringBuffer val = new StringBuffer();
2375 String vals = props.get(key).toString();
2378 npos = vals.indexOf("\n",pos);
2381 val.append(vals.substring(pos));
2383 val.append(vals.substring(pos, npos));
2388 contents.append("<tr><td>"+key+"</td><td>"+val+"</td></tr>");
2390 contents.append("</table>");
2392 editPane.setText(contents.toString()+"</html>");
2393 JInternalFrame frame = new JInternalFrame();
2394 frame.getContentPane().add(new JScrollPane(editPane));
2396 Desktop.instance.addInternalFrame(frame,"Alignment Properties: "+getTitle(),500,400);
2403 * @param e DOCUMENT ME!
2405 public void overviewMenuItem_actionPerformed(ActionEvent e)
2407 if (alignPanel.overviewPanel != null)
2412 JInternalFrame frame = new JInternalFrame();
2413 OverviewPanel overview = new OverviewPanel(alignPanel);
2414 frame.setContentPane(overview);
2415 Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),
2416 frame.getWidth(), frame.getHeight());
2418 frame.setLayer(JLayeredPane.PALETTE_LAYER);
2419 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
2421 public void internalFrameClosed(
2422 javax.swing.event.InternalFrameEvent evt)
2424 alignPanel.setOverviewPanel(null);
2429 alignPanel.setOverviewPanel(overview);
2432 public void textColour_actionPerformed(ActionEvent e)
2434 new TextColourChooser().chooseColour(alignPanel, null);
2440 * @param e DOCUMENT ME!
2442 protected void noColourmenuItem_actionPerformed(ActionEvent e)
2450 * @param e DOCUMENT ME!
2452 public void clustalColour_actionPerformed(ActionEvent e)
2454 changeColour(new ClustalxColourScheme(
2455 viewport.alignment.getSequences(), viewport.alignment.getWidth()));
2461 * @param e DOCUMENT ME!
2463 public void zappoColour_actionPerformed(ActionEvent e)
2465 changeColour(new ZappoColourScheme());
2471 * @param e DOCUMENT ME!
2473 public void taylorColour_actionPerformed(ActionEvent e)
2475 changeColour(new TaylorColourScheme());
2481 * @param e DOCUMENT ME!
2483 public void hydrophobicityColour_actionPerformed(ActionEvent e)
2485 changeColour(new HydrophobicColourScheme());
2491 * @param e DOCUMENT ME!
2493 public void helixColour_actionPerformed(ActionEvent e)
2495 changeColour(new HelixColourScheme());
2501 * @param e DOCUMENT ME!
2503 public void strandColour_actionPerformed(ActionEvent e)
2505 changeColour(new StrandColourScheme());
2511 * @param e DOCUMENT ME!
2513 public void turnColour_actionPerformed(ActionEvent e)
2515 changeColour(new TurnColourScheme());
2521 * @param e DOCUMENT ME!
2523 public void buriedColour_actionPerformed(ActionEvent e)
2525 changeColour(new BuriedColourScheme());
2531 * @param e DOCUMENT ME!
2533 public void nucleotideColour_actionPerformed(ActionEvent e)
2535 changeColour(new NucleotideColourScheme());
2538 public void annotationColour_actionPerformed(ActionEvent e)
2540 new AnnotationColourChooser(viewport, alignPanel);
2547 * @param e DOCUMENT ME!
2549 protected void applyToAllGroups_actionPerformed(ActionEvent e)
2551 viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());
2557 * @param cs DOCUMENT ME!
2559 public void changeColour(ColourSchemeI cs)
2565 if (viewport.getAbovePIDThreshold())
2567 threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
2570 cs.setThreshold(threshold,
2571 viewport.getIgnoreGapsConsensus());
2573 viewport.setGlobalColourScheme(cs);
2577 cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2580 if (viewport.getConservationSelected())
2583 Alignment al = (Alignment) viewport.alignment;
2584 Conservation c = new Conservation("All",
2585 ResidueProperties.propHash, 3,
2586 al.getSequences(), 0,
2590 c.verdict(false, viewport.ConsPercGaps);
2592 cs.setConservation(c);
2594 cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,
2599 cs.setConservation(null);
2602 cs.setConsensus(viewport.hconsensus);
2605 viewport.setGlobalColourScheme(cs);
2607 if (viewport.getColourAppliesToAllGroups())
2609 Vector groups = viewport.alignment.getGroups();
2611 for (int i = 0; i < groups.size(); i++)
2613 SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
2621 if (cs instanceof ClustalxColourScheme)
2623 sg.cs = new ClustalxColourScheme(
2624 sg.getSequences(viewport.hiddenRepSequences), sg.getWidth());
2626 else if (cs instanceof UserColourScheme)
2628 sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());
2634 sg.cs = (ColourSchemeI) cs.getClass().newInstance();
2636 catch (Exception ex)
2641 if (viewport.getAbovePIDThreshold()
2642 || cs instanceof PIDColourScheme
2643 || cs instanceof Blosum62ColourScheme)
2645 sg.cs.setThreshold(threshold,
2646 viewport.getIgnoreGapsConsensus());
2648 sg.cs.setConsensus(AAFrequency.calculate(
2649 sg.getSequences(viewport.hiddenRepSequences), sg.getStartRes(),
2654 sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2658 if (viewport.getConservationSelected())
2660 Conservation c = new Conservation("Group",
2661 ResidueProperties.propHash, 3,
2662 sg.getSequences(viewport.
2663 hiddenRepSequences),
2667 c.verdict(false, viewport.ConsPercGaps);
2668 sg.cs.setConservation(c);
2672 sg.cs.setConservation(null);
2677 if (alignPanel.getOverviewPanel() != null)
2679 alignPanel.getOverviewPanel().updateOverviewImage();
2685 alignPanel.paintAlignment(true);
2691 * @param e DOCUMENT ME!
2693 protected void modifyPID_actionPerformed(ActionEvent e)
2695 if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)
2697 SliderPanel.setPIDSliderSource(alignPanel,
2698 viewport.getGlobalColourScheme(),
2700 SliderPanel.showPIDSlider();
2707 * @param e DOCUMENT ME!
2709 protected void modifyConservation_actionPerformed(ActionEvent e)
2711 if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)
2713 SliderPanel.setConservationSlider(alignPanel,
2714 viewport.globalColourScheme,
2716 SliderPanel.showConservationSlider();
2723 * @param e DOCUMENT ME!
2725 protected void conservationMenuItem_actionPerformed(ActionEvent e)
2727 viewport.setConservationSelected(conservationMenuItem.isSelected());
2729 viewport.setAbovePIDThreshold(false);
2730 abovePIDThreshold.setSelected(false);
2732 changeColour(viewport.getGlobalColourScheme());
2734 modifyConservation_actionPerformed(null);
2740 * @param e DOCUMENT ME!
2742 public void abovePIDThreshold_actionPerformed(ActionEvent e)
2744 viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());
2746 conservationMenuItem.setSelected(false);
2747 viewport.setConservationSelected(false);
2749 changeColour(viewport.getGlobalColourScheme());
2751 modifyPID_actionPerformed(null);
2757 * @param e DOCUMENT ME!
2759 public void userDefinedColour_actionPerformed(ActionEvent e)
2761 if (e.getActionCommand().equals("User Defined..."))
2763 new UserDefinedColours(alignPanel, null);
2767 UserColourScheme udc = (UserColourScheme) UserDefinedColours.
2768 getUserColourSchemes().get(e.getActionCommand());
2774 public void updateUserColourMenu()
2777 Component[] menuItems = colourMenu.getMenuComponents();
2778 int i, iSize = menuItems.length;
2779 for (i = 0; i < iSize; i++)
2781 if (menuItems[i].getName() != null &&
2782 menuItems[i].getName().equals("USER_DEFINED"))
2784 colourMenu.remove(menuItems[i]);
2788 if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
2790 java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
2791 getUserColourSchemes().keys();
2793 while (userColours.hasMoreElements())
2795 final JRadioButtonMenuItem radioItem = new JRadioButtonMenuItem(
2797 nextElement().toString());
2798 radioItem.setName("USER_DEFINED");
2799 radioItem.addMouseListener(new MouseAdapter()
2801 public void mousePressed(MouseEvent evt)
2803 if(evt.isControlDown() || SwingUtilities.isRightMouseButton(evt))
2805 radioItem.removeActionListener(radioItem.getActionListeners()[0]);
2807 int option = JOptionPane.showInternalConfirmDialog(jalview.gui.
2809 "Remove from default list?",
2810 "Remove user defined colour",
2811 JOptionPane.YES_NO_OPTION);
2812 if(option == JOptionPane.YES_OPTION)
2814 jalview.gui.UserDefinedColours.removeColourFromDefaults(
2815 radioItem.getText());
2816 colourMenu.remove(radioItem);
2820 radioItem.addActionListener(new ActionListener()
2822 public void actionPerformed(ActionEvent evt)
2824 userDefinedColour_actionPerformed(evt);
2831 radioItem.addActionListener(new ActionListener()
2833 public void actionPerformed(ActionEvent evt)
2835 userDefinedColour_actionPerformed(evt);
2839 colourMenu.insert(radioItem, 15);
2840 colours.add(radioItem);
2848 * @param e DOCUMENT ME!
2850 public void PIDColour_actionPerformed(ActionEvent e)
2852 changeColour(new PIDColourScheme());
2858 * @param e DOCUMENT ME!
2860 public void BLOSUM62Colour_actionPerformed(ActionEvent e)
2862 changeColour(new Blosum62ColourScheme());
2868 * @param e DOCUMENT ME!
2870 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
2872 SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2873 AlignmentSorter.sortByPID(viewport.getAlignment(),
2874 viewport.getAlignment().getSequenceAt(0), null);
2875 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
2876 viewport.alignment));
2877 alignPanel.paintAlignment(true);
2883 * @param e DOCUMENT ME!
2885 public void sortIDMenuItem_actionPerformed(ActionEvent e)
2887 SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2888 AlignmentSorter.sortByID(viewport.getAlignment());
2889 addHistoryItem(new OrderCommand("ID Sort", oldOrder, viewport.alignment));
2890 alignPanel.paintAlignment(true);
2896 * @param e DOCUMENT ME!
2898 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
2900 SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
2901 AlignmentSorter.sortByGroup(viewport.getAlignment());
2902 addHistoryItem(new OrderCommand("Group Sort", oldOrder, viewport.alignment));
2904 alignPanel.paintAlignment(true);
2909 * @param e DOCUMENT ME!
2911 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
2913 new RedundancyPanel(alignPanel, this);
2920 * @param e DOCUMENT ME!
2922 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
2924 if ( (viewport.getSelectionGroup() == null) ||
2925 (viewport.getSelectionGroup().getSize() < 2))
2927 JOptionPane.showInternalMessageDialog(this,
2928 "You must select at least 2 sequences.",
2929 "Invalid Selection",
2930 JOptionPane.WARNING_MESSAGE);
2934 JInternalFrame frame = new JInternalFrame();
2935 frame.setContentPane(new PairwiseAlignPanel(viewport));
2936 Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);
2943 * @param e DOCUMENT ME!
2945 public void PCAMenuItem_actionPerformed(ActionEvent e)
2947 if ( ( (viewport.getSelectionGroup() != null) &&
2948 (viewport.getSelectionGroup().getSize() < 4) &&
2949 (viewport.getSelectionGroup().getSize() > 0)) ||
2950 (viewport.getAlignment().getHeight() < 4))
2952 JOptionPane.showInternalMessageDialog(this,
2953 "Principal component analysis must take\n" +
2954 "at least 4 input sequences.",
2955 "Sequence selection insufficient",
2956 JOptionPane.WARNING_MESSAGE);
2961 new PCAPanel(alignPanel);
2965 public void autoCalculate_actionPerformed(ActionEvent e)
2967 viewport.autoCalculateConsensus = autoCalculate.isSelected();
2968 if(viewport.autoCalculateConsensus)
2970 viewport.firePropertyChange("alignment",
2972 viewport.getAlignment().getSequences());
2980 * @param e DOCUMENT ME!
2982 public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)
2984 NewTreePanel("AV", "PID", "Average distance tree using PID");
2990 * @param e DOCUMENT ME!
2992 public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)
2994 NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
3000 * @param e DOCUMENT ME!
3002 protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)
3004 NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
3010 * @param e DOCUMENT ME!
3012 protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)
3014 NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
3020 * @param type DOCUMENT ME!
3021 * @param pwType DOCUMENT ME!
3022 * @param title DOCUMENT ME!
3024 void NewTreePanel(String type, String pwType, String title)
3028 if (viewport.getSelectionGroup() != null)
3030 if (viewport.getSelectionGroup().getSize() < 3)
3032 JOptionPane.showMessageDialog(Desktop.desktop,
3033 "You need to have more than two sequences selected to build a tree!",
3034 "Not enough sequences",
3035 JOptionPane.WARNING_MESSAGE);
3040 SequenceGroup sg = viewport.getSelectionGroup();
3042 /* Decide if the selection is a column region */
3043 while (s < sg.getSize())
3045 if ( ( (SequenceI) sg.getSequences(null).elementAt(s++)).getLength() <
3048 JOptionPane.showMessageDialog(Desktop.desktop,
3049 "The selected region to create a tree may\nonly contain residues or gaps.\n" +
3050 "Try using the Pad function in the edit menu,\n" +
3051 "or one of the multiple sequence alignment web services.",
3052 "Sequences in selection are not aligned",
3053 JOptionPane.WARNING_MESSAGE);
3059 title = title + " on region";
3060 tp = new TreePanel(alignPanel, type, pwType);
3064 //are the sequences aligned?
3065 if (!viewport.alignment.isAligned())
3067 JOptionPane.showMessageDialog(Desktop.desktop,
3068 "The sequences must be aligned before creating a tree.\n" +
3069 "Try using the Pad function in the edit menu,\n" +
3070 "or one of the multiple sequence alignment web services.",
3071 "Sequences not aligned",
3072 JOptionPane.WARNING_MESSAGE);
3077 if(viewport.alignment.getHeight()<2)
3082 tp = new TreePanel(alignPanel, type, pwType);
3087 if(viewport.viewName!=null)
3089 title+= viewport.viewName+" of ";
3092 title += this.title;
3094 Desktop.addInternalFrame(tp, title, 600, 500);
3100 * @param title DOCUMENT ME!
3101 * @param order DOCUMENT ME!
3103 public void addSortByOrderMenuItem(String title, final AlignmentOrder order)
3105 final JMenuItem item = new JMenuItem("by " + title);
3107 item.addActionListener(new java.awt.event.ActionListener()
3109 public void actionPerformed(ActionEvent e)
3111 SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
3113 // TODO: JBPNote - have to map order entries to curent SequenceI pointers
3114 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3116 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3117 viewport.alignment));
3119 alignPanel.paintAlignment(true);
3124 * Add a new sort by annotation score menu item
3125 * @param sort the menu to add the option to
3126 * @param scoreLabel the label used to retrieve scores for each sequence on the alignment
3128 public void addSortByAnnotScoreMenuItem(JMenu sort, final String scoreLabel)
3130 final JMenuItem item = new JMenuItem(scoreLabel);
3132 item.addActionListener(new java.awt.event.ActionListener()
3134 public void actionPerformed(ActionEvent e)
3136 SequenceI [] oldOrder = viewport.getAlignment().getSequencesArray();
3137 AlignmentSorter.sortByAnnotationScore(scoreLabel, viewport.getAlignment());//,viewport.getSelectionGroup());
3138 addHistoryItem(new OrderCommand("Sort by "+scoreLabel, oldOrder, viewport.alignment));
3139 alignPanel.paintAlignment(true);
3144 * last hash for alignment's annotation array - used to minimise cost of rebuild.
3146 protected int _annotationScoreVectorHash;
3148 * search the alignment and rebuild the sort by annotation score submenu
3149 * the last alignment annotation vector hash is stored to minimize
3150 * cost of rebuilding in subsequence calls.
3153 public void buildSortByAnnotationScoresMenu()
3155 if(viewport.alignment.getAlignmentAnnotation()==null)
3160 if (viewport.alignment.getAlignmentAnnotation().hashCode()!=_annotationScoreVectorHash)
3162 sortByAnnotScore.removeAll();
3163 // almost certainly a quicker way to do this - but we keep it simple
3164 Hashtable scoreSorts=new Hashtable();
3165 AlignmentAnnotation aann[];
3166 Enumeration sq = viewport.alignment.getSequences().elements();
3167 while (sq.hasMoreElements())
3169 aann = ((SequenceI) sq.nextElement()).getAnnotation();
3170 for (int i=0;aann!=null && i<aann.length; i++)
3172 if (aann[i].hasScore() && aann[i].sequenceRef!=null)
3174 scoreSorts.put(aann[i].label, aann[i].label);
3178 Enumeration labels = scoreSorts.keys();
3179 while (labels.hasMoreElements())
3181 addSortByAnnotScoreMenuItem(sortByAnnotScore, (String) labels.nextElement());
3183 sortByAnnotScore.setVisible(scoreSorts.size()>0);
3186 _annotationScoreVectorHash =
3187 viewport.alignment.getAlignmentAnnotation().hashCode();
3192 * Maintain the Order by->Displayed Tree menu.
3193 * Creates a new menu item for a TreePanel with an appropriate
3194 * <code>jalview.analysis.AlignmentSorter</code> call. Listeners are added
3195 * to remove the menu item when the treePanel is closed, and adjust
3196 * the tree leaf to sequence mapping when the alignment is modified.
3197 * @param treePanel Displayed tree window.
3198 * @param title SortBy menu item title.
3200 public void buildTreeMenu()
3202 sortByTreeMenu.removeAll();
3204 Vector comps = (Vector) PaintRefresher.components.get(viewport.
3205 getSequenceSetId());
3206 Vector treePanels = new Vector();
3207 int i, iSize = comps.size();
3208 for(i=0; i<iSize; i++)
3210 if(comps.elementAt(i) instanceof TreePanel)
3212 treePanels.add(comps.elementAt(i));
3216 iSize = treePanels.size();
3220 sortByTreeMenu.setVisible(false);
3224 sortByTreeMenu.setVisible(true);
3226 for(i=0; i<treePanels.size(); i++)
3228 TreePanel tp = (TreePanel)treePanels.elementAt(i);
3229 final JMenuItem item = new JMenuItem(tp.getTitle());
3230 final NJTree tree = ((TreePanel)treePanels.elementAt(i)).getTree();
3231 item.addActionListener(new java.awt.event.ActionListener()
3233 public void actionPerformed(ActionEvent e)
3235 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3236 AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
3238 addHistoryItem(new OrderCommand("Tree Sort",
3240 viewport.alignment));
3242 alignPanel.paintAlignment(true);
3246 sortByTreeMenu.add(item);
3251 * Work out whether the whole set of sequences
3252 * or just the selected set will be submitted for multiple alignment.
3255 private jalview.datamodel.AlignmentView gatherSequencesForAlignment()
3257 // Now, check we have enough sequences
3258 AlignmentView msa = null;
3260 if ( (viewport.getSelectionGroup() != null) &&
3261 (viewport.getSelectionGroup().getSize() > 1))
3263 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!
3264 /*SequenceGroup seqs = viewport.getSelectionGroup();
3266 msa = new SequenceI[sz = seqs.getSize(false)];
3268 for (int i = 0; i < sz; i++)
3270 msa[i] = (SequenceI) seqs.getSequenceAt(i);
3272 msa = viewport.getAlignmentView(true);
3276 /*Vector seqs = viewport.getAlignment().getSequences();
3278 if (seqs.size() > 1)
3280 msa = new SequenceI[seqs.size()];
3282 for (int i = 0; i < seqs.size(); i++)
3284 msa[i] = (SequenceI) seqs.elementAt(i);
3287 msa = viewport.getAlignmentView(false);
3293 * Decides what is submitted to a secondary structure prediction service,
3294 * the currently selected sequence, or the currently selected alignment
3295 * (where the first sequence in the set is the one that the prediction
3298 AlignmentView gatherSeqOrMsaForSecStrPrediction()
3300 AlignmentView seqs = null;
3302 if ( (viewport.getSelectionGroup() != null) &&
3303 (viewport.getSelectionGroup().getSize() > 0))
3305 seqs = viewport.getAlignmentView(true);
3309 seqs = viewport.getAlignmentView(false);
3311 // limit sequences - JBPNote in future - could spawn multiple prediction jobs
3312 // TODO: viewport.alignment.isAligned is a global state - the local selection may well be aligned - we preserve 2.0.8 behaviour for moment.
3313 if (!viewport.alignment.isAligned())
3315 seqs.setSequences(new SeqCigar[]
3316 {seqs.getSequences()[0]});
3323 * @param e DOCUMENT ME!
3325 protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)
3327 // Pick the tree file
3328 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
3331 chooser.setFileView(new JalviewFileView());
3332 chooser.setDialogTitle("Select a newick-like tree file");
3333 chooser.setToolTipText("Load a tree file");
3335 int value = chooser.showOpenDialog(null);
3337 if (value == JalviewFileChooser.APPROVE_OPTION)
3339 String choice = chooser.getSelectedFile().getPath();
3340 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
3341 jalview.io.NewickFile fin = null;
3344 fin = new jalview.io.NewickFile(choice,
3346 viewport.setCurrentTree(ShowNewickTree(fin, choice).getTree());
3348 catch (Exception ex)
3350 JOptionPane.showMessageDialog(Desktop.desktop,
3352 "Problem reading tree file",
3353 JOptionPane.WARNING_MESSAGE);
3354 ex.printStackTrace();
3356 if (fin!=null && fin.hasWarningMessage())
3358 JOptionPane.showMessageDialog(Desktop.desktop,
3359 fin.getWarningMessage(),
3360 "Possible problem with tree file",
3361 JOptionPane.WARNING_MESSAGE);
3367 public TreePanel ShowNewickTree(NewickFile nf, String title)
3369 return ShowNewickTree(nf,title,600,500,4,5);
3372 public TreePanel ShowNewickTree(NewickFile nf, String title,
3373 AlignmentView input)
3375 return ShowNewickTree(nf,title, input, 600,500,4,5);
3378 public TreePanel ShowNewickTree(NewickFile nf, String title, int w, int h,
3381 return ShowNewickTree(nf, title, null, w, h, x, y);
3384 * Add a treeviewer for the tree extracted from a newick file object to the current alignment view
3386 * @param nf the tree
3387 * @param title tree viewer title
3388 * @param input Associated alignment input data (or null)
3393 * @return TreePanel handle
3395 public TreePanel ShowNewickTree(NewickFile nf, String title,
3396 AlignmentView input, int w, int h, int x,
3399 TreePanel tp = null;
3405 if (nf.getTree() != null)
3407 tp = new TreePanel(alignPanel,
3416 tp.setLocation(x,y);
3420 Desktop.addInternalFrame(tp, title, w, h);
3423 catch (Exception ex)
3425 ex.printStackTrace();
3433 * Generates menu items and listener event actions for web service clients
3436 public void BuildWebServiceMenu()
3438 // TODO: add support for context dependent disabling of services based on alignment and current selection
3439 // TODO: refactor to allow list of AbstractName/Handler bindings to be stored or retrieved from elsewhere
3440 // TODO: add additional serviceHandle parameter to specify abstract handler class independently of AbstractName
3441 // TODO: add in rediscovery GUI function to restart discoverer
3442 // TODO: group services by location as well as function and/or introduce object broker mechanism.
3443 if ( (Discoverer.services != null)
3444 && (Discoverer.services.size() > 0))
3446 Vector msaws = (Vector) Discoverer.services.get("MsaWS");
3447 Vector secstrpr = (Vector) Discoverer.services.get("SecStrPred");
3448 Vector wsmenu = new Vector();
3449 final AlignFrame af = this;
3452 // Add any Multiple Sequence Alignment Services
3453 final JMenu msawsmenu = new JMenu("Alignment");
3454 for (int i = 0, j = msaws.size(); i < j; i++)
3456 final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws.
3458 final JMenuItem method = new JMenuItem(sh.getName());
3459 method.addActionListener(new ActionListener()
3461 public void actionPerformed(ActionEvent e)
3463 AlignmentView msa = gatherSequencesForAlignment();
3464 new jalview.ws.MsaWSClient(sh, title, msa,
3466 viewport.getAlignment().getDataset(),
3472 msawsmenu.add(method);
3473 // Deal with services that we know accept partial alignments.
3474 if (sh.getName().indexOf("lustal") > -1)
3476 // We know that ClustalWS can accept partial alignments for refinement.
3477 final JMenuItem methodR = new JMenuItem(sh.getName()+" Realign");
3478 methodR.addActionListener(new ActionListener()
3480 public void actionPerformed(ActionEvent e)
3482 AlignmentView msa = gatherSequencesForAlignment();
3483 new jalview.ws.MsaWSClient(sh, title, msa,
3485 viewport.getAlignment().getDataset(),
3491 msawsmenu.add(methodR);
3495 wsmenu.add(msawsmenu);
3497 if (secstrpr != null)
3499 // Add any secondary structure prediction services
3500 final JMenu secstrmenu = new JMenu("Secondary Structure Prediction");
3501 for (int i = 0, j = secstrpr.size(); i < j; i++)
3503 final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle)
3505 final JMenuItem method = new JMenuItem(sh.getName());
3506 method.addActionListener(new ActionListener()
3508 public void actionPerformed(ActionEvent e)
3510 AlignmentView msa = gatherSeqOrMsaForSecStrPrediction();
3511 if (msa.getSequences().length == 1)
3513 // Single Sequence prediction
3514 new jalview.ws.JPredClient(sh, title, false, msa, af, true);
3518 if (msa.getSequences().length > 1)
3520 // Sequence profile based prediction
3521 new jalview.ws.JPredClient(sh,
3522 title, true, msa, af, true);
3527 secstrmenu.add(method);
3529 wsmenu.add(secstrmenu);
3531 resetWebServiceMenu();
3532 for (int i = 0, j = wsmenu.size(); i < j; i++)
3534 webService.add( (JMenu) wsmenu.get(i));
3539 resetWebServiceMenu();
3540 this.webService.add(this.webServiceNoServices);
3546 * empty the web service menu and add any ad-hoc functions
3547 * not dynamically discovered.
3550 private void resetWebServiceMenu()
3552 webService.removeAll();
3553 // Temporary hack - DBRef Fetcher always top level ws entry.
3554 JMenuItem rfetch = new JMenuItem("Fetch DB References");
3555 rfetch.setToolTipText("Retrieve and parse uniprot records for the alignment or the currently selected sequences");
3556 webService.add(rfetch);
3557 rfetch.addActionListener(new ActionListener() {
3559 public void actionPerformed(ActionEvent e)
3561 new jalview.ws.DBRefFetcher(
3562 alignPanel.av.getSequenceSelection(),
3563 alignPanel.alignFrame).fetchDBRefs(false);
3569 /* public void vamsasStore_actionPerformed(ActionEvent e)
3571 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
3572 getProperty("LAST_DIRECTORY"));
3574 chooser.setFileView(new JalviewFileView());
3575 chooser.setDialogTitle("Export to Vamsas file");
3576 chooser.setToolTipText("Export");
3578 int value = chooser.showSaveDialog(this);
3580 if (value == JalviewFileChooser.APPROVE_OPTION)
3582 jalview.io.VamsasDatastore vs = new jalview.io.VamsasDatastore(viewport);
3583 //vs.store(chooser.getSelectedFile().getAbsolutePath() );
3584 vs.storeJalview( chooser.getSelectedFile().getAbsolutePath(), this);
3588 * prototype of an automatically enabled/disabled analysis function
3591 protected void setShowProductsEnabled()
3593 SequenceI [] selection = viewport.getSequenceSelection();
3594 if (canShowProducts(selection, viewport.getSelectionGroup()!=null, viewport.getAlignment().getDataset()))
3596 showProducts.setEnabled(true);
3599 showProducts.setEnabled(false);
3603 * search selection for sequence xRef products and build the
3604 * show products menu.
3607 * @return true if showProducts menu should be enabled.
3609 public boolean canShowProducts(SequenceI[] selection, boolean isRegionSelection, Alignment dataset)
3611 boolean showp=false;
3613 showProducts.removeAll();
3614 final boolean dna = viewport.getAlignment().isNucleotide();
3615 final Alignment ds = dataset;
3616 String[] ptypes = CrossRef.findSequenceXrefTypes(dna, selection, dataset);
3617 //Object[] prods = CrossRef.buildXProductsList(viewport.getAlignment().isNucleotide(), selection, dataset, true);
3618 final SequenceI[] sel = selection;
3619 for (int t=0; ptypes!=null && t<ptypes.length; t++)
3622 final boolean isRegSel = isRegionSelection;
3623 final AlignFrame af = this;
3624 final String source = ptypes[t];
3625 JMenuItem xtype = new JMenuItem(ptypes[t]);
3626 xtype.addActionListener(new ActionListener() {
3628 public void actionPerformed(ActionEvent e)
3630 // TODO: new thread for this call with vis-delay
3631 af.showProductsFor(sel, ds, isRegSel, dna, source);
3635 showProducts.add(xtype);
3637 showProducts.setVisible(showp);
3638 showProducts.setEnabled(showp);
3639 } catch (Exception e)
3641 jalview.bin.Cache.log.warn("canTranslate threw an exception - please report to help@jalview.org",e);
3646 protected void showProductsFor(SequenceI[] sel, Alignment ds, boolean isRegSel, boolean dna, String source)
3648 final boolean fisRegSel = isRegSel;
3649 final boolean fdna = dna;
3650 final String fsrc = source;
3651 final AlignFrame ths = this;
3652 final SequenceI[] fsel = sel;
3653 Runnable foo = new Runnable() {
3657 final long sttime = System.currentTimeMillis();
3658 ths.setProgressBar("Searching for sequences from "+fsrc, sttime);
3660 Alignment ds = ths.getViewport().alignment.getDataset(); // update our local dataset reference
3661 Alignment prods = CrossRef.findXrefSequences(fsel, fdna, fsrc, ds);
3664 SequenceI[] sprods = new SequenceI[prods.getHeight()];
3665 for (int s=0; s<sprods.length;s++)
3667 sprods[s] = (prods.getSequenceAt(s)).deriveSequence();
3668 if (ds.getSequences()==null || !ds.getSequences().contains(sprods[s].getDatasetSequence()))
3669 ds.addSequence(sprods[s].getDatasetSequence());
3670 sprods[s].updatePDBIds();
3672 Alignment al = new Alignment(sprods);
3673 AlignedCodonFrame[] cf = prods.getCodonFrames();
3674 for (int s=0; cf!=null && s<cf.length; s++)
3676 al.addCodonFrame(cf[s]);
3680 AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
3681 String newtitle =""+((fdna) ? "Proteins " : "Nucleotides ") + " for "+((fisRegSel) ? "selected region of " : "")
3683 Desktop.addInternalFrame(naf, newtitle, DEFAULT_WIDTH,
3686 System.err.println("No Sequences generated for xRef type "+fsrc);
3691 jalview.bin.Cache.log.error("Exception when finding crossreferences",e);
3695 jalview.bin.Cache.log.error("Error when finding crossreferences",e);
3697 ths.setProgressBar("Finished searching for sequences from "+fsrc, sttime);
3701 Thread frunner = new Thread(foo);
3706 public boolean canShowTranslationProducts(SequenceI[] selection, AlignmentI alignment)
3710 return (jalview.analysis.Dna.canTranslate(selection, viewport.getViewAsVisibleContigs(true)));
3711 } catch (Exception e)
3713 jalview.bin.Cache.log.warn("canTranslate threw an exception - please report to help@jalview.org",e);
3718 public void showProducts_actionPerformed(ActionEvent e)
3720 ///////////////////////////////
3721 // Collect Data to be translated/transferred
3723 SequenceI [] selection = viewport.getSequenceSelection();
3724 AlignmentI al = null;
3726 al = jalview.analysis.Dna.CdnaTranslate(selection, viewport.getViewAsVisibleContigs(true),
3727 viewport.getGapCharacter(), viewport.getAlignment().getDataset());
3728 } catch (Exception ex) {
3730 jalview.bin.Cache.log.debug("Exception during translation.",ex);
3734 JOptionPane.showMessageDialog(Desktop.desktop,
3735 "Please select at least three bases in at least one sequence in order to perform a cDNA translation.",
3736 "Translation Failed",
3737 JOptionPane.WARNING_MESSAGE);
3739 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
3740 Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),
3746 public void showTranslation_actionPerformed(ActionEvent e)
3748 ///////////////////////////////
3749 // Collect Data to be translated/transferred
3751 SequenceI [] selection = viewport.getSequenceSelection();
3752 String [] seqstring = viewport.getViewAsString(true);
3753 AlignmentI al = null;
3755 al = jalview.analysis.Dna.CdnaTranslate(selection, seqstring, viewport.getViewAsVisibleContigs(true),
3756 viewport.getGapCharacter(), viewport.alignment.getAlignmentAnnotation(),
3757 viewport.alignment.getWidth(), viewport.getAlignment().getDataset());
3758 } catch (Exception ex) {
3760 jalview.bin.Cache.log.debug("Exception during translation.",ex);
3764 JOptionPane.showMessageDialog(Desktop.desktop,
3765 "Please select at least three bases in at least one sequence in order to perform a cDNA translation.",
3766 "Translation Failed",
3767 JOptionPane.WARNING_MESSAGE);
3769 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
3770 Desktop.addInternalFrame(af, "Translation of "+this.getTitle(),
3777 * Try to load a features file onto the alignment.
3778 * @param file contents or path to retrieve file
3779 * @param type access mode of file (see jalview.io.AlignFile)
3780 * @return true if features file was parsed corectly.
3782 public boolean parseFeaturesFile(String file, String type)
3784 boolean featuresFile = false;
3787 featuresFile = new FeaturesFile(file,
3788 type).parse(viewport.alignment.getDataset(),
3789 alignPanel.seqPanel.seqCanvas.
3790 getFeatureRenderer().featureColours,
3795 ex.printStackTrace();
3800 viewport.showSequenceFeatures = true;
3801 showSeqFeatures.setSelected(true);
3802 alignPanel.paintAlignment(true);
3805 return featuresFile;
3808 public void dragEnter(DropTargetDragEvent evt)
3811 public void dragExit(DropTargetEvent evt)
3814 public void dragOver(DropTargetDragEvent evt)
3817 public void dropActionChanged(DropTargetDragEvent evt)
3820 public void drop(DropTargetDropEvent evt)
3822 Transferable t = evt.getTransferable();
3823 java.util.List files = null;
3827 DataFlavor uriListFlavor = new DataFlavor(
3828 "text/uri-list;class=java.lang.String");
3829 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3831 //Works on Windows and MacOSX
3832 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3833 files = (java.util.List) t.getTransferData(DataFlavor.
3834 javaFileListFlavor);
3836 else if (t.isDataFlavorSupported(uriListFlavor))
3838 // This is used by Unix drag system
3839 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3840 String data = (String) t.getTransferData(uriListFlavor);
3841 files = new java.util.ArrayList(1);
3842 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3845 st.hasMoreTokens(); )
3847 String s = st.nextToken();
3848 if (s.startsWith("#"))
3850 // the line is a comment (as per the RFC 2483)
3854 java.net.URI uri = new java.net.URI(s);
3855 java.io.File file = new java.io.File(uri);
3862 e.printStackTrace();
3869 for (int i = 0; i < files.size(); i++)
3871 loadJalviewDataFile(files.get(i).toString());
3874 catch (Exception ex)
3876 ex.printStackTrace();
3882 * Attempt to load a "dropped" file: First by testing
3883 * whether it's and Annotation file, then a JNet file, and finally a features file. If all are
3884 * false then the user may have dropped an alignment file onto this
3886 * @param file either a filename or a URL string.
3888 public void loadJalviewDataFile(String file)
3892 String protocol = "File";
3894 if (file.indexOf("http:") > -1 || file.indexOf("file:") > -1)
3899 boolean isAnnotation = new AnnotationFile().readAnnotationFile(viewport.
3900 alignment, file, protocol);
3904 // try to see if its a JNet 'concise' style annotation file *before* we try to parse it as a features file
3905 String format = new IdentifyFile().Identify(file, protocol);
3906 if(format.equalsIgnoreCase("JnetFile"))
3908 jalview.io.JPredFile predictions = new jalview.io.JPredFile(
3910 new JnetAnnotationMaker().add_annotation(predictions,
3911 viewport.getAlignment(),
3917 // try to parse it as a features file
3918 boolean isGroupsFile = parseFeaturesFile(file,protocol);
3919 // if it wasn't a features file then we just treat it as a general alignment file to load into the current view.
3922 new FileLoader().LoadFile(viewport, file, protocol, format);
3924 alignPanel.paintAlignment(true);
3931 alignPanel.adjustAnnotationHeight();
3932 buildSortByAnnotationScoresMenu();
3933 alignPanel.paintAlignment(true);
3936 catch (Exception ex)
3938 ex.printStackTrace();
3942 public void tabSelectionChanged(int index)
3946 alignPanel = (AlignmentPanel) alignPanels.elementAt(index);
3947 viewport = alignPanel.av;
3948 setMenusFromViewport(viewport);
3952 public void tabbedPane_mousePressed(MouseEvent e)
3954 if(SwingUtilities.isRightMouseButton(e))
3956 String reply = JOptionPane.showInternalInputDialog(this,
3959 JOptionPane.QUESTION_MESSAGE);
3963 viewport.viewName = reply;
3964 tabbedPane.setTitleAt( tabbedPane.getSelectedIndex() ,reply);
3970 public AlignViewport getCurrentView()
3977 * Open the dialog for regex description parsing.
3979 protected void extractScores_actionPerformed(ActionEvent e)
3981 ParseProperties pp = new jalview.analysis.ParseProperties(viewport.alignment);
3982 if (pp.getScoresFromDescription("col", "score column ", "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)", true)>0)
3984 buildSortByAnnotationScoresMenu();
3993 public PrintThread(AlignmentPanel ap)
3997 static PageFormat pf;
4000 PrinterJob printJob = PrinterJob.getPrinterJob();
4004 printJob.setPrintable(ap, pf);
4008 printJob.setPrintable(ap);
4011 if (printJob.printDialog())
4017 catch (Exception PrintException)
4019 PrintException.printStackTrace();