2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.OutputStreamWriter;
53 import java.io.PrintWriter;
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.Deque;
58 import java.util.Enumeration;
59 import java.util.Hashtable;
60 import java.util.List;
61 import java.util.Locale;
62 import java.util.Vector;
64 import javax.swing.ButtonGroup;
65 import javax.swing.JCheckBoxMenuItem;
66 import javax.swing.JComponent;
67 import javax.swing.JEditorPane;
68 import javax.swing.JInternalFrame;
69 import javax.swing.JLabel;
70 import javax.swing.JLayeredPane;
71 import javax.swing.JMenu;
72 import javax.swing.JMenuItem;
73 import javax.swing.JPanel;
74 import javax.swing.JScrollPane;
75 import javax.swing.SwingUtilities;
77 import ext.vamsas.ServiceHandle;
78 import jalview.analysis.AlignmentSorter;
79 import jalview.analysis.AlignmentUtils;
80 import jalview.analysis.CrossRef;
81 import jalview.analysis.Dna;
82 import jalview.analysis.GeneticCodeI;
83 import jalview.analysis.ParseProperties;
84 import jalview.analysis.SequenceIdMatcher;
85 import jalview.api.AlignExportSettingsI;
86 import jalview.api.AlignViewControllerGuiI;
87 import jalview.api.AlignViewControllerI;
88 import jalview.api.AlignViewportI;
89 import jalview.api.AlignmentViewPanel;
90 import jalview.api.FeatureSettingsControllerI;
91 import jalview.api.FeatureSettingsModelI;
92 import jalview.api.SplitContainerI;
93 import jalview.api.ViewStyleI;
94 import jalview.api.analysis.SimilarityParamsI;
95 import jalview.bin.Cache;
96 import jalview.bin.Console;
97 import jalview.bin.Jalview;
98 import jalview.bin.groovy.JalviewObjectI;
99 import jalview.commands.CommandI;
100 import jalview.commands.EditCommand;
101 import jalview.commands.EditCommand.Action;
102 import jalview.commands.OrderCommand;
103 import jalview.commands.RemoveGapColCommand;
104 import jalview.commands.RemoveGapsCommand;
105 import jalview.commands.SlideSequencesCommand;
106 import jalview.commands.TrimRegionCommand;
107 import jalview.datamodel.AlignExportSettingsAdapter;
108 import jalview.datamodel.AlignedCodonFrame;
109 import jalview.datamodel.Alignment;
110 import jalview.datamodel.AlignmentAnnotation;
111 import jalview.datamodel.AlignmentExportData;
112 import jalview.datamodel.AlignmentI;
113 import jalview.datamodel.AlignmentOrder;
114 import jalview.datamodel.AlignmentView;
115 import jalview.datamodel.ColumnSelection;
116 import jalview.datamodel.ContactMatrixI;
117 import jalview.datamodel.HiddenColumns;
118 import jalview.datamodel.PDBEntry;
119 import jalview.datamodel.SeqCigar;
120 import jalview.datamodel.Sequence;
121 import jalview.datamodel.SequenceGroup;
122 import jalview.datamodel.SequenceI;
123 import jalview.gui.ColourMenuHelper.ColourChangeListener;
124 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
125 import jalview.io.AlignmentProperties;
126 import jalview.io.AnnotationFile;
127 import jalview.io.BackupFiles;
128 import jalview.io.BioJsHTMLOutput;
129 import jalview.io.DataSourceType;
130 import jalview.io.FileFormat;
131 import jalview.io.FileFormatI;
132 import jalview.io.FileFormats;
133 import jalview.io.FileLoader;
134 import jalview.io.FileParse;
135 import jalview.io.FormatAdapter;
136 import jalview.io.HtmlSvgOutput;
137 import jalview.io.IdentifyFile;
138 import jalview.io.JPredFile;
139 import jalview.io.JalviewFileChooser;
140 import jalview.io.JalviewFileView;
141 import jalview.io.JnetAnnotationMaker;
142 import jalview.io.NewickFile;
143 import jalview.io.ScoreMatrixFile;
144 import jalview.io.TCoffeeScoreFile;
145 import jalview.io.exceptions.ImageOutputException;
146 import jalview.io.vcf.VCFLoader;
147 import jalview.jbgui.GAlignFrame;
148 import jalview.project.Jalview2XML;
149 import jalview.schemes.ColourSchemeI;
150 import jalview.schemes.ColourSchemes;
151 import jalview.schemes.ResidueColourScheme;
152 import jalview.schemes.TCoffeeColourScheme;
153 import jalview.util.HttpUtils;
154 import jalview.util.ImageMaker.TYPE;
155 import jalview.util.MessageManager;
156 import jalview.util.Platform;
157 import jalview.util.imagemaker.BitmapImageSizing;
158 import jalview.viewmodel.AlignmentViewport;
159 import jalview.viewmodel.ViewportRanges;
160 import jalview.ws.DBRefFetcher;
161 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
162 import jalview.ws.jws1.Discoverer;
163 import jalview.ws.jws2.Jws2Discoverer;
164 import jalview.ws.jws2.jabaws2.Jws2Instance;
165 import jalview.ws.seqfetcher.DbSourceProxy;
171 * @version $Revision$
173 @SuppressWarnings("serial")
174 public class AlignFrame extends GAlignFrame implements DropTargetListener,
175 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
178 public static final int DEFAULT_WIDTH = 700;
180 public static final int DEFAULT_HEIGHT = 500;
183 * The currently displayed panel (selected tabbed view if more than one)
185 public AlignmentPanel alignPanel;
187 AlignViewport viewport;
189 public AlignViewControllerI avc;
191 List<AlignmentPanel> alignPanels = new ArrayList<>();
194 * Last format used to load or save alignments in this window
196 FileFormatI currentFileFormat = null;
199 * Current filename for this alignment
201 String fileName = null;
206 * Creates a new AlignFrame object with specific width and height.
212 public AlignFrame(AlignmentI al, int width, int height)
214 this(al, null, width, height);
218 * Creates a new AlignFrame object with specific width, height and
224 * @param sequenceSetId
226 public AlignFrame(AlignmentI al, int width, int height,
227 String sequenceSetId)
229 this(al, null, width, height, sequenceSetId);
233 * Creates a new AlignFrame object with specific width, height and
239 * @param sequenceSetId
242 public AlignFrame(AlignmentI al, int width, int height,
243 String sequenceSetId, String viewId)
245 this(al, null, width, height, sequenceSetId, viewId);
249 * new alignment window with hidden columns
253 * @param hiddenColumns
254 * ColumnSelection or null
256 * Width of alignment frame
260 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
263 this(al, hiddenColumns, width, height, null);
267 * Create alignment frame for al with hiddenColumns, a specific width and
268 * height, and specific sequenceId
271 * @param hiddenColumns
274 * @param sequenceSetId
277 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
278 int height, String sequenceSetId)
280 this(al, hiddenColumns, width, height, sequenceSetId, null);
284 * Create alignment frame for al with hiddenColumns, a specific width and
285 * height, and specific sequenceId
288 * @param hiddenColumns
291 * @param sequenceSetId
296 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
297 int height, String sequenceSetId, String viewId)
299 setSize(width, height);
301 if (al.getDataset() == null)
306 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
308 alignPanel = new AlignmentPanel(this, viewport);
310 addAlignmentPanel(alignPanel, true);
314 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
315 HiddenColumns hiddenColumns, int width, int height)
317 setSize(width, height);
319 if (al.getDataset() == null)
324 viewport = new AlignViewport(al, hiddenColumns);
326 if (hiddenSeqs != null && hiddenSeqs.length > 0)
328 viewport.hideSequence(hiddenSeqs);
330 alignPanel = new AlignmentPanel(this, viewport);
331 addAlignmentPanel(alignPanel, true);
336 * Make a new AlignFrame from existing alignmentPanels
343 public AlignFrame(AlignmentPanel ap)
347 addAlignmentPanel(ap, false);
352 * initalise the alignframe from the underlying viewport data and the
359 // setBackground(Color.white); // BH 2019
361 if (!Jalview.isHeadlessMode())
363 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
366 avc = new jalview.controller.AlignViewController(this, viewport,
368 if (viewport.getAlignmentConservationAnnotation() == null)
370 // BLOSUM62Colour.setEnabled(false);
371 conservationMenuItem.setEnabled(false);
372 modifyConservation.setEnabled(false);
373 // PIDColour.setEnabled(false);
374 // abovePIDThreshold.setEnabled(false);
375 // modifyPID.setEnabled(false);
378 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
380 if (sortby.equals("Id"))
382 sortIDMenuItem_actionPerformed(null);
384 else if (sortby.equals("Pairwise Identity"))
386 sortPairwiseMenuItem_actionPerformed(null);
390 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
392 setMenusFromViewport(viewport);
393 buildSortByAnnotationScoresMenu();
394 calculateTree.addActionListener(new ActionListener()
398 public void actionPerformed(ActionEvent e)
405 if (Desktop.desktop != null)
407 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
408 if (!Platform.isJS())
410 addServiceListeners();
415 if (viewport.getWrapAlignment())
417 wrapMenuItem_actionPerformed(null);
420 if (Cache.getDefault("SHOW_OVERVIEW", false))
422 this.overviewMenuItem_actionPerformed(null);
427 final List<AlignmentViewPanel> selviews = new ArrayList<>();
428 final List<AlignmentPanel> origview = new ArrayList<>();
429 final String menuLabel = MessageManager
430 .getString("label.copy_format_from");
431 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
432 new ViewSetProvider()
436 public AlignmentPanel[] getAllAlignmentPanels()
439 origview.add(alignPanel);
440 // make an array of all alignment panels except for this one
441 List<AlignmentPanel> aps = new ArrayList<>(
442 Arrays.asList(Desktop.getAlignmentPanels(null)));
443 aps.remove(AlignFrame.this.alignPanel);
444 return aps.toArray(new AlignmentPanel[aps.size()]);
446 }, selviews, new ItemListener()
450 public void itemStateChanged(ItemEvent e)
452 if (origview.size() > 0)
454 final AlignmentPanel ap = origview.get(0);
457 * Copy the ViewStyle of the selected panel to 'this one'.
458 * Don't change value of 'scaleProteinAsCdna' unless copying
461 ViewStyleI vs = selviews.get(0).getAlignViewport()
463 boolean fromSplitFrame = selviews.get(0)
464 .getAlignViewport().getCodingComplement() != null;
467 vs.setScaleProteinAsCdna(ap.getAlignViewport()
468 .getViewStyle().isScaleProteinAsCdna());
470 ap.getAlignViewport().setViewStyle(vs);
473 * Also rescale ViewStyle of SplitFrame complement if there is
474 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
475 * the whole ViewStyle (allow cDNA protein to have different
478 AlignViewportI complement = ap.getAlignViewport()
479 .getCodingComplement();
480 if (complement != null && vs.isScaleProteinAsCdna())
482 AlignFrame af = Desktop.getAlignFrameFor(complement);
483 ((SplitFrame) af.getSplitViewContainer())
485 af.setMenusForViewport();
489 ap.setSelected(true);
490 ap.alignFrame.setMenusForViewport();
495 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
496 .indexOf("devel") > -1
497 || Cache.getDefault("VERSION", "DEVELOPMENT")
498 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
500 formatMenu.add(vsel);
502 addFocusListener(new FocusAdapter()
505 public void focusGained(FocusEvent e)
507 Jalview.getInstance().setCurrentAlignFrame(AlignFrame.this);
514 * Change the filename and format for the alignment, and enable the 'reload'
515 * button functionality.
522 public void setFileName(String file, FileFormatI format)
525 setFileFormat(format);
526 reload.setEnabled(true);
530 * JavaScript will have this, maybe others. More dependable than a file name
531 * and maintains a reference to the actual bytes loaded.
535 public void setFileObject(File file)
537 this.fileObject = file;
541 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
544 void addKeyListener()
546 addKeyListener(new KeyAdapter()
549 public void keyPressed(KeyEvent evt)
551 if (viewport.cursorMode
552 && ((evt.getKeyCode() >= KeyEvent.VK_0
553 && evt.getKeyCode() <= KeyEvent.VK_9)
554 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
555 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
556 && Character.isDigit(evt.getKeyChar()))
558 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
561 switch (evt.getKeyCode())
564 case 27: // escape key
565 deselectAllSequenceMenuItem_actionPerformed(null);
569 case KeyEvent.VK_DOWN:
570 if (evt.isAltDown() || !viewport.cursorMode)
572 moveSelectedSequences(false);
574 if (viewport.cursorMode)
576 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
581 if (evt.isAltDown() || !viewport.cursorMode)
583 moveSelectedSequences(true);
585 if (viewport.cursorMode)
587 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
592 case KeyEvent.VK_LEFT:
593 if (evt.isAltDown() || !viewport.cursorMode)
595 slideSequences(false,
596 alignPanel.getSeqPanel().getKeyboardNo1());
600 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
605 case KeyEvent.VK_RIGHT:
606 if (evt.isAltDown() || !viewport.cursorMode)
608 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
612 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
616 case KeyEvent.VK_SPACE:
617 if (viewport.cursorMode)
619 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
620 || evt.isShiftDown() || evt.isAltDown());
624 // case KeyEvent.VK_A:
625 // if (viewport.cursorMode)
627 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
628 // //jalview.bin.Console.outPrintln("A");
632 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
633 * jalview.bin.Console.outPrintln("closing bracket"); } break;
635 case KeyEvent.VK_DELETE:
636 case KeyEvent.VK_BACK_SPACE:
637 if (!viewport.cursorMode)
639 cut_actionPerformed();
643 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
644 || evt.isShiftDown() || evt.isAltDown());
650 if (viewport.cursorMode)
652 alignPanel.getSeqPanel().setCursorRow();
656 if (viewport.cursorMode && !evt.isControlDown())
658 alignPanel.getSeqPanel().setCursorColumn();
662 if (viewport.cursorMode)
664 alignPanel.getSeqPanel().setCursorPosition();
668 case KeyEvent.VK_ENTER:
669 case KeyEvent.VK_COMMA:
670 if (viewport.cursorMode)
672 alignPanel.getSeqPanel().setCursorRowAndColumn();
677 if (viewport.cursorMode)
679 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
683 if (viewport.cursorMode)
685 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
690 viewport.cursorMode = !viewport.cursorMode;
691 setStatus(MessageManager
692 .formatMessage("label.keyboard_editing_mode", new String[]
693 { (viewport.cursorMode ? "on" : "off") }));
694 if (viewport.cursorMode)
696 ViewportRanges ranges = viewport.getRanges();
697 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
699 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
702 alignPanel.getSeqPanel().seqCanvas.repaint();
708 Help.showHelpWindow();
709 } catch (Exception ex)
711 ex.printStackTrace();
716 boolean toggleSeqs = !evt.isControlDown();
717 boolean toggleCols = !evt.isShiftDown();
718 toggleHiddenRegions(toggleSeqs, toggleCols);
723 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
724 boolean modifyExisting = true; // always modify, don't clear
725 // evt.isShiftDown();
726 boolean invertHighlighted = evt.isAltDown();
727 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
731 case KeyEvent.VK_PAGE_UP:
732 viewport.getRanges().pageUp();
734 case KeyEvent.VK_PAGE_DOWN:
735 viewport.getRanges().pageDown();
741 public void keyReleased(KeyEvent evt)
743 switch (evt.getKeyCode())
745 case KeyEvent.VK_LEFT:
746 if (evt.isAltDown() || !viewport.cursorMode)
748 viewport.firePropertyChange("alignment", null,
749 viewport.getAlignment().getSequences());
753 case KeyEvent.VK_RIGHT:
754 if (evt.isAltDown() || !viewport.cursorMode)
756 viewport.firePropertyChange("alignment", null,
757 viewport.getAlignment().getSequences());
765 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
767 ap.alignFrame = this;
768 avc = new jalview.controller.AlignViewController(this, viewport,
773 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
775 int aSize = alignPanels.size();
777 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
779 if (aSize == 1 && ap.av.getViewName() == null)
781 this.getContentPane().add(ap, BorderLayout.CENTER);
787 setInitialTabVisible();
790 expandViews.setEnabled(true);
791 gatherViews.setEnabled(true);
792 tabbedPane.addTab(ap.av.getViewName(), ap);
794 ap.setVisible(false);
799 if (ap.av.isPadGaps())
801 ap.av.getAlignment().padGaps();
803 ap.av.updateConservation(ap);
804 ap.av.updateConsensus(ap);
805 ap.av.updateSecondaryStructureConsensus(ap);
806 ap.av.updateStrucConsensus(ap);
810 public void setInitialTabVisible()
812 expandViews.setEnabled(true);
813 gatherViews.setEnabled(true);
814 tabbedPane.setVisible(true);
815 AlignmentPanel first = alignPanels.get(0);
816 tabbedPane.addTab(first.av.getViewName(), first);
817 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
820 public AlignViewport getViewport()
825 /* Set up intrinsic listeners for dynamically generated GUI bits. */
826 private void addServiceListeners()
828 final java.beans.PropertyChangeListener thisListener;
829 Desktop.instance.addJalviewPropertyChangeListener("services",
830 thisListener = new java.beans.PropertyChangeListener()
833 public void propertyChange(PropertyChangeEvent evt)
835 // // jalview.bin.Console.outPrintln("Discoverer property
837 // if (evt.getPropertyName().equals("services"))
839 SwingUtilities.invokeLater(new Runnable()
845 jalview.bin.Console.errPrintln(
846 "Rebuild WS Menu for service change");
847 BuildWebServiceMenu();
854 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
857 public void internalFrameClosed(
858 javax.swing.event.InternalFrameEvent evt)
860 // jalview.bin.Console.outPrintln("deregistering discoverer listener");
861 Desktop.instance.removeJalviewPropertyChangeListener("services",
863 closeMenuItem_actionPerformed(true);
866 // Finally, build the menu once to get current service state
867 new Thread(new Runnable()
872 BuildWebServiceMenu();
878 * Configure menu items that vary according to whether the alignment is
879 * nucleotide or protein
881 public void setGUINucleotide()
883 AlignmentI al = getViewport().getAlignment();
884 boolean nucleotide = al.isNucleotide();
886 loadVcf.setVisible(nucleotide);
887 showTranslation.setVisible(nucleotide);
888 showReverse.setVisible(nucleotide);
889 showReverseComplement.setVisible(nucleotide);
890 conservationMenuItem.setEnabled(!nucleotide);
892 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
893 showGroupConservation.setEnabled(!nucleotide);
895 showComplementMenuItem
896 .setText(nucleotide ? MessageManager.getString("label.protein")
897 : MessageManager.getString("label.nucleotide"));
901 * set up menus for the current viewport. This may be called after any
902 * operation that affects the data in the current view (selection changed,
903 * etc) to update the menus to reflect the new state.
906 public void setMenusForViewport()
908 setMenusFromViewport(viewport);
912 * Need to call this method when tabs are selected for multiple views, or when
913 * loading from Jalview2XML.java
918 public void setMenusFromViewport(AlignViewport av)
920 padGapsMenuitem.setSelected(av.isPadGaps());
921 colourTextMenuItem.setSelected(av.isShowColourText());
922 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
923 modifyPID.setEnabled(abovePIDThreshold.isSelected());
924 conservationMenuItem.setSelected(av.getConservationSelected());
925 modifyConservation.setEnabled(conservationMenuItem.isSelected());
926 seqLimits.setSelected(av.getShowJVSuffix());
927 idRightAlign.setSelected(av.isRightAlignIds());
928 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
929 renderGapsMenuItem.setSelected(av.isRenderGaps());
930 wrapMenuItem.setSelected(av.getWrapAlignment());
931 scaleAbove.setVisible(av.getWrapAlignment());
932 scaleLeft.setVisible(av.getWrapAlignment());
933 scaleRight.setVisible(av.getWrapAlignment());
934 annotationPanelMenuItem.setState(av.isShowAnnotation());
936 * Show/hide annotations only enabled if annotation panel is shown
938 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
939 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
940 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
941 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
942 viewBoxesMenuItem.setSelected(av.getShowBoxes());
943 viewTextMenuItem.setSelected(av.getShowText());
944 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
945 showGroupConsensus.setSelected(av.isShowGroupConsensus());
946 showGroupConservation.setSelected(av.isShowGroupConservation());
947 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
948 showSequenceLogo.setSelected(av.isShowSequenceLogo());
949 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
951 ColourMenuHelper.setColourSelected(colourMenu,
952 av.getGlobalColourScheme());
954 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
955 hiddenMarkers.setState(av.getShowHiddenMarkers());
956 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
957 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
958 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
959 autoCalculate.setSelected(av.autoCalculateConsensus);
960 sortByTree.setSelected(av.sortByTree);
961 listenToViewSelections.setSelected(av.followSelection);
963 showProducts.setEnabled(canShowProducts());
964 setGroovyEnabled(Desktop.getGroovyConsole() != null);
970 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
974 public void setGroovyEnabled(boolean b)
976 runGroovy.setEnabled(b);
979 private IProgressIndicator progressBar;
984 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
987 public void setProgressBar(String message, long id)
989 if (!Platform.isHeadless() && progressBar != null)
990 progressBar.setProgressBar(message, id);
994 public void registerHandler(final long id,
995 final IProgressIndicatorHandler handler)
997 if (progressBar != null)
998 progressBar.registerHandler(id, handler);
1003 * @return true if any progress bars are still active
1006 public boolean operationInProgress()
1008 return progressBar == null ? false : progressBar.operationInProgress();
1012 * Sets the text of the status bar. Note that setting a null or empty value
1013 * will cause the status bar to be hidden, with possibly undesirable flicker
1014 * of the screen layout.
1017 public void setStatus(String text)
1019 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1023 * Added so Castor Mapping file can obtain Jalview Version
1025 public String getVersion()
1027 return Cache.getProperty("VERSION");
1030 public FeatureRenderer getFeatureRenderer()
1032 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1036 public void fetchSequence_actionPerformed()
1038 new SequenceFetcher(this);
1042 public void addFromFile_actionPerformed(ActionEvent e)
1044 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1048 public void reload_actionPerformed(ActionEvent e)
1050 if (fileName != null)
1052 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1053 // originating file's format
1054 // TODO: work out how to recover feature settings for correct view(s) when
1055 // file is reloaded.
1056 if (FileFormat.Jalview.equals(currentFileFormat))
1058 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1059 for (int i = 0; i < frames.length; i++)
1061 if (frames[i] instanceof AlignFrame && frames[i] != this
1062 && ((AlignFrame) frames[i]).fileName != null
1063 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1067 frames[i].setSelected(true);
1068 Desktop.instance.closeAssociatedWindows();
1069 } catch (java.beans.PropertyVetoException ex)
1075 Desktop.instance.closeAssociatedWindows();
1077 FileLoader loader = new FileLoader();
1078 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1079 ? DataSourceType.URL
1080 : DataSourceType.FILE;
1081 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1085 Rectangle bounds = this.getBounds();
1087 FileLoader loader = new FileLoader();
1089 AlignFrame newframe = null;
1091 if (fileObject == null)
1094 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1095 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1096 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1101 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1102 DataSourceType.FILE, currentFileFormat);
1105 newframe.setBounds(bounds);
1106 if (featureSettings != null && featureSettings.isShowing())
1108 final Rectangle fspos = featureSettings.frame.getBounds();
1109 // TODO: need a 'show feature settings' function that takes bounds -
1110 // need to refactor Desktop.addFrame
1111 newframe.featureSettings_actionPerformed(null);
1112 final FeatureSettings nfs = newframe.featureSettings;
1113 SwingUtilities.invokeLater(new Runnable()
1118 nfs.frame.setBounds(fspos);
1121 this.featureSettings.close();
1122 this.featureSettings = null;
1124 this.closeMenuItem_actionPerformed(true);
1130 public void addFromText_actionPerformed(ActionEvent e)
1133 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1137 public void addFromURL_actionPerformed(ActionEvent e)
1139 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1143 public void save_actionPerformed(ActionEvent e)
1145 if (fileName == null || (currentFileFormat == null)
1146 || HttpUtils.startsWithHttpOrHttps(fileName))
1148 saveAs_actionPerformed();
1152 saveAlignment(fileName, currentFileFormat);
1157 * Saves the alignment to a file with a name chosen by the user, if necessary
1158 * warning if a file would be overwritten
1161 public void saveAs_actionPerformed()
1163 String format = currentFileFormat == null ? null
1164 : currentFileFormat.getName();
1165 JalviewFileChooser chooser = JalviewFileChooser
1166 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1168 chooser.setFileView(new JalviewFileView());
1169 chooser.setDialogTitle(
1170 MessageManager.getString("label.save_alignment_to_file"));
1171 chooser.setToolTipText(MessageManager.getString("action.save"));
1173 int value = chooser.showSaveDialog(this);
1175 if (value != JalviewFileChooser.APPROVE_OPTION)
1179 currentFileFormat = chooser.getSelectedFormat();
1180 // todo is this (2005) test now obsolete - value is never null?
1181 while (currentFileFormat == null)
1183 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1185 .getString("label.select_file_format_before_saving"),
1186 MessageManager.getString("label.file_format_not_specified"),
1187 JvOptionPane.WARNING_MESSAGE);
1188 currentFileFormat = chooser.getSelectedFormat();
1189 value = chooser.showSaveDialog(this);
1190 if (value != JalviewFileChooser.APPROVE_OPTION)
1196 fileName = chooser.getSelectedFile().getPath();
1198 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1199 Cache.setProperty("LAST_DIRECTORY", fileName);
1200 saveAlignment(fileName, currentFileFormat);
1203 boolean lastSaveSuccessful = false;
1205 FileFormatI lastFormatSaved;
1207 String lastFilenameSaved;
1210 * Raise a dialog or status message for the last call to saveAlignment.
1212 * @return true if last call to saveAlignment(file, format) was successful.
1214 public boolean isSaveAlignmentSuccessful()
1217 if (!lastSaveSuccessful)
1219 if (!Platform.isHeadless())
1221 JvOptionPane.showInternalMessageDialog(this, MessageManager
1222 .formatMessage("label.couldnt_save_file", new Object[]
1223 { lastFilenameSaved }),
1224 MessageManager.getString("label.error_saving_file"),
1225 JvOptionPane.WARNING_MESSAGE);
1229 Console.error(MessageManager
1230 .formatMessage("label.couldnt_save_file", new Object[]
1231 { lastFilenameSaved }));
1237 setStatus(MessageManager.formatMessage(
1238 "label.successfully_saved_to_file_in_format", new Object[]
1239 { lastFilenameSaved, lastFormatSaved }));
1242 return lastSaveSuccessful;
1246 * Saves the alignment to the specified file path, in the specified format,
1247 * which may be an alignment format, or Jalview project format. If the
1248 * alignment has hidden regions, or the format is one capable of including
1249 * non-sequence data (features, annotations, groups), then the user may be
1250 * prompted to specify what to include in the output.
1255 public void saveAlignment(String file, FileFormatI format)
1257 saveAlignment(file, format, false, false);
1260 public void saveAlignment(String file, FileFormatI format, boolean stdout,
1261 boolean forceBackup)
1263 lastSaveSuccessful = true;
1266 lastFilenameSaved = file;
1268 lastFormatSaved = format;
1270 if (FileFormat.Jalview.equals(format))
1272 String shortName = title;
1273 if (shortName.indexOf(File.separatorChar) > -1)
1275 shortName = shortName
1276 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1278 // TODO deal with stdout=true
1279 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1282 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1283 if (lastSaveSuccessful)
1285 this.getViewport().setSavedUpToDate(true);
1288 statusBar.setText(MessageManager.formatMessage(
1289 "label.successfully_saved_to_file_in_format", new Object[]
1295 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1296 Runnable cancelAction = () -> {
1297 lastSaveSuccessful = false;
1299 Runnable outputAction = () -> {
1300 // todo defer this to inside formatSequences (or later)
1301 AlignmentExportData exportData = viewport.getAlignExportData(options);
1302 String output = new FormatAdapter(alignPanel, options)
1303 .formatSequences(format, exportData.getAlignment(),
1304 exportData.getOmitHidden(),
1305 exportData.getStartEndPostions(),
1306 viewport.getAlignment().getHiddenColumns());
1309 lastSaveSuccessful = false;
1313 // create backupfiles object and get new temp filename destination
1314 boolean doBackup = forceBackup
1315 || (BackupFiles.getEnabled() && !stdout);
1316 BackupFiles backupfiles = null;
1319 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1320 backupfiles = new BackupFiles(file);
1324 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1326 Console.trace("ALIGNFRAME setting PrintWriter");
1327 PrintWriter out = stdout
1328 ? new PrintWriter(new OutputStreamWriter(System.out))
1329 : new PrintWriter(new FileWriter(tempFilePath));
1331 if (backupfiles != null)
1333 Console.trace("ALIGNFRAME about to write to temp file "
1334 + backupfiles.getTempFilePath());
1341 Console.trace("ALIGNFRAME about to close file");
1343 Console.trace("ALIGNFRAME closed file");
1345 AlignFrame.this.setTitle(stdout ? "STDOUT" : file);
1348 statusBar.setText(MessageManager.formatMessage(
1349 "label.successfully_printed_to_stdout_in_format",
1351 { format.getName() }));
1355 statusBar.setText(MessageManager.formatMessage(
1356 "label.successfully_saved_to_file_in_format",
1358 { fileName, format.getName() }));
1360 lastSaveSuccessful = true;
1361 } catch (IOException e)
1363 lastSaveSuccessful = false;
1365 "ALIGNFRAME Something happened writing the temp file");
1366 Console.error(e.getMessage());
1367 Console.debug(Cache.getStackTraceString(e));
1368 } catch (Exception ex)
1370 lastSaveSuccessful = false;
1372 "ALIGNFRAME Something unexpected happened writing the temp file");
1373 Console.error(ex.getMessage());
1374 Console.debug(Cache.getStackTraceString(ex));
1379 backupfiles.setWriteSuccess(lastSaveSuccessful);
1380 Console.debug("ALIGNFRAME writing temp file was "
1381 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1382 // do the backup file roll and rename the temp file to actual file
1383 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1384 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1385 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1386 + (lastSaveSuccessful ? "" : "un") + "successfully");
1389 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1390 if (lastSaveSuccessful)
1392 AlignFrame.this.getViewport().setSavedUpToDate(true);
1398 * show dialog with export options if applicable; else just do it
1400 if (AlignExportOptions.isNeeded(viewport, format))
1402 AlignExportOptions choices = new AlignExportOptions(
1403 alignPanel.getAlignViewport(), format, options);
1404 choices.setResponseAction(0, outputAction);
1405 choices.setResponseAction(1, cancelAction);
1406 choices.showDialog();
1413 } catch (Exception e)
1415 // TODO Auto-generated catch block
1416 e.printStackTrace();
1422 * Outputs the alignment to textbox in the requested format, if necessary
1423 * first prompting the user for whether to include hidden regions or
1426 * @param fileFormatName
1429 protected void outputText_actionPerformed(String fileFormatName)
1431 FileFormatI fileFormat = FileFormats.getInstance()
1432 .forName(fileFormatName);
1433 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1434 Runnable outputAction = () -> {
1435 // todo defer this to inside formatSequences (or later)
1436 AlignmentExportData exportData = viewport.getAlignExportData(options);
1437 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1438 cap.setForInput(null);
1441 FileFormatI format = fileFormat;
1442 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1443 format, exportData.getAlignment(),
1444 exportData.getOmitHidden(),
1445 exportData.getStartEndPostions(),
1446 viewport.getAlignment().getHiddenColumns()));
1447 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1448 "label.alignment_output_command", new Object[]
1449 { fileFormat.getName() }), 600, 500);
1450 } catch (OutOfMemoryError oom)
1452 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1459 * show dialog with export options if applicable; else just do it
1461 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1463 AlignExportOptions choices = new AlignExportOptions(
1464 alignPanel.getAlignViewport(), fileFormat, options);
1465 choices.setResponseAction(0, outputAction);
1466 choices.showDialog();
1473 } catch (Exception e)
1475 e.printStackTrace();
1487 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1489 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1492 htmlSVG.exportHTML(null);
1493 } catch (ImageOutputException x)
1495 // report problem to console and raise dialog
1500 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1502 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1505 bjs.exportHTML(null);
1506 } catch (ImageOutputException x)
1508 // report problem to console and raise dialog
1512 public void createImageMap(File file, String image)
1516 alignPanel.makePNGImageMap(file, image);
1517 } catch (ImageOutputException x)
1519 // report problem to console and raise dialog
1524 public void createPNG_actionPerformed(ActionEvent e)
1529 } catch (ImageOutputException ioex)
1531 // raise dialog, and report via console
1536 public void createEPS_actionPerformed(ActionEvent e)
1541 } catch (ImageOutputException ioex)
1543 // raise dialog, and report via console
1549 public void createSVG_actionPerformed(ActionEvent e)
1554 } catch (ImageOutputException ioex)
1556 // raise dialog, and report via console
1562 * Creates a PNG image of the alignment and writes it to the given file. If
1563 * the file is null, the user is prompted to choose a file.
1567 public void createPNG(File f) throws ImageOutputException
1569 createPNG(f, null, BitmapImageSizing.defaultBitmapImageSizing());
1572 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1573 throws ImageOutputException
1575 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1579 * Creates an EPS image of the alignment and writes it to the given file. If
1580 * the file is null, the user is prompted to choose a file.
1584 public void createEPS(File f) throws ImageOutputException
1589 public void createEPS(File f, String renderer) throws ImageOutputException
1591 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1595 * Creates an SVG image of the alignment and writes it to the given file. If
1596 * the file is null, the user is prompted to choose a file.
1600 public void createSVG(File f) throws ImageOutputException
1605 public void createSVG(File f, String renderer) throws ImageOutputException
1607 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1611 public void pageSetup_actionPerformed(ActionEvent e)
1613 PrinterJob printJob = PrinterJob.getPrinterJob();
1614 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1624 public void printMenuItem_actionPerformed(ActionEvent e)
1626 // Putting in a thread avoids Swing painting problems
1627 PrintThread thread = new PrintThread(alignPanel);
1632 public void exportFeatures_actionPerformed(ActionEvent e)
1634 new AnnotationExporter(alignPanel).exportFeatures();
1638 public void exportAnnotations_actionPerformed(ActionEvent e)
1640 new AnnotationExporter(alignPanel).exportAnnotations();
1644 public void associatedData_actionPerformed(ActionEvent e)
1646 final JalviewFileChooser chooser = new JalviewFileChooser(
1647 Cache.getProperty("LAST_DIRECTORY"));
1648 chooser.setFileView(new JalviewFileView());
1649 String tooltip = MessageManager
1650 .getString("label.load_jalview_annotations");
1651 chooser.setDialogTitle(tooltip);
1652 chooser.setToolTipText(tooltip);
1653 chooser.setResponseHandler(0, () -> {
1654 String choice = chooser.getSelectedFile().getPath();
1655 Cache.setProperty("LAST_DIRECTORY", choice);
1656 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1659 chooser.showOpenDialog(this);
1663 * Close the current view or all views in the alignment frame. If the frame
1664 * only contains one view then the alignment will be removed from memory.
1666 * @param closeAllTabs
1669 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1671 if (alignPanels != null && alignPanels.size() < 2)
1673 closeAllTabs = true;
1676 Desktop.closeModal(this);
1680 if (alignPanels != null)
1684 if (this.isClosed())
1686 // really close all the windows - otherwise wait till
1687 // setClosed(true) is called
1688 for (int i = 0; i < alignPanels.size(); i++)
1690 AlignmentPanel ap = alignPanels.get(i);
1697 closeView(alignPanel);
1702 if (featureSettings != null && featureSettings.isOpen())
1704 featureSettings.close();
1705 featureSettings = null;
1709 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1710 * be called recursively, with the frame now in 'closed' state
1712 this.setClosed(true);
1714 } catch (Exception ex)
1716 ex.printStackTrace();
1721 * Close the specified panel and close up tabs appropriately.
1723 * @param panelToClose
1725 public void closeView(AlignmentPanel panelToClose)
1727 int index = tabbedPane.getSelectedIndex();
1728 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1729 alignPanels.remove(panelToClose);
1730 panelToClose.closePanel();
1731 panelToClose = null;
1733 tabbedPane.removeTabAt(closedindex);
1734 tabbedPane.validate();
1736 if (index > closedindex || index == tabbedPane.getTabCount())
1738 // modify currently selected tab index if necessary.
1742 this.tabSelectionChanged(index);
1748 void updateEditMenuBar()
1751 if (viewport.getHistoryList().size() > 0)
1753 undoMenuItem.setEnabled(true);
1754 CommandI command = viewport.getHistoryList().peek();
1755 undoMenuItem.setText(MessageManager
1756 .formatMessage("label.undo_command", new Object[]
1757 { command.getDescription() }));
1761 undoMenuItem.setEnabled(false);
1762 undoMenuItem.setText(MessageManager.getString("action.undo"));
1765 if (viewport.getRedoList().size() > 0)
1767 redoMenuItem.setEnabled(true);
1769 CommandI command = viewport.getRedoList().peek();
1770 redoMenuItem.setText(MessageManager
1771 .formatMessage("label.redo_command", new Object[]
1772 { command.getDescription() }));
1776 redoMenuItem.setEnabled(false);
1777 redoMenuItem.setText(MessageManager.getString("action.redo"));
1782 public void addHistoryItem(CommandI command)
1784 if (command.getSize() > 0)
1786 viewport.addToHistoryList(command);
1787 viewport.clearRedoList();
1788 updateEditMenuBar();
1789 viewport.updateHiddenColumns();
1790 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1791 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1792 // viewport.getColumnSelection()
1793 // .getHiddenColumns().size() > 0);
1799 * @return alignment objects for all views
1801 public AlignmentI[] getViewAlignments()
1803 if (alignPanels != null)
1805 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1807 for (AlignmentPanel ap : alignPanels)
1809 als[i++] = ap.av.getAlignment();
1813 if (viewport != null)
1815 return new AlignmentI[] { viewport.getAlignment() };
1827 protected void undoMenuItem_actionPerformed(ActionEvent e)
1829 if (viewport.getHistoryList().isEmpty())
1833 CommandI command = viewport.getHistoryList().pop();
1834 viewport.addToRedoList(command);
1835 command.undoCommand(getViewAlignments());
1837 AlignmentViewport originalSource = getOriginatingSource(command);
1838 updateEditMenuBar();
1840 if (originalSource != null)
1842 if (originalSource != viewport)
1845 "Implementation worry: mismatch of viewport origin for undo");
1847 originalSource.updateHiddenColumns();
1848 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1850 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1851 // viewport.getColumnSelection()
1852 // .getHiddenColumns().size() > 0);
1853 originalSource.firePropertyChange("alignment", null,
1854 originalSource.getAlignment().getSequences());
1865 protected void redoMenuItem_actionPerformed(ActionEvent e)
1867 if (viewport.getRedoList().size() < 1)
1872 CommandI command = viewport.getRedoList().pop();
1873 viewport.addToHistoryList(command);
1874 command.doCommand(getViewAlignments());
1876 AlignmentViewport originalSource = getOriginatingSource(command);
1877 updateEditMenuBar();
1879 if (originalSource != null)
1882 if (originalSource != viewport)
1885 "Implementation worry: mismatch of viewport origin for redo");
1887 originalSource.updateHiddenColumns();
1888 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1890 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1891 // viewport.getColumnSelection()
1892 // .getHiddenColumns().size() > 0);
1893 originalSource.firePropertyChange("alignment", null,
1894 originalSource.getAlignment().getSequences());
1898 AlignmentViewport getOriginatingSource(CommandI command)
1900 AlignmentViewport originalSource = null;
1901 // For sequence removal and addition, we need to fire
1902 // the property change event FROM the viewport where the
1903 // original alignment was altered
1904 AlignmentI al = null;
1905 if (command instanceof EditCommand)
1907 EditCommand editCommand = (EditCommand) command;
1908 al = editCommand.getAlignment();
1909 List<Component> comps = PaintRefresher.components
1910 .get(viewport.getSequenceSetId());
1912 for (Component comp : comps)
1914 if (comp instanceof AlignmentPanel)
1916 if (al == ((AlignmentPanel) comp).av.getAlignment())
1918 originalSource = ((AlignmentPanel) comp).av;
1925 if (originalSource == null)
1927 // The original view is closed, we must validate
1928 // the current view against the closed view first
1931 PaintRefresher.validateSequences(al, viewport.getAlignment());
1934 originalSource = viewport;
1937 return originalSource;
1941 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1942 * or the sequence under cursor in keyboard mode
1947 public void moveSelectedSequences(boolean up)
1949 SequenceGroup sg = viewport.getSelectionGroup();
1953 if (viewport.cursorMode)
1955 sg = new SequenceGroup();
1956 sg.addSequence(viewport.getAlignment().getSequenceAt(
1957 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1965 if (sg.getSize() < 1)
1970 // TODO: JAL-3733 - add an event to the undo buffer for this !
1972 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1973 viewport.getHiddenRepSequences(), up);
1974 alignPanel.paintAlignment(true, false);
1977 synchronized void slideSequences(boolean right, int size)
1979 List<SequenceI> sg = new ArrayList<>();
1980 if (viewport.cursorMode)
1982 sg.add(viewport.getAlignment()
1983 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1985 else if (viewport.getSelectionGroup() != null
1986 && viewport.getSelectionGroup().getSize() != viewport
1987 .getAlignment().getHeight())
1989 sg = viewport.getSelectionGroup()
1990 .getSequences(viewport.getHiddenRepSequences());
1998 List<SequenceI> invertGroup = new ArrayList<>();
2000 for (SequenceI seq : viewport.getAlignment().getSequences())
2002 if (!sg.contains(seq))
2004 invertGroup.add(seq);
2008 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
2010 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
2011 for (int i = 0; i < invertGroup.size(); i++)
2013 seqs2[i] = invertGroup.get(i);
2016 SlideSequencesCommand ssc;
2019 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
2020 viewport.getGapCharacter());
2024 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
2025 viewport.getGapCharacter());
2028 int groupAdjustment = 0;
2029 if (ssc.getGapsInsertedBegin() && right)
2031 if (viewport.cursorMode)
2033 alignPanel.getSeqPanel().moveCursor(size, 0);
2037 groupAdjustment = size;
2040 else if (!ssc.getGapsInsertedBegin() && !right)
2042 if (viewport.cursorMode)
2044 alignPanel.getSeqPanel().moveCursor(-size, 0);
2048 groupAdjustment = -size;
2052 if (groupAdjustment != 0)
2054 viewport.getSelectionGroup().setStartRes(
2055 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2056 viewport.getSelectionGroup().setEndRes(
2057 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2061 * just extend the last slide command if compatible; but not if in
2062 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2064 boolean appendHistoryItem = false;
2065 Deque<CommandI> historyList = viewport.getHistoryList();
2066 boolean inSplitFrame = getSplitViewContainer() != null;
2067 if (!inSplitFrame && historyList != null && historyList.size() > 0
2068 && historyList.peek() instanceof SlideSequencesCommand)
2070 appendHistoryItem = ssc.appendSlideCommand(
2071 (SlideSequencesCommand) historyList.peek());
2074 if (!appendHistoryItem)
2076 addHistoryItem(ssc);
2089 protected void copy_actionPerformed()
2091 if (viewport.getSelectionGroup() == null)
2095 // TODO: preserve the ordering of displayed alignment annotation in any
2096 // internal paste (particularly sequence associated annotation)
2097 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2098 String[] omitHidden = null;
2100 if (viewport.hasHiddenColumns())
2102 omitHidden = viewport.getViewAsString(true);
2105 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2106 seqs, omitHidden, null);
2108 StringSelection ss = new StringSelection(output);
2112 jalview.gui.Desktop.internalCopy = true;
2113 // Its really worth setting the clipboard contents
2114 // to empty before setting the large StringSelection!!
2115 Toolkit.getDefaultToolkit().getSystemClipboard()
2116 .setContents(new StringSelection(""), null);
2118 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2120 } catch (OutOfMemoryError er)
2122 new OOMWarning("copying region", er);
2126 HiddenColumns hiddenColumns = null;
2127 if (viewport.hasHiddenColumns())
2129 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2130 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2132 // create new HiddenColumns object with copy of hidden regions
2133 // between startRes and endRes, offset by startRes
2134 hiddenColumns = new HiddenColumns(
2135 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2136 hiddenCutoff, hiddenOffset);
2139 Desktop.jalviewClipboard = new Object[] { seqs,
2140 viewport.getAlignment().getDataset(), hiddenColumns };
2141 setStatus(MessageManager.formatMessage(
2142 "label.copied_sequences_to_clipboard", new Object[]
2143 { Integer.valueOf(seqs.length).toString() }));
2153 protected void pasteNew_actionPerformed(ActionEvent e)
2165 protected void pasteThis_actionPerformed(ActionEvent e)
2171 * Paste contents of Jalview clipboard
2173 * @param newAlignment
2174 * true to paste to a new alignment, otherwise add to this.
2176 void paste(boolean newAlignment)
2178 boolean externalPaste = true;
2181 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2182 Transferable contents = c.getContents(this);
2184 if (contents == null)
2193 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2194 if (str.length() < 1)
2199 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2201 } catch (OutOfMemoryError er)
2203 new OOMWarning("Out of memory pasting sequences!!", er);
2207 SequenceI[] sequences;
2208 boolean annotationAdded = false;
2209 AlignmentI alignment = null;
2211 if (Desktop.jalviewClipboard != null)
2213 // The clipboard was filled from within Jalview, we must use the
2215 // And dataset from the copied alignment
2216 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2217 // be doubly sure that we create *new* sequence objects.
2218 sequences = new SequenceI[newseq.length];
2219 for (int i = 0; i < newseq.length; i++)
2221 sequences[i] = new Sequence(newseq[i]);
2223 alignment = new Alignment(sequences);
2224 externalPaste = false;
2228 // parse the clipboard as an alignment.
2229 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2231 sequences = alignment.getSequencesArray();
2235 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2241 if (Desktop.jalviewClipboard != null)
2243 // dataset is inherited
2244 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2248 // new dataset is constructed
2249 alignment.setDataset(null);
2251 alwidth = alignment.getWidth() + 1;
2255 AlignmentI pastedal = alignment; // preserve pasted alignment object
2256 // Add pasted sequences and dataset into existing alignment.
2257 alignment = viewport.getAlignment();
2258 alwidth = alignment.getWidth() + 1;
2259 // decide if we need to import sequences from an existing dataset
2260 boolean importDs = Desktop.jalviewClipboard != null
2261 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2262 // importDs==true instructs us to copy over new dataset sequences from
2263 // an existing alignment
2264 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2266 // minimum dataset set
2268 for (int i = 0; i < sequences.length; i++)
2272 newDs.addElement(null);
2274 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2276 if (importDs && ds != null)
2278 if (!newDs.contains(ds))
2280 newDs.setElementAt(ds, i);
2281 ds = new Sequence(ds);
2282 // update with new dataset sequence
2283 sequences[i].setDatasetSequence(ds);
2287 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2292 // copy and derive new dataset sequence
2293 sequences[i] = sequences[i].deriveSequence();
2294 alignment.getDataset()
2295 .addSequence(sequences[i].getDatasetSequence());
2296 // TODO: avoid creation of duplicate dataset sequences with a
2297 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2299 alignment.addSequence(sequences[i]); // merges dataset
2303 newDs.clear(); // tidy up
2305 if (alignment.getAlignmentAnnotation() != null)
2307 for (AlignmentAnnotation alan : alignment
2308 .getAlignmentAnnotation())
2310 if (alan.graphGroup > fgroup)
2312 fgroup = alan.graphGroup;
2316 if (pastedal.getAlignmentAnnotation() != null)
2318 // Add any annotation attached to alignment.
2319 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2320 for (int i = 0; i < alann.length; i++)
2322 annotationAdded = true;
2323 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2325 AlignmentAnnotation newann = new AlignmentAnnotation(
2327 if (newann.graphGroup > -1)
2329 if (newGraphGroups.size() <= newann.graphGroup
2330 || newGraphGroups.get(newann.graphGroup) == null)
2332 for (int q = newGraphGroups
2333 .size(); q <= newann.graphGroup; q++)
2335 newGraphGroups.add(q, null);
2337 newGraphGroups.set(newann.graphGroup,
2338 Integer.valueOf(++fgroup));
2340 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2344 newann.padAnnotation(alwidth);
2345 alignment.addAnnotation(newann);
2355 addHistoryItem(new EditCommand(
2356 MessageManager.getString("label.add_sequences"),
2357 Action.PASTE, sequences, 0, alignment.getWidth(),
2360 // Add any annotations attached to sequences
2361 for (int i = 0; i < sequences.length; i++)
2363 if (sequences[i].getAnnotation() != null)
2365 AlignmentAnnotation newann;
2366 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2368 annotationAdded = true;
2369 newann = sequences[i].getAnnotation()[a];
2370 newann.adjustForAlignment();
2371 newann.padAnnotation(alwidth);
2372 if (newann.graphGroup > -1)
2374 if (newann.graphGroup > -1)
2376 if (newGraphGroups.size() <= newann.graphGroup
2377 || newGraphGroups.get(newann.graphGroup) == null)
2379 for (int q = newGraphGroups
2380 .size(); q <= newann.graphGroup; q++)
2382 newGraphGroups.add(q, null);
2384 newGraphGroups.set(newann.graphGroup,
2385 Integer.valueOf(++fgroup));
2387 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2391 // annotation was duplicated earlier
2392 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2393 // take care of contact matrix too
2394 ContactMatrixI cm = sequences[i]
2395 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2398 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2402 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2410 // propagate alignment changed.
2411 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2412 if (annotationAdded)
2414 // Duplicate sequence annotation in all views.
2415 AlignmentI[] alview = this.getViewAlignments();
2416 for (int i = 0; i < sequences.length; i++)
2418 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2423 for (int avnum = 0; avnum < alview.length; avnum++)
2425 if (alview[avnum] != alignment)
2427 // duplicate in a view other than the one with input focus
2428 int avwidth = alview[avnum].getWidth() + 1;
2429 // this relies on sann being preserved after we
2430 // modify the sequence's annotation array for each duplication
2431 for (int a = 0; a < sann.length; a++)
2433 AlignmentAnnotation newann = new AlignmentAnnotation(
2435 sequences[i].addAlignmentAnnotation(newann);
2436 newann.padAnnotation(avwidth);
2437 alview[avnum].addAnnotation(newann); // annotation was
2438 // duplicated earlier
2439 // TODO JAL-1145 graphGroups are not updated for sequence
2440 // annotation added to several views. This may cause
2442 alview[avnum].setAnnotationIndex(newann, a);
2447 buildSortByAnnotationScoresMenu();
2449 viewport.firePropertyChange("alignment", null,
2450 alignment.getSequences());
2451 if (alignPanels != null)
2453 for (AlignmentPanel ap : alignPanels)
2455 ap.validateAnnotationDimensions(false);
2460 alignPanel.validateAnnotationDimensions(false);
2466 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2468 String newtitle = new String("Copied sequences");
2470 if (Desktop.jalviewClipboard != null
2471 && Desktop.jalviewClipboard[2] != null)
2473 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2474 af.viewport.setHiddenColumns(hc);
2477 // >>>This is a fix for the moment, until a better solution is
2479 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2480 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2481 .getFeatureRenderer());
2483 // TODO: maintain provenance of an alignment, rather than just make the
2484 // title a concatenation of operations.
2487 if (title.startsWith("Copied sequences"))
2493 newtitle = newtitle.concat("- from " + title);
2498 newtitle = new String("Pasted sequences");
2501 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2506 } catch (Exception ex)
2508 ex.printStackTrace();
2509 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2510 // could be anything being pasted in here
2516 protected void expand_newalign(ActionEvent e)
2520 AlignmentI alignment = AlignmentUtils
2521 .expandContext(getViewport().getAlignment(), -1);
2522 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2524 String newtitle = new String("Flanking alignment");
2526 if (Desktop.jalviewClipboard != null
2527 && Desktop.jalviewClipboard[2] != null)
2529 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2530 af.viewport.setHiddenColumns(hc);
2533 // >>>This is a fix for the moment, until a better solution is
2535 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2536 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2537 .getFeatureRenderer());
2539 // TODO: maintain provenance of an alignment, rather than just make the
2540 // title a concatenation of operations.
2542 if (title.startsWith("Copied sequences"))
2548 newtitle = newtitle.concat("- from " + title);
2552 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2554 } catch (Exception ex)
2556 ex.printStackTrace();
2557 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2558 // could be anything being pasted in here
2559 } catch (OutOfMemoryError oom)
2561 new OOMWarning("Viewing flanking region of alignment", oom);
2566 * Action Cut (delete and copy) the selected region
2569 protected void cut_actionPerformed()
2571 copy_actionPerformed();
2572 delete_actionPerformed();
2576 * Performs menu option to Delete the currently selected region
2579 protected void delete_actionPerformed()
2582 SequenceGroup sg = viewport.getSelectionGroup();
2588 Runnable okAction = () -> {
2589 SequenceI[] cut = sg.getSequences()
2590 .toArray(new SequenceI[sg.getSize()]);
2592 addHistoryItem(new EditCommand(
2593 MessageManager.getString("label.cut_sequences"), Action.CUT,
2594 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2595 viewport.getAlignment()));
2597 viewport.setSelectionGroup(null);
2598 viewport.sendSelection();
2599 viewport.getAlignment().deleteGroup(sg);
2601 viewport.firePropertyChange("alignment", null,
2602 viewport.getAlignment().getSequences());
2603 if (viewport.getAlignment().getHeight() < 1)
2607 AlignFrame.this.setClosed(true);
2608 } catch (Exception ex)
2615 * If the cut affects all sequences, prompt for confirmation
2617 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2619 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2620 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2621 if (wholeHeight && wholeWidth)
2623 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2624 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2625 Object[] options = new Object[] {
2626 MessageManager.getString("action.ok"),
2627 MessageManager.getString("action.cancel") };
2628 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2629 MessageManager.getString("label.delete_all"),
2630 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2631 options, options[0]);
2638 } catch (Exception e)
2640 e.printStackTrace();
2652 protected void deleteGroups_actionPerformed(ActionEvent e)
2654 if (avc.deleteGroups())
2656 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2657 alignPanel.updateAnnotation();
2658 alignPanel.paintAlignment(true, true);
2669 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2671 SequenceGroup sg = new SequenceGroup(
2672 viewport.getAlignment().getSequences());
2674 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2675 viewport.setSelectionGroup(sg);
2676 viewport.isSelectionGroupChanged(true);
2677 viewport.sendSelection();
2678 // JAL-2034 - should delegate to
2679 // alignPanel to decide if overview needs
2681 alignPanel.paintAlignment(false, false);
2682 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2692 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2694 if (viewport.cursorMode)
2696 alignPanel.getSeqPanel().keyboardNo1 = null;
2697 alignPanel.getSeqPanel().keyboardNo2 = null;
2699 viewport.setSelectionGroup(null);
2700 viewport.getColumnSelection().clear();
2701 viewport.setSearchResults(null);
2702 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2703 // JAL-2034 - should delegate to
2704 // alignPanel to decide if overview needs
2706 alignPanel.paintAlignment(false, false);
2707 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2708 viewport.sendSelection();
2718 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2720 SequenceGroup sg = viewport.getSelectionGroup();
2724 selectAllSequenceMenuItem_actionPerformed(null);
2729 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2731 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2733 // JAL-2034 - should delegate to
2734 // alignPanel to decide if overview needs
2737 alignPanel.paintAlignment(true, false);
2738 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2739 viewport.sendSelection();
2743 public void invertColSel_actionPerformed(ActionEvent e)
2745 viewport.invertColumnSelection();
2746 alignPanel.paintAlignment(true, false);
2747 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2748 viewport.sendSelection();
2758 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2760 trimAlignment(true);
2770 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2772 trimAlignment(false);
2775 void trimAlignment(boolean trimLeft)
2777 ColumnSelection colSel = viewport.getColumnSelection();
2780 if (!colSel.isEmpty())
2784 column = colSel.getMin();
2788 column = colSel.getMax();
2792 if (viewport.getSelectionGroup() != null)
2794 seqs = viewport.getSelectionGroup()
2795 .getSequencesAsArray(viewport.getHiddenRepSequences());
2799 seqs = viewport.getAlignment().getSequencesArray();
2802 TrimRegionCommand trimRegion;
2805 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2806 column, viewport.getAlignment());
2807 viewport.getRanges().setStartRes(0);
2811 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2812 column, viewport.getAlignment());
2815 setStatus(MessageManager.formatMessage("label.removed_columns",
2817 { Integer.valueOf(trimRegion.getSize()).toString() }));
2819 addHistoryItem(trimRegion);
2821 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2823 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2824 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2826 viewport.getAlignment().deleteGroup(sg);
2830 viewport.firePropertyChange("alignment", null,
2831 viewport.getAlignment().getSequences());
2842 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2844 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2847 if (viewport.getSelectionGroup() != null)
2849 seqs = viewport.getSelectionGroup()
2850 .getSequencesAsArray(viewport.getHiddenRepSequences());
2851 start = viewport.getSelectionGroup().getStartRes();
2852 end = viewport.getSelectionGroup().getEndRes();
2856 seqs = viewport.getAlignment().getSequencesArray();
2859 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2860 "Remove Gapped Columns", seqs, start, end,
2861 viewport.getAlignment());
2863 addHistoryItem(removeGapCols);
2865 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2867 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2869 // This is to maintain viewport position on first residue
2870 // of first sequence
2871 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2872 ViewportRanges ranges = viewport.getRanges();
2873 int startRes = seq.findPosition(ranges.getStartRes());
2874 // ShiftList shifts;
2875 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2876 // edit.alColumnChanges=shifts.getInverse();
2877 // if (viewport.hasHiddenColumns)
2878 // viewport.getColumnSelection().compensateForEdits(shifts);
2879 ranges.setStartRes(seq.findIndex(startRes) - 1);
2880 viewport.firePropertyChange("alignment", null,
2881 viewport.getAlignment().getSequences());
2892 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2894 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2897 if (viewport.getSelectionGroup() != null)
2899 seqs = viewport.getSelectionGroup()
2900 .getSequencesAsArray(viewport.getHiddenRepSequences());
2901 start = viewport.getSelectionGroup().getStartRes();
2902 end = viewport.getSelectionGroup().getEndRes();
2906 seqs = viewport.getAlignment().getSequencesArray();
2909 // This is to maintain viewport position on first residue
2910 // of first sequence
2911 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2912 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2914 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2915 viewport.getAlignment()));
2917 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2919 viewport.firePropertyChange("alignment", null,
2920 viewport.getAlignment().getSequences());
2931 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2933 viewport.setPadGaps(padGapsMenuitem.isSelected());
2934 viewport.firePropertyChange("alignment", null,
2935 viewport.getAlignment().getSequences());
2939 * Opens a Finder dialog
2944 public void findMenuItem_actionPerformed(ActionEvent e)
2946 new Finder(alignPanel, false, null);
2950 * Create a new view of the current alignment.
2953 public void newView_actionPerformed(ActionEvent e)
2955 newView(null, true);
2959 * Creates and shows a new view of the current alignment.
2962 * title of newly created view; if null, one will be generated
2963 * @param copyAnnotation
2964 * if true then duplicate all annnotation, groups and settings
2965 * @return new alignment panel, already displayed.
2967 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2970 * Create a new AlignmentPanel (with its own, new Viewport)
2972 AlignmentPanel newap = new jalview.project.Jalview2XML()
2973 .copyAlignPanel(alignPanel);
2974 if (!copyAnnotation)
2977 * remove all groups and annotation except for the automatic stuff
2979 newap.av.getAlignment().deleteAllGroups();
2980 newap.av.getAlignment().deleteAllAnnotations(false);
2983 newap.av.setGatherViewsHere(false);
2985 if (viewport.getViewName() == null)
2987 viewport.setViewName(
2988 MessageManager.getString("label.view_name_original"));
2992 * Views share the same edits undo and redo stacks
2994 newap.av.setHistoryList(viewport.getHistoryList());
2995 newap.av.setRedoList(viewport.getRedoList());
2998 * copy any visualisation settings that are not saved in the project
3000 newap.av.setColourAppliesToAllGroups(
3001 viewport.getColourAppliesToAllGroups());
3004 * Views share the same mappings; need to deregister any new mappings
3005 * created by copyAlignPanel, and register the new reference to the shared
3008 newap.av.replaceMappings(viewport.getAlignment());
3011 * start up cDNA consensus (if applicable) now mappings are in place
3013 if (newap.av.initComplementConsensus())
3015 newap.refresh(true); // adjust layout of annotations
3018 newap.av.setViewName(getNewViewName(viewTitle));
3020 addAlignmentPanel(newap, true);
3021 newap.alignmentChanged();
3023 if (alignPanels.size() == 2)
3025 viewport.setGatherViewsHere(true);
3027 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
3033 * Make a new name for the view, ensuring it is unique within the current
3034 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3035 * these now use viewId. Unique view names are still desirable for usability.)
3040 protected String getNewViewName(String viewTitle)
3042 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3043 boolean addFirstIndex = false;
3044 if (viewTitle == null || viewTitle.trim().length() == 0)
3046 viewTitle = MessageManager.getString("action.view");
3047 addFirstIndex = true;
3051 index = 1;// we count from 1 if given a specific name
3053 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3055 List<Component> comps = PaintRefresher.components
3056 .get(viewport.getSequenceSetId());
3058 List<String> existingNames = getExistingViewNames(comps);
3060 while (existingNames.contains(newViewName))
3062 newViewName = viewTitle + " " + (++index);
3068 * Returns a list of distinct view names found in the given list of
3069 * components. View names are held on the viewport of an AlignmentPanel.
3074 protected List<String> getExistingViewNames(List<Component> comps)
3076 List<String> existingNames = new ArrayList<>();
3077 for (Component comp : comps)
3079 if (comp instanceof AlignmentPanel)
3081 AlignmentPanel ap = (AlignmentPanel) comp;
3082 if (!existingNames.contains(ap.av.getViewName()))
3084 existingNames.add(ap.av.getViewName());
3088 return existingNames;
3092 * Explode tabbed views into separate windows.
3095 public void expandViews_actionPerformed(ActionEvent e)
3097 Desktop.explodeViews(this);
3101 * Gather views in separate windows back into a tabbed presentation.
3104 public void gatherViews_actionPerformed(ActionEvent e)
3106 Desktop.instance.gatherViews(this);
3116 public void font_actionPerformed(ActionEvent e)
3118 new FontChooser(alignPanel);
3128 protected void seqLimit_actionPerformed(ActionEvent e)
3130 viewport.setShowJVSuffix(seqLimits.isSelected());
3132 alignPanel.getIdPanel().getIdCanvas()
3133 .setPreferredSize(alignPanel.calculateIdWidth());
3134 alignPanel.paintAlignment(true, false);
3138 public void idRightAlign_actionPerformed(ActionEvent e)
3140 viewport.setRightAlignIds(idRightAlign.isSelected());
3141 alignPanel.paintAlignment(false, false);
3145 public void centreColumnLabels_actionPerformed(ActionEvent e)
3147 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3148 alignPanel.paintAlignment(false, false);
3154 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3157 protected void followHighlight_actionPerformed()
3160 * Set the 'follow' flag on the Viewport (and scroll to position if now
3163 final boolean state = this.followHighlightMenuItem.getState();
3164 viewport.setFollowHighlight(state);
3167 alignPanel.scrollToPosition(viewport.getSearchResults());
3178 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3180 viewport.setColourText(colourTextMenuItem.isSelected());
3181 alignPanel.paintAlignment(false, false);
3191 public void wrapMenuItem_actionPerformed(ActionEvent e)
3193 setWrapFormat(wrapMenuItem.isSelected(), false);
3196 public void setWrapFormat(boolean b, boolean setMenuItem)
3198 scaleAbove.setVisible(b);
3199 scaleLeft.setVisible(b);
3200 scaleRight.setVisible(b);
3201 viewport.setWrapAlignment(b);
3202 alignPanel.updateLayout();
3205 wrapMenuItem.setSelected(b);
3210 public void showAllSeqs_actionPerformed(ActionEvent e)
3212 viewport.showAllHiddenSeqs();
3216 public void showAllColumns_actionPerformed(ActionEvent e)
3218 viewport.showAllHiddenColumns();
3219 alignPanel.paintAlignment(true, true);
3220 viewport.sendSelection();
3224 public void hideSelSequences_actionPerformed(ActionEvent e)
3226 viewport.hideAllSelectedSeqs();
3230 * called by key handler and the hide all/show all menu items
3235 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3238 boolean hide = false;
3239 SequenceGroup sg = viewport.getSelectionGroup();
3240 if (!toggleSeqs && !toggleCols)
3242 // Hide everything by the current selection - this is a hack - we do the
3243 // invert and then hide
3244 // first check that there will be visible columns after the invert.
3245 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3246 && sg.getStartRes() <= sg.getEndRes()))
3248 // now invert the sequence set, if required - empty selection implies
3249 // that no hiding is required.
3252 invertSequenceMenuItem_actionPerformed(null);
3253 sg = viewport.getSelectionGroup();
3257 viewport.expandColSelection(sg, true);
3258 // finally invert the column selection and get the new sequence
3260 invertColSel_actionPerformed(null);
3267 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3269 hideSelSequences_actionPerformed(null);
3272 else if (!(toggleCols && viewport.hasSelectedColumns()))
3274 showAllSeqs_actionPerformed(null);
3280 if (viewport.hasSelectedColumns())
3282 hideSelColumns_actionPerformed(null);
3285 viewport.setSelectionGroup(sg);
3290 showAllColumns_actionPerformed(null);
3299 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3300 * event.ActionEvent)
3303 public void hideAllButSelection_actionPerformed(ActionEvent e)
3305 toggleHiddenRegions(false, false);
3306 viewport.sendSelection();
3313 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3317 public void hideAllSelection_actionPerformed(ActionEvent e)
3319 SequenceGroup sg = viewport.getSelectionGroup();
3320 viewport.expandColSelection(sg, false);
3321 viewport.hideAllSelectedSeqs();
3322 viewport.hideSelectedColumns();
3323 alignPanel.updateLayout();
3324 alignPanel.paintAlignment(true, true);
3325 viewport.sendSelection();
3332 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3336 public void showAllhidden_actionPerformed(ActionEvent e)
3338 viewport.showAllHiddenColumns();
3339 viewport.showAllHiddenSeqs();
3340 alignPanel.paintAlignment(true, true);
3341 viewport.sendSelection();
3345 public void hideSelColumns_actionPerformed(ActionEvent e)
3347 viewport.hideSelectedColumns();
3348 alignPanel.updateLayout();
3349 alignPanel.paintAlignment(true, true);
3350 viewport.sendSelection();
3354 public void hiddenMarkers_actionPerformed(ActionEvent e)
3356 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3367 protected void scaleAbove_actionPerformed(ActionEvent e)
3369 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3370 alignPanel.updateLayout();
3371 alignPanel.paintAlignment(true, false);
3381 protected void scaleLeft_actionPerformed(ActionEvent e)
3383 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3384 alignPanel.updateLayout();
3385 alignPanel.paintAlignment(true, false);
3395 protected void scaleRight_actionPerformed(ActionEvent e)
3397 viewport.setScaleRightWrapped(scaleRight.isSelected());
3398 alignPanel.updateLayout();
3399 alignPanel.paintAlignment(true, false);
3409 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3411 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3412 alignPanel.paintAlignment(false, false);
3422 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3424 viewport.setShowText(viewTextMenuItem.isSelected());
3425 alignPanel.paintAlignment(false, false);
3435 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3437 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3438 alignPanel.paintAlignment(false, false);
3441 public FeatureSettings featureSettings;
3444 public FeatureSettingsControllerI getFeatureSettingsUI()
3446 return featureSettings;
3450 public void featureSettings_actionPerformed(ActionEvent e)
3452 showFeatureSettingsUI();
3456 public FeatureSettingsControllerI showFeatureSettingsUI()
3458 if (featureSettings != null)
3460 featureSettings.closeOldSettings();
3461 featureSettings = null;
3463 if (!showSeqFeatures.isSelected())
3465 // make sure features are actually displayed
3466 showSeqFeatures.setSelected(true);
3467 showSeqFeatures_actionPerformed(null);
3469 featureSettings = new FeatureSettings(this);
3470 return featureSettings;
3474 * Set or clear 'Show Sequence Features'
3480 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3482 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3483 alignPanel.paintAlignment(true, true);
3487 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3488 * the annotations panel as a whole.
3490 * The options to show/hide all annotations should be enabled when the panel
3491 * is shown, and disabled when the panel is hidden.
3496 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3498 final boolean setVisible = annotationPanelMenuItem.isSelected();
3499 viewport.setShowAnnotation(setVisible);
3500 this.showAllSeqAnnotations.setEnabled(setVisible);
3501 this.hideAllSeqAnnotations.setEnabled(setVisible);
3502 this.showAllAlAnnotations.setEnabled(setVisible);
3503 this.hideAllAlAnnotations.setEnabled(setVisible);
3504 alignPanel.updateLayout();
3508 public void alignmentProperties()
3511 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3514 String content = MessageManager.formatMessage("label.html_content",
3516 { contents.toString() });
3519 if (Platform.isJS())
3521 JLabel textLabel = new JLabel();
3522 textLabel.setText(content);
3523 textLabel.setBackground(Color.WHITE);
3525 pane = new JPanel(new BorderLayout());
3526 ((JPanel) pane).setOpaque(true);
3527 pane.setBackground(Color.WHITE);
3528 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3537 JEditorPane editPane = new JEditorPane("text/html", "");
3538 editPane.setEditable(false);
3539 editPane.setText(content);
3543 JInternalFrame frame = new JInternalFrame();
3544 frame.setFrameIcon(null);
3545 frame.getContentPane().add(new JScrollPane(pane));
3547 Desktop.addInternalFrame(frame, MessageManager
3548 .formatMessage("label.alignment_properties", new Object[]
3549 { getTitle() }), 500, 400);
3553 * Opens an Overview panel for the alignment, unless one is open already
3558 public void overviewMenuItem_actionPerformed(ActionEvent e)
3560 boolean showHiddenRegions = Cache
3561 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3562 openOverviewPanel(showHiddenRegions);
3565 public OverviewPanel openOverviewPanel(boolean showHidden)
3567 if (alignPanel.overviewPanel != null)
3569 return alignPanel.overviewPanel;
3571 JInternalFrame frame = new JInternalFrame();
3572 frame.setFrameIcon(null);
3573 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3575 frame.setContentPane(overview);
3577 alignPanel.setOverviewPanel(overview);
3578 alignPanel.setOverviewTitle(this);
3580 Desktop.addInternalFrame(frame, overview.getTitle(), true,
3581 frame.getWidth(), frame.getHeight(), true, true);
3583 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3584 final AlignmentPanel thePanel = this.alignPanel;
3585 frame.addInternalFrameListener(
3586 new javax.swing.event.InternalFrameAdapter()
3589 public void internalFrameClosed(
3590 javax.swing.event.InternalFrameEvent evt)
3593 thePanel.setOverviewPanel(null);
3596 if (getKeyListeners().length > 0)
3598 frame.addKeyListener(getKeyListeners()[0]);
3605 public void textColour_actionPerformed()
3607 new TextColourChooser().chooseColour(alignPanel, null);
3611 * public void covariationColour_actionPerformed() {
3613 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3617 public void annotationColour_actionPerformed()
3619 new AnnotationColourChooser(viewport, alignPanel);
3623 public void annotationColumn_actionPerformed(ActionEvent e)
3625 new AnnotationColumnChooser(viewport, alignPanel);
3629 * Action on the user checking or unchecking the option to apply the selected
3630 * colour scheme to all groups. If unchecked, groups may have their own
3631 * independent colour schemes.
3636 public void applyToAllGroups_actionPerformed(boolean selected)
3638 viewport.setColourAppliesToAllGroups(selected);
3642 * Action on user selecting a colour from the colour menu
3645 * the name (not the menu item label!) of the colour scheme
3648 public void changeColour_actionPerformed(String name)
3651 * 'User Defined' opens a panel to configure or load a
3652 * user-defined colour scheme
3654 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3656 new UserDefinedColours(alignPanel);
3661 * otherwise set the chosen colour scheme (or null for 'None')
3663 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3664 viewport, viewport.getAlignment(),
3665 viewport.getHiddenRepSequences());
3670 * Actions on setting or changing the alignment colour scheme
3675 public void changeColour(ColourSchemeI cs)
3677 // TODO: pull up to controller method
3678 ColourMenuHelper.setColourSelected(colourMenu, cs);
3680 viewport.setGlobalColourScheme(cs);
3682 alignPanel.paintAlignment(true, true);
3686 * Show the PID threshold slider panel
3689 protected void modifyPID_actionPerformed()
3691 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3692 alignPanel.getViewName());
3693 SliderPanel.showPIDSlider();
3697 * Show the Conservation slider panel
3700 protected void modifyConservation_actionPerformed()
3702 SliderPanel.setConservationSlider(alignPanel,
3703 viewport.getResidueShading(), alignPanel.getViewName());
3704 SliderPanel.showConservationSlider();
3708 * Action on selecting or deselecting (Colour) By Conservation
3711 public void conservationMenuItem_actionPerformed(boolean selected)
3713 modifyConservation.setEnabled(selected);
3714 viewport.setConservationSelected(selected);
3715 viewport.getResidueShading().setConservationApplied(selected);
3717 changeColour(viewport.getGlobalColourScheme());
3720 modifyConservation_actionPerformed();
3724 SliderPanel.hideConservationSlider();
3729 * Action on selecting or deselecting (Colour) Above PID Threshold
3732 public void abovePIDThreshold_actionPerformed(boolean selected)
3734 modifyPID.setEnabled(selected);
3735 viewport.setAbovePIDThreshold(selected);
3738 viewport.getResidueShading().setThreshold(0,
3739 viewport.isIgnoreGapsConsensus());
3742 changeColour(viewport.getGlobalColourScheme());
3745 modifyPID_actionPerformed();
3749 SliderPanel.hidePIDSlider();
3760 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3762 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3763 AlignmentSorter.sortByPID(viewport.getAlignment(),
3764 viewport.getAlignment().getSequenceAt(0));
3765 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3766 viewport.getAlignment()));
3767 alignPanel.paintAlignment(true, false);
3777 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3779 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3780 AlignmentSorter.sortByID(viewport.getAlignment());
3782 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3783 alignPanel.paintAlignment(true, false);
3793 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3795 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3796 AlignmentSorter.sortByLength(viewport.getAlignment());
3797 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3798 viewport.getAlignment()));
3799 alignPanel.paintAlignment(true, false);
3809 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3811 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3812 AlignmentSorter.sortByGroup(viewport.getAlignment());
3813 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3814 viewport.getAlignment()));
3816 alignPanel.paintAlignment(true, false);
3826 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3828 new RedundancyPanel(alignPanel, this);
3838 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3840 if ((viewport.getSelectionGroup() == null)
3841 || (viewport.getSelectionGroup().getSize() < 2))
3843 JvOptionPane.showInternalMessageDialog(this,
3844 MessageManager.getString(
3845 "label.you_must_select_least_two_sequences"),
3846 MessageManager.getString("label.invalid_selection"),
3847 JvOptionPane.WARNING_MESSAGE);
3851 JInternalFrame frame = new JInternalFrame();
3852 frame.setFrameIcon(null);
3853 frame.setContentPane(new PairwiseAlignPanel(viewport));
3854 Desktop.addInternalFrame(frame,
3855 MessageManager.getString("action.pairwise_alignment"), 600,
3861 public void autoCalculate_actionPerformed(ActionEvent e)
3863 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3864 if (viewport.autoCalculateConsensus)
3866 viewport.firePropertyChange("alignment", null,
3867 viewport.getAlignment().getSequences());
3872 public void sortByTreeOption_actionPerformed(ActionEvent e)
3874 viewport.sortByTree = sortByTree.isSelected();
3878 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3880 viewport.followSelection = listenToViewSelections.isSelected();
3884 * Constructs a tree panel and adds it to the desktop
3887 * tree type (NJ or AV)
3889 * name of score model used to compute the tree
3891 * parameters for the distance or similarity calculation
3893 void newTreePanel(String type, String modelName,
3894 SimilarityParamsI options)
3896 String frameTitle = "";
3899 boolean onSelection = false;
3900 if (viewport.getSelectionGroup() != null
3901 && viewport.getSelectionGroup().getSize() > 0)
3903 SequenceGroup sg = viewport.getSelectionGroup();
3905 /* Decide if the selection is a column region */
3906 for (SequenceI _s : sg.getSequences())
3908 if (_s.getLength() < sg.getEndRes())
3910 JvOptionPane.showMessageDialog(Desktop.desktop,
3911 MessageManager.getString(
3912 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3913 MessageManager.getString(
3914 "label.sequences_selection_not_aligned"),
3915 JvOptionPane.WARNING_MESSAGE);
3924 if (viewport.getAlignment().getHeight() < 2)
3930 tp = new TreePanel(alignPanel, type, modelName, options);
3931 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3933 frameTitle += " from ";
3935 if (viewport.getViewName() != null)
3937 frameTitle += viewport.getViewName() + " of ";
3940 frameTitle += this.title;
3942 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3953 public void addSortByOrderMenuItem(String title,
3954 final AlignmentOrder order)
3956 final JMenuItem item = new JMenuItem(MessageManager
3957 .formatMessage("action.by_title_param", new Object[]
3960 item.addActionListener(new java.awt.event.ActionListener()
3963 public void actionPerformed(ActionEvent e)
3965 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3967 // TODO: JBPNote - have to map order entries to curent SequenceI
3969 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3971 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3972 viewport.getAlignment()));
3974 alignPanel.paintAlignment(true, false);
3980 * Add a new sort by annotation score menu item
3983 * the menu to add the option to
3985 * the label used to retrieve scores for each sequence on the
3988 public void addSortByAnnotScoreMenuItem(JMenu sort,
3989 final String scoreLabel)
3991 final JMenuItem item = new JMenuItem(scoreLabel);
3993 item.addActionListener(new java.awt.event.ActionListener()
3996 public void actionPerformed(ActionEvent e)
3998 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3999 AlignmentSorter.sortByAnnotationScore(scoreLabel,
4000 viewport.getAlignment());// ,viewport.getSelectionGroup());
4001 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
4002 viewport.getAlignment()));
4003 alignPanel.paintAlignment(true, false);
4009 * last hash for alignment's annotation array - used to minimise cost of
4012 protected int _annotationScoreVectorHash;
4015 * search the alignment and rebuild the sort by annotation score submenu the
4016 * last alignment annotation vector hash is stored to minimize cost of
4017 * rebuilding in subsequence calls.
4021 public void buildSortByAnnotationScoresMenu()
4023 if (viewport.getAlignment().getAlignmentAnnotation() == null)
4028 if (viewport.getAlignment().getAlignmentAnnotation()
4029 .hashCode() != _annotationScoreVectorHash)
4031 sortByAnnotScore.removeAll();
4032 // almost certainly a quicker way to do this - but we keep it simple
4033 Hashtable<String, String> scoreSorts = new Hashtable<>();
4034 AlignmentAnnotation aann[];
4035 for (SequenceI sqa : viewport.getAlignment().getSequences())
4037 aann = sqa.getAnnotation();
4038 for (int i = 0; aann != null && i < aann.length; i++)
4040 if (aann[i].hasScore() && aann[i].sequenceRef != null)
4042 scoreSorts.put(aann[i].label, aann[i].label);
4046 Enumeration<String> labels = scoreSorts.keys();
4047 while (labels.hasMoreElements())
4049 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4051 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4054 _annotationScoreVectorHash = viewport.getAlignment()
4055 .getAlignmentAnnotation().hashCode();
4060 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4061 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4062 * call. Listeners are added to remove the menu item when the treePanel is
4063 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4067 public void buildTreeSortMenu()
4069 sortByTreeMenu.removeAll();
4071 List<Component> comps = PaintRefresher.components
4072 .get(viewport.getSequenceSetId());
4073 List<TreePanel> treePanels = new ArrayList<>();
4074 for (Component comp : comps)
4076 if (comp instanceof TreePanel)
4078 treePanels.add((TreePanel) comp);
4082 if (treePanels.size() < 1)
4084 sortByTreeMenu.setVisible(false);
4088 sortByTreeMenu.setVisible(true);
4090 for (final TreePanel tp : treePanels)
4092 final JMenuItem item = new JMenuItem(tp.getTitle());
4093 item.addActionListener(new java.awt.event.ActionListener()
4096 public void actionPerformed(ActionEvent e)
4098 tp.sortByTree_actionPerformed();
4099 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4104 sortByTreeMenu.add(item);
4108 public boolean sortBy(AlignmentOrder alorder, String undoname)
4110 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4111 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4112 if (undoname != null)
4114 addHistoryItem(new OrderCommand(undoname, oldOrder,
4115 viewport.getAlignment()));
4117 alignPanel.paintAlignment(true, false);
4122 * Work out whether the whole set of sequences or just the selected set will
4123 * be submitted for multiple alignment.
4126 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4128 // Now, check we have enough sequences
4129 AlignmentView msa = null;
4131 if ((viewport.getSelectionGroup() != null)
4132 && (viewport.getSelectionGroup().getSize() > 1))
4134 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4135 // some common interface!
4137 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4138 * SequenceI[sz = seqs.getSize(false)];
4140 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4141 * seqs.getSequenceAt(i); }
4143 msa = viewport.getAlignmentView(true);
4145 else if (viewport.getSelectionGroup() != null
4146 && viewport.getSelectionGroup().getSize() == 1)
4148 int option = JvOptionPane.showConfirmDialog(this,
4149 MessageManager.getString("warn.oneseq_msainput_selection"),
4150 MessageManager.getString("label.invalid_selection"),
4151 JvOptionPane.OK_CANCEL_OPTION);
4152 if (option == JvOptionPane.OK_OPTION)
4154 msa = viewport.getAlignmentView(false);
4159 msa = viewport.getAlignmentView(false);
4165 * Decides what is submitted to a secondary structure prediction service: the
4166 * first sequence in the alignment, or in the current selection, or, if the
4167 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4168 * region or the whole alignment. (where the first sequence in the set is the
4169 * one that the prediction will be for).
4171 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4173 AlignmentView seqs = null;
4175 if ((viewport.getSelectionGroup() != null)
4176 && (viewport.getSelectionGroup().getSize() > 0))
4178 seqs = viewport.getAlignmentView(true);
4182 seqs = viewport.getAlignmentView(false);
4184 // limit sequences - JBPNote in future - could spawn multiple prediction
4186 // TODO: viewport.getAlignment().isAligned is a global state - the local
4187 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4188 if (!viewport.getAlignment().isAligned(false))
4190 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4191 // TODO: if seqs.getSequences().length>1 then should really have warned
4205 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4207 // Pick the tree file
4208 JalviewFileChooser chooser = new JalviewFileChooser(
4209 Cache.getProperty("LAST_DIRECTORY"));
4210 chooser.setFileView(new JalviewFileView());
4211 chooser.setDialogTitle(
4212 MessageManager.getString("label.select_newick_like_tree_file"));
4213 chooser.setToolTipText(
4214 MessageManager.getString("label.load_tree_file"));
4216 chooser.setResponseHandler(0, () -> {
4217 String filePath = chooser.getSelectedFile().getPath();
4218 Cache.setProperty("LAST_DIRECTORY", filePath);
4219 NewickFile fin = null;
4222 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4223 DataSourceType.FILE));
4224 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4225 } catch (Exception ex)
4227 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4228 MessageManager.getString("label.problem_reading_tree_file"),
4229 JvOptionPane.WARNING_MESSAGE);
4230 ex.printStackTrace();
4232 if (fin != null && fin.hasWarningMessage())
4234 JvOptionPane.showMessageDialog(Desktop.desktop,
4235 fin.getWarningMessage(),
4237 .getString("label.possible_problem_with_tree_file"),
4238 JvOptionPane.WARNING_MESSAGE);
4241 chooser.showOpenDialog(this);
4244 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4246 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4249 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4250 int h, int x, int y)
4252 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4256 * Add a treeviewer for the tree extracted from a Newick file object to the
4257 * current alignment view
4264 * Associated alignment input data (or null)
4273 * @return TreePanel handle
4275 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4276 AlignmentView input, int w, int h, int x, int y)
4278 TreePanel tp = null;
4284 if (nf.getTree() != null)
4286 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4292 tp.setLocation(x, y);
4295 Desktop.addInternalFrame(tp, treeTitle, w, h);
4297 } catch (Exception ex)
4299 ex.printStackTrace();
4305 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4308 int w = 400, h = 500;
4312 NewickFile fin = new NewickFile(
4313 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4314 String title = aa.label + " " + cm.getTreeMethod() + " tree"
4315 + (aa.sequenceRef != null
4316 ? (" for " + aa.sequenceRef.getDisplayId(false))
4319 showColumnWiseTree(fin, aa, title, w, h, x, y);
4320 } catch (Throwable xx)
4322 Console.error("Unexpected exception showing tree for contact matrix",
4327 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4328 String treeTitle, int w, int h, int x, int y)
4333 if (nf.getTree() == null)
4337 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4343 tp.setLocation(x, y);
4346 Desktop.addInternalFrame(tp, treeTitle, w, h);
4348 } catch (Throwable xx)
4350 Console.error("Unexpected exception showing tree for contact matrix",
4356 private boolean buildingMenu = false;
4359 * Generates menu items and listener event actions for web service clients
4362 public void BuildWebServiceMenu()
4364 while (buildingMenu)
4369 .errPrintln("Waiting for building menu to finish.");
4371 } catch (Exception e)
4375 final AlignFrame me = this;
4376 buildingMenu = true;
4377 new Thread(new Runnable()
4382 final List<JMenuItem> legacyItems = new ArrayList<>();
4385 // jalview.bin.Console.errPrintln("Building ws menu again "
4386 // + Thread.currentThread());
4387 // TODO: add support for context dependent disabling of services based
4389 // alignment and current selection
4390 // TODO: add additional serviceHandle parameter to specify abstract
4392 // class independently of AbstractName
4393 // TODO: add in rediscovery GUI function to restart discoverer
4394 // TODO: group services by location as well as function and/or
4396 // object broker mechanism.
4397 final Vector<JMenu> wsmenu = new Vector<>();
4398 final IProgressIndicator af = me;
4401 * do not i18n these strings - they are hard-coded in class
4402 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4403 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4405 final JMenu msawsmenu = new JMenu("Alignment");
4406 final JMenu secstrmenu = new JMenu(
4407 "Secondary Structure Prediction");
4408 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4409 final JMenu analymenu = new JMenu("Analysis");
4410 final JMenu dismenu = new JMenu("Protein Disorder");
4411 // JAL-940 - only show secondary structure prediction services from
4412 // the legacy server
4413 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4415 Discoverer.services != null && (Discoverer.services.size() > 0))
4417 // TODO: refactor to allow list of AbstractName/Handler bindings to
4419 // stored or retrieved from elsewhere
4420 // No MSAWS used any more:
4421 // Vector msaws = null; // (Vector)
4422 // Discoverer.services.get("MsaWS");
4423 Vector<ServiceHandle> secstrpr = Discoverer.services
4425 if (secstrpr != null)
4427 // Add any secondary structure prediction services
4428 for (int i = 0, j = secstrpr.size(); i < j; i++)
4430 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4431 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4432 .getServiceClient(sh);
4433 int p = secstrmenu.getItemCount();
4434 impl.attachWSMenuEntry(secstrmenu, me);
4435 int q = secstrmenu.getItemCount();
4436 for (int litm = p; litm < q; litm++)
4438 legacyItems.add(secstrmenu.getItem(litm));
4444 // Add all submenus in the order they should appear on the web
4446 wsmenu.add(msawsmenu);
4447 wsmenu.add(secstrmenu);
4448 wsmenu.add(dismenu);
4449 wsmenu.add(analymenu);
4450 // No search services yet
4451 // wsmenu.add(seqsrchmenu);
4453 javax.swing.SwingUtilities.invokeLater(new Runnable()
4460 webService.removeAll();
4461 // first, add discovered services onto the webservices menu
4462 if (wsmenu.size() > 0)
4464 for (int i = 0, j = wsmenu.size(); i < j; i++)
4466 webService.add(wsmenu.get(i));
4471 webService.add(me.webServiceNoServices);
4473 // TODO: move into separate menu builder class.
4475 // logic for 2.11.1.4 is
4476 // always look to see if there is a discover. if there isn't
4477 // we can't show any Jws2 services
4478 // if there are services available, show them - regardless of
4479 // the 'show JWS2 preference'
4480 // if the discoverer is running then say so
4481 // otherwise offer to trigger discovery if 'show JWS2' is not
4483 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4484 if (jws2servs != null)
4486 if (jws2servs.hasServices())
4488 jws2servs.attachWSMenuEntry(webService, me);
4489 for (Jws2Instance sv : jws2servs.getServices())
4491 if (sv.description.toLowerCase(Locale.ROOT)
4494 for (JMenuItem jmi : legacyItems)
4496 jmi.setVisible(false);
4502 if (jws2servs.isRunning())
4504 JMenuItem tm = new JMenuItem(
4505 "Still discovering JABA Services");
4506 tm.setEnabled(false);
4509 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4511 JMenuItem enableJws2 = new JMenuItem(
4512 "Discover Web Services");
4513 enableJws2.setToolTipText(
4514 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4515 enableJws2.setEnabled(true);
4516 enableJws2.addActionListener(new ActionListener()
4520 public void actionPerformed(ActionEvent e)
4522 // start service discoverer, but ignore preference
4523 Desktop.instance.startServiceDiscovery(false,
4527 webService.add(enableJws2);
4531 build_urlServiceMenu(me.webService);
4532 build_fetchdbmenu(webService);
4533 for (JMenu item : wsmenu)
4535 if (item.getItemCount() == 0)
4537 item.setEnabled(false);
4541 item.setEnabled(true);
4544 } catch (Exception e)
4547 "Exception during web service menu building process.",
4552 } catch (Exception e)
4555 buildingMenu = false;
4562 * construct any groupURL type service menu entries.
4566 protected void build_urlServiceMenu(JMenu webService)
4568 // TODO: remove this code when 2.7 is released
4569 // DEBUG - alignmentView
4571 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4572 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4574 * @Override public void actionPerformed(ActionEvent e) {
4575 * jalview.datamodel.AlignmentView
4576 * .testSelectionViews(af.viewport.getAlignment(),
4577 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4579 * }); webService.add(testAlView);
4581 // TODO: refactor to RestClient discoverer and merge menu entries for
4582 // rest-style services with other types of analysis/calculation service
4583 // SHmmr test client - still being implemented.
4584 // DEBUG - alignmentView
4586 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4589 client.attachWSMenuEntry(
4590 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4596 * Searches the alignment sequences for xRefs and builds the Show
4597 * Cross-References menu (formerly called Show Products), with database
4598 * sources for which cross-references are found (protein sources for a
4599 * nucleotide alignment and vice versa)
4601 * @return true if Show Cross-references menu should be enabled
4603 public boolean canShowProducts()
4605 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4606 AlignmentI dataset = viewport.getAlignment().getDataset();
4608 showProducts.removeAll();
4609 final boolean dna = viewport.getAlignment().isNucleotide();
4611 if (seqs == null || seqs.length == 0)
4613 // nothing to see here.
4617 boolean showp = false;
4620 List<String> ptypes = new CrossRef(seqs, dataset)
4621 .findXrefSourcesForSequences(dna);
4623 for (final String source : ptypes)
4626 final AlignFrame af = this;
4627 JMenuItem xtype = new JMenuItem(source);
4628 xtype.addActionListener(new ActionListener()
4631 public void actionPerformed(ActionEvent e)
4633 showProductsFor(af.viewport.getSequenceSelection(), dna,
4637 showProducts.add(xtype);
4639 showProducts.setVisible(showp);
4640 showProducts.setEnabled(showp);
4641 } catch (Exception e)
4644 "canShowProducts threw an exception - please report to help@jalview.org",
4652 * Finds and displays cross-references for the selected sequences (protein
4653 * products for nucleotide sequences, dna coding sequences for peptides).
4656 * the sequences to show cross-references for
4658 * true if from a nucleotide alignment (so showing proteins)
4660 * the database to show cross-references for
4662 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4663 final String source)
4665 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4670 * Construct and display a new frame containing the translation of this
4671 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4674 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4676 AlignmentI al = null;
4679 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4681 al = dna.translateCdna(codeTable);
4682 } catch (Exception ex)
4684 Console.error("Exception during translation. Please report this !",
4686 final String msg = MessageManager.getString(
4687 "label.error_when_translating_sequences_submit_bug_report");
4688 final String errorTitle = MessageManager
4689 .getString("label.implementation_error")
4690 + MessageManager.getString("label.translation_failed");
4691 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4692 JvOptionPane.ERROR_MESSAGE);
4695 if (al == null || al.getHeight() == 0)
4697 final String msg = MessageManager.getString(
4698 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4699 final String errorTitle = MessageManager
4700 .getString("label.translation_failed");
4701 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4702 JvOptionPane.WARNING_MESSAGE);
4706 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4707 af.setFileFormat(this.currentFileFormat);
4708 final String newTitle = MessageManager
4709 .formatMessage("label.translation_of_params", new Object[]
4710 { this.getTitle(), codeTable.getId() });
4711 af.setTitle(newTitle);
4712 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4714 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4715 viewport.openSplitFrame(af, new Alignment(seqs));
4719 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4726 * Set the file format
4730 public void setFileFormat(FileFormatI format)
4732 this.currentFileFormat = format;
4736 * Try to load a features file onto the alignment.
4739 * contents or path to retrieve file or a File object
4741 * access mode of file (see jalview.io.AlignFile)
4742 * @return true if features file was parsed correctly.
4744 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4747 return avc.parseFeaturesFile(file, sourceType,
4748 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4753 public void refreshFeatureUI(boolean enableIfNecessary)
4755 // note - currently this is only still here rather than in the controller
4756 // because of the featureSettings hard reference that is yet to be
4758 if (enableIfNecessary)
4760 viewport.setShowSequenceFeatures(true);
4761 showSeqFeatures.setSelected(true);
4767 public void dragEnter(DropTargetDragEvent evt)
4772 public void dragExit(DropTargetEvent evt)
4777 public void dragOver(DropTargetDragEvent evt)
4782 public void dropActionChanged(DropTargetDragEvent evt)
4787 public void drop(DropTargetDropEvent evt)
4789 // JAL-1552 - acceptDrop required before getTransferable call for
4790 // Java's Transferable for native dnd
4791 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4792 Transferable t = evt.getTransferable();
4794 final AlignFrame thisaf = this;
4795 final List<Object> files = new ArrayList<>();
4796 List<DataSourceType> protocols = new ArrayList<>();
4800 Desktop.transferFromDropTarget(files, protocols, evt, t);
4801 } catch (Exception e)
4803 e.printStackTrace();
4807 new Thread(new Runnable()
4814 // check to see if any of these files have names matching sequences
4817 SequenceIdMatcher idm = new SequenceIdMatcher(
4818 viewport.getAlignment().getSequencesArray());
4820 * Object[] { String,SequenceI}
4822 ArrayList<Object[]> filesmatched = new ArrayList<>();
4823 ArrayList<Object[]> filesnotmatched = new ArrayList<>();
4824 for (int i = 0; i < files.size(); i++)
4827 Object file = files.get(i);
4828 String fileName = file.toString();
4830 DataSourceType protocol = (file instanceof File
4831 ? DataSourceType.FILE
4832 : FormatAdapter.checkProtocol(fileName));
4833 if (protocol == DataSourceType.FILE)
4836 if (file instanceof File)
4839 Platform.cacheFileData(fl);
4843 fl = new File(fileName);
4845 pdbfn = fl.getName();
4847 else if (protocol == DataSourceType.URL)
4849 URL url = new URL(fileName);
4850 pdbfn = url.getFile();
4852 if (pdbfn.length() > 0)
4854 // attempt to find a match in the alignment
4855 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4856 int l = 0, c = pdbfn.indexOf(".");
4857 while (mtch == null && c != -1)
4862 } while ((c = pdbfn.indexOf(".", l)) > l);
4865 pdbfn = pdbfn.substring(0, l);
4867 mtch = idm.findAllIdMatches(pdbfn);
4869 FileFormatI type = null;
4874 type = new IdentifyFile().identify(file, protocol);
4875 } catch (Exception ex)
4879 if (type != null && type.isStructureFile())
4881 filesmatched.add(new Object[] { file, protocol, mtch });
4885 // File wasn't named like one of the sequences or wasn't a PDB
4887 filesnotmatched.add(new Object[] { file, protocol, type });
4891 if (filesmatched.size() > 0)
4893 boolean autoAssociate = Cache
4894 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4897 String msg = MessageManager.formatMessage(
4898 "label.automatically_associate_structure_files_with_sequences_same_name",
4900 { Integer.valueOf(filesmatched.size())
4902 String ttl = MessageManager.getString(
4903 "label.automatically_associate_structure_files_by_name");
4904 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4905 ttl, JvOptionPane.YES_NO_OPTION);
4906 autoAssociate = choice == JvOptionPane.YES_OPTION;
4910 for (Object[] fm : filesmatched)
4912 // try and associate
4913 // TODO: may want to set a standard ID naming formalism for
4914 // associating PDB files which have no IDs.
4915 for (SequenceI toassoc : (SequenceI[]) fm[2])
4917 PDBEntry pe = new AssociatePdbFileWithSeq()
4918 .associatePdbWithSeq(fm[0].toString(),
4919 (DataSourceType) fm[1], toassoc, false,
4923 jalview.bin.Console.errPrintln("Associated file : "
4924 + (fm[0].toString()) + " with "
4925 + toassoc.getDisplayId(true));
4929 // TODO: do we need to update overview ? only if features are
4931 alignPanel.paintAlignment(true, false);
4937 * add declined structures as sequences
4939 for (Object[] o : filesmatched)
4941 filesnotmatched.add(new Object[] { o[0], o[1] });
4945 if (filesnotmatched.size() > 0)
4947 if (assocfiles > 0 && (Cache.getDefault(
4948 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4949 || JvOptionPane.showConfirmDialog(thisaf,
4950 "<html>" + MessageManager.formatMessage(
4951 "label.ignore_unmatched_dropped_files_info",
4954 filesnotmatched.size())
4957 MessageManager.getString(
4958 "label.ignore_unmatched_dropped_files"),
4959 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4963 for (Object[] fn : filesnotmatched)
4965 loadJalviewDataFile(fn[0], (DataSourceType) fn[1],
4966 (FileFormatI) fn[2], null);
4970 } catch (Exception ex)
4972 ex.printStackTrace();
4980 * Attempt to load a "dropped" file or URL string, by testing in turn for
4982 * <li>an Annotation file</li>
4983 * <li>a JNet file</li>
4984 * <li>a features file</li>
4985 * <li>else try to interpret as an alignment file</li>
4989 * either a filename or a URL string.
4991 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4992 FileFormatI format, SequenceI assocSeq)
4994 // BH 2018 was String file
4997 if (sourceType == null)
4999 sourceType = FormatAdapter.checkProtocol(file);
5001 // if the file isn't identified, or not positively identified as some
5002 // other filetype (PFAM is default unidentified alignment file type) then
5003 // try to parse as annotation.
5004 boolean isAnnotation = (format == null
5005 || FileFormat.Pfam.equals(format))
5006 ? new AnnotationFile().annotateAlignmentView(viewport,
5012 // first see if its a T-COFFEE score file
5013 TCoffeeScoreFile tcf = null;
5016 tcf = new TCoffeeScoreFile(file, sourceType);
5019 if (tcf.annotateAlignment(viewport.getAlignment(), true))
5023 new TCoffeeColourScheme(viewport.getAlignment()));
5024 isAnnotation = true;
5025 setStatus(MessageManager.getString(
5026 "label.successfully_pasted_tcoffee_scores_to_alignment"));
5030 // some problem - if no warning its probable that the ID matching
5031 // process didn't work
5032 JvOptionPane.showMessageDialog(Desktop.desktop,
5033 tcf.getWarningMessage() == null
5034 ? MessageManager.getString(
5035 "label.check_file_matches_sequence_ids_alignment")
5036 : tcf.getWarningMessage(),
5037 MessageManager.getString(
5038 "label.problem_reading_tcoffee_score_file"),
5039 JvOptionPane.WARNING_MESSAGE);
5046 } catch (Exception x)
5049 "Exception when processing data source as T-COFFEE score file",
5055 // try to see if its a JNet 'concise' style annotation file *before*
5057 // try to parse it as a features file
5060 format = new IdentifyFile().identify(file, sourceType);
5062 if (FileFormat.FeatureSettings == format)
5064 if (featureSettings != null)
5066 featureSettings.load(file, sourceType);
5070 FeatureSettings.loadFeatureSettingsFile(getFeatureRenderer(),
5071 fileObject, sourceType);
5074 else if (FileFormat.ScoreMatrix == format)
5076 ScoreMatrixFile sm = new ScoreMatrixFile(
5077 new FileParse(file, sourceType));
5079 // todo: i18n this message
5080 setStatus(MessageManager.formatMessage(
5081 "label.successfully_loaded_matrix",
5082 sm.getMatrixName()));
5084 else if (FileFormat.Jnet.equals(format))
5086 JPredFile predictions = new JPredFile(file, sourceType);
5087 new JnetAnnotationMaker();
5088 JnetAnnotationMaker.add_annotation(predictions,
5089 viewport.getAlignment(), 0, false);
5090 viewport.getAlignment().setupJPredAlignment();
5091 isAnnotation = true;
5093 // else if (IdentifyFile.FeaturesFile.equals(format))
5094 else if (FileFormat.Features.equals(format))
5096 if (parseFeaturesFile(file, sourceType))
5098 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5099 if (splitFrame != null)
5101 splitFrame.repaint();
5105 alignPanel.paintAlignment(true, true);
5111 new FileLoader().LoadFile(viewport, file, sourceType, format);
5118 alignPanel.adjustAnnotationHeight();
5119 viewport.updateSequenceIdColours();
5120 buildSortByAnnotationScoresMenu();
5121 alignPanel.paintAlignment(true, true);
5123 } catch (Exception ex)
5125 ex.printStackTrace();
5126 } catch (OutOfMemoryError oom)
5131 } catch (Exception x)
5136 + (sourceType != null
5137 ? (sourceType == DataSourceType.PASTE
5139 : "using " + sourceType + " from "
5143 ? "(parsing as '" + format + "' file)"
5145 oom, Desktop.desktop);
5150 * Method invoked by the ChangeListener on the tabbed pane, in other words
5151 * when a different tabbed pane is selected by the user or programmatically.
5154 public void tabSelectionChanged(int index)
5159 * update current Overview window title (if there is one)
5160 * to add view name "Original" if necessary
5162 alignPanel.setOverviewTitle(this);
5165 * switch panels and set Overview title (if there is one
5166 * because it was opened automatically)
5168 alignPanel = alignPanels.get(index);
5169 alignPanel.setOverviewTitle(this);
5171 viewport = alignPanel.av;
5172 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5173 setMenusFromViewport(viewport);
5174 if (featureSettings != null && featureSettings.isOpen()
5175 && featureSettings.fr.getViewport() != viewport)
5177 if (viewport.isShowSequenceFeatures())
5179 // refresh the featureSettings to reflect UI change
5180 showFeatureSettingsUI();
5184 // close feature settings for this view.
5185 featureSettings.close();
5192 * 'focus' any colour slider that is open to the selected viewport
5194 if (viewport.getConservationSelected())
5196 SliderPanel.setConservationSlider(alignPanel,
5197 viewport.getResidueShading(), alignPanel.getViewName());
5201 SliderPanel.hideConservationSlider();
5203 if (viewport.getAbovePIDThreshold())
5205 SliderPanel.setPIDSliderSource(alignPanel,
5206 viewport.getResidueShading(), alignPanel.getViewName());
5210 SliderPanel.hidePIDSlider();
5214 * If there is a frame linked to this one in a SplitPane, switch it to the
5215 * same view tab index. No infinite recursion of calls should happen, since
5216 * tabSelectionChanged() should not get invoked on setting the selected
5217 * index to an unchanged value. Guard against setting an invalid index
5218 * before the new view peer tab has been created.
5220 final AlignViewportI peer = viewport.getCodingComplement();
5223 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5224 .getAlignPanel().alignFrame;
5225 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5227 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5233 * On right mouse click on view tab, prompt for and set new view name.
5236 public void tabbedPane_mousePressed(MouseEvent e)
5238 if (e.isPopupTrigger())
5240 String msg = MessageManager.getString("label.enter_view_name");
5241 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5242 String reply = JvOptionPane.showInputDialog(msg, ttl);
5246 viewport.setViewName(reply);
5247 // TODO warn if reply is in getExistingViewNames()?
5248 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5253 public AlignViewport getCurrentView()
5259 * Open the dialog for regex description parsing.
5262 protected void extractScores_actionPerformed(ActionEvent e)
5264 ParseProperties pp = new jalview.analysis.ParseProperties(
5265 viewport.getAlignment());
5266 // TODO: verify regex and introduce GUI dialog for version 2.5
5267 // if (pp.getScoresFromDescription("col", "score column ",
5268 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5270 if (pp.getScoresFromDescription("description column",
5271 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5273 buildSortByAnnotationScoresMenu();
5281 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5285 protected void showDbRefs_actionPerformed(ActionEvent e)
5287 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5293 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5297 protected void showNpFeats_actionPerformed(ActionEvent e)
5299 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5303 * find the viewport amongst the tabs in this alignment frame and close that
5308 public boolean closeView(AlignViewportI av)
5312 this.closeMenuItem_actionPerformed(false);
5315 Component[] comp = tabbedPane.getComponents();
5316 for (int i = 0; comp != null && i < comp.length; i++)
5318 if (comp[i] instanceof AlignmentPanel)
5320 if (((AlignmentPanel) comp[i]).av == av)
5323 closeView((AlignmentPanel) comp[i]);
5331 protected void build_fetchdbmenu(JMenu webService)
5333 // Temporary hack - DBRef Fetcher always top level ws entry.
5334 // TODO We probably want to store a sequence database checklist in
5335 // preferences and have checkboxes.. rather than individual sources selected
5337 final JMenu rfetch = new JMenu(
5338 MessageManager.getString("action.fetch_db_references"));
5339 rfetch.setToolTipText(MessageManager.getString(
5340 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5341 webService.add(rfetch);
5343 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5344 MessageManager.getString("option.trim_retrieved_seqs"));
5345 trimrs.setToolTipText(
5346 MessageManager.getString("label.trim_retrieved_sequences"));
5348 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5349 trimrs.addActionListener(new ActionListener()
5352 public void actionPerformed(ActionEvent e)
5354 trimrs.setSelected(trimrs.isSelected());
5355 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5356 Boolean.valueOf(trimrs.isSelected()).toString());
5360 JMenuItem fetchr = new JMenuItem(
5361 MessageManager.getString("label.standard_databases"));
5362 fetchr.setToolTipText(
5363 MessageManager.getString("label.fetch_embl_uniprot"));
5364 fetchr.addActionListener(new ActionListener()
5368 public void actionPerformed(ActionEvent e)
5370 new Thread(new Runnable()
5375 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5376 .getAlignment().isNucleotide();
5377 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5378 alignPanel.av.getSequenceSelection(),
5379 alignPanel.alignFrame, null,
5380 alignPanel.alignFrame.featureSettings, isNucleotide);
5381 dbRefFetcher.addListener(new FetchFinishedListenerI()
5384 public void finished()
5387 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5388 .getFeatureSettingsModels())
5391 alignPanel.av.mergeFeaturesStyle(srcSettings);
5393 AlignFrame.this.setMenusForViewport();
5396 dbRefFetcher.fetchDBRefs(false);
5404 new Thread(new Runnable()
5409 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5410 .getSequenceFetcherSingleton();
5411 javax.swing.SwingUtilities.invokeLater(new Runnable()
5416 String[] dbclasses = sf.getNonAlignmentSources();
5417 List<DbSourceProxy> otherdb;
5418 JMenu dfetch = new JMenu();
5419 JMenu ifetch = new JMenu();
5420 JMenuItem fetchr = null;
5421 int comp = 0, icomp = 0, mcomp = 15;
5422 String mname = null;
5424 for (String dbclass : dbclasses)
5426 otherdb = sf.getSourceProxy(dbclass);
5427 // add a single entry for this class, or submenu allowing 'fetch
5429 if (otherdb == null || otherdb.size() < 1)
5435 mname = "From " + dbclass;
5437 if (otherdb.size() == 1)
5439 final DbSourceProxy[] dassource = otherdb
5440 .toArray(new DbSourceProxy[0]);
5441 DbSourceProxy src = otherdb.get(0);
5442 fetchr = new JMenuItem(src.getDbSource());
5443 fetchr.addActionListener(new ActionListener()
5447 public void actionPerformed(ActionEvent e)
5449 new Thread(new Runnable()
5455 boolean isNucleotide = alignPanel.alignFrame
5456 .getViewport().getAlignment()
5458 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5459 alignPanel.av.getSequenceSelection(),
5460 alignPanel.alignFrame, dassource,
5461 alignPanel.alignFrame.featureSettings,
5464 .addListener(new FetchFinishedListenerI()
5467 public void finished()
5469 FeatureSettingsModelI srcSettings = dassource[0]
5470 .getFeatureColourScheme();
5471 alignPanel.av.mergeFeaturesStyle(
5473 AlignFrame.this.setMenusForViewport();
5476 dbRefFetcher.fetchDBRefs(false);
5482 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5483 MessageManager.formatMessage(
5484 "label.fetch_retrieve_from", new Object[]
5485 { src.getDbName() })));
5491 final DbSourceProxy[] dassource = otherdb
5492 .toArray(new DbSourceProxy[0]);
5494 DbSourceProxy src = otherdb.get(0);
5495 fetchr = new JMenuItem(MessageManager
5496 .formatMessage("label.fetch_all_param", new Object[]
5497 { src.getDbSource() }));
5498 fetchr.addActionListener(new ActionListener()
5501 public void actionPerformed(ActionEvent e)
5503 new Thread(new Runnable()
5509 boolean isNucleotide = alignPanel.alignFrame
5510 .getViewport().getAlignment()
5512 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5513 alignPanel.av.getSequenceSelection(),
5514 alignPanel.alignFrame, dassource,
5515 alignPanel.alignFrame.featureSettings,
5518 .addListener(new FetchFinishedListenerI()
5521 public void finished()
5523 AlignFrame.this.setMenusForViewport();
5526 dbRefFetcher.fetchDBRefs(false);
5532 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5533 MessageManager.formatMessage(
5534 "label.fetch_retrieve_from_all_sources",
5536 { Integer.valueOf(otherdb.size())
5538 src.getDbSource(), src.getDbName() })));
5541 // and then build the rest of the individual menus
5542 ifetch = new JMenu(MessageManager.formatMessage(
5543 "label.source_from_db_source", new Object[]
5544 { src.getDbSource() }));
5546 String imname = null;
5548 for (DbSourceProxy sproxy : otherdb)
5550 String dbname = sproxy.getDbName();
5551 String sname = dbname.length() > 5
5552 ? dbname.substring(0, 5) + "..."
5554 String msname = dbname.length() > 10
5555 ? dbname.substring(0, 10) + "..."
5559 imname = MessageManager
5560 .formatMessage("label.from_msname", new Object[]
5563 fetchr = new JMenuItem(msname);
5564 final DbSourceProxy[] dassrc = { sproxy };
5565 fetchr.addActionListener(new ActionListener()
5569 public void actionPerformed(ActionEvent e)
5571 new Thread(new Runnable()
5577 boolean isNucleotide = alignPanel.alignFrame
5578 .getViewport().getAlignment()
5580 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5581 alignPanel.av.getSequenceSelection(),
5582 alignPanel.alignFrame, dassrc,
5583 alignPanel.alignFrame.featureSettings,
5586 .addListener(new FetchFinishedListenerI()
5589 public void finished()
5591 AlignFrame.this.setMenusForViewport();
5594 dbRefFetcher.fetchDBRefs(false);
5600 fetchr.setToolTipText(
5601 "<html>" + MessageManager.formatMessage(
5602 "label.fetch_retrieve_from", new Object[]
5606 if (++icomp >= mcomp || i == (otherdb.size()))
5608 ifetch.setText(MessageManager.formatMessage(
5609 "label.source_to_target", imname, sname));
5611 ifetch = new JMenu();
5619 if (comp >= mcomp || dbi >= (dbclasses.length))
5621 dfetch.setText(MessageManager.formatMessage(
5622 "label.source_to_target", mname, dbclass));
5624 dfetch = new JMenu();
5637 * Left justify the whole alignment.
5640 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5642 AlignmentI al = viewport.getAlignment();
5644 viewport.firePropertyChange("alignment", null, al);
5648 * Right justify the whole alignment.
5651 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5653 AlignmentI al = viewport.getAlignment();
5655 viewport.firePropertyChange("alignment", null, al);
5659 public void setShowSeqFeatures(boolean b)
5661 showSeqFeatures.setSelected(b);
5662 viewport.setShowSequenceFeatures(b);
5669 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5670 * awt.event.ActionEvent)
5673 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5675 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5676 alignPanel.paintAlignment(false, false);
5683 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5687 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5689 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5690 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5698 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5699 * .event.ActionEvent)
5702 protected void showGroupConservation_actionPerformed(ActionEvent e)
5704 viewport.setShowGroupConservation(showGroupConservation.getState());
5705 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5712 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5713 * .event.ActionEvent)
5716 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5718 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5719 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5723 protected void showSSConsensusHistogram_actionPerformed(ActionEvent e)
5725 viewport.setShowSSConsensusHistogram(showSSConsensusHistogram.getState());
5726 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5733 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5734 * .event.ActionEvent)
5737 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5739 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5740 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5744 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5746 showSequenceLogo.setState(true);
5747 viewport.setShowSequenceLogo(true);
5748 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5749 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5753 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5755 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5762 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5763 * .event.ActionEvent)
5766 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5768 if (avc.makeGroupsFromSelection())
5770 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5771 alignPanel.updateAnnotation();
5772 alignPanel.paintAlignment(true,
5773 viewport.needToUpdateStructureViews());
5777 public void clearAlignmentSeqRep()
5779 // TODO refactor alignmentseqrep to controller
5780 if (viewport.getAlignment().hasSeqrep())
5782 viewport.getAlignment().setSeqrep(null);
5783 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5784 alignPanel.updateAnnotation();
5785 alignPanel.paintAlignment(true, true);
5790 protected void createGroup_actionPerformed(ActionEvent e)
5792 if (avc.createGroup())
5794 if (applyAutoAnnotationSettings.isSelected())
5796 alignPanel.updateAnnotation(true, false);
5798 alignPanel.alignmentChanged();
5803 protected void unGroup_actionPerformed(ActionEvent e)
5807 alignPanel.alignmentChanged();
5812 * make the given alignmentPanel the currently selected tab
5814 * @param alignmentPanel
5816 public void setDisplayedView(AlignmentPanel alignmentPanel)
5818 if (!viewport.getSequenceSetId()
5819 .equals(alignmentPanel.av.getSequenceSetId()))
5821 throw new Error(MessageManager.getString(
5822 "error.implementation_error_cannot_show_view_alignment_frame"));
5824 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5825 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5827 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5832 * Action on selection of menu options to Show or Hide annotations.
5835 * @param forSequences
5836 * update sequence-related annotations
5837 * @param forAlignment
5838 * update non-sequence-related annotations
5841 public void setAnnotationsVisibility(boolean visible,
5842 boolean forSequences, boolean forAlignment)
5844 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5845 .getAlignmentAnnotation();
5850 for (AlignmentAnnotation aa : anns)
5853 * don't display non-positional annotations on an alignment
5855 if (aa.annotations == null)
5859 boolean apply = (aa.sequenceRef == null && forAlignment)
5860 || (aa.sequenceRef != null && forSequences);
5863 aa.visible = visible;
5866 alignPanel.validateAnnotationDimensions(true);
5867 // TODO this triggers relayout of annotation panel - otherwise annotation
5868 // label height is different to panel height
5869 alignPanel.fontChanged();
5870 alignPanel.alignmentChanged();
5874 * Store selected annotation sort order for the view and repaint.
5877 protected void sortAnnotations_actionPerformed()
5879 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5881 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5882 alignPanel.paintAlignment(false, false);
5887 * @return alignment panels in this alignment frame
5889 public List<? extends AlignmentViewPanel> getAlignPanels()
5891 // alignPanels is never null
5892 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5897 * Open a new alignment window, with the cDNA associated with this (protein)
5898 * alignment, aligned as is the protein.
5900 protected void viewAsCdna_actionPerformed()
5902 // TODO no longer a menu action - refactor as required
5903 final AlignmentI alignment = getViewport().getAlignment();
5904 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5905 if (mappings == null)
5909 List<SequenceI> cdnaSeqs = new ArrayList<>();
5910 for (SequenceI aaSeq : alignment.getSequences())
5912 for (AlignedCodonFrame acf : mappings)
5914 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5918 * There is a cDNA mapping for this protein sequence - add to new
5919 * alignment. It will share the same dataset sequence as other mapped
5920 * cDNA (no new mappings need to be created).
5922 final Sequence newSeq = new Sequence(dnaSeq);
5923 newSeq.setDatasetSequence(dnaSeq);
5924 cdnaSeqs.add(newSeq);
5928 if (cdnaSeqs.size() == 0)
5930 // show a warning dialog no mapped cDNA
5933 AlignmentI cdna = new Alignment(
5934 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5935 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5936 AlignFrame.DEFAULT_HEIGHT);
5937 cdna.alignAs(alignment);
5938 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5940 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5941 AlignFrame.DEFAULT_HEIGHT);
5945 * Set visibility of dna/protein complement view (available when shown in a
5951 protected void showComplement_actionPerformed(boolean show)
5953 SplitContainerI sf = getSplitViewContainer();
5956 sf.setComplementVisible(this, show);
5961 * Generate the reverse (optionally complemented) of the selected sequences,
5962 * and add them to the alignment
5965 protected void showReverse_actionPerformed(boolean complement)
5967 AlignmentI al = null;
5970 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5971 al = dna.reverseCdna(complement);
5972 viewport.addAlignment(al, "");
5973 addHistoryItem(new EditCommand(
5974 MessageManager.getString("label.add_sequences"), Action.PASTE,
5975 al.getSequencesArray(), 0, al.getWidth(),
5976 viewport.getAlignment()));
5977 } catch (Exception ex)
5979 jalview.bin.Console.errPrintln(ex.getMessage());
5985 * Try to run a script in the Groovy console, having first ensured that this
5986 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5987 * be targeted at this alignment.
5990 protected void runGroovy_actionPerformed()
5992 Jalview.getInstance().setCurrentAlignFrame(this);
5993 groovy.console.ui.Console console = Desktop.getGroovyConsole();
5994 if (console != null)
5998 console.setVariable(JalviewObjectI.currentAlFrameName, this);
5999 console.runScript();
6000 } catch (Exception ex)
6002 jalview.bin.Console.errPrintln((ex.toString()));
6003 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
6004 MessageManager.getString("label.couldnt_run_groovy_script"),
6005 MessageManager.getString("label.groovy_support_failed"),
6006 JvOptionPane.ERROR_MESSAGE);
6012 .errPrintln("Can't run Groovy script as console not found");
6017 * Hides columns containing (or not containing) a specified feature, provided
6018 * that would not leave all columns hidden
6020 * @param featureType
6021 * @param columnsContaining
6024 public boolean hideFeatureColumns(String featureType,
6025 boolean columnsContaining)
6027 boolean notForHiding = avc.markColumnsContainingFeatures(
6028 columnsContaining, false, false, featureType);
6031 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
6032 false, featureType))
6034 getViewport().hideSelectedColumns();
6042 protected void selectHighlightedColumns_actionPerformed(
6043 ActionEvent actionEvent)
6045 // include key modifier check in case user selects from menu
6046 avc.markHighlightedColumns(
6047 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
6048 (actionEvent.getModifiers() & (ActionEvent.META_MASK
6049 | ActionEvent.CTRL_MASK)) != 0);
6053 protected void copyHighlightedColumns_actionPerformed(
6054 ActionEvent actionEvent)
6056 avc.copyHighlightedRegionsToClipboard();
6060 * Rebuilds the Colour menu, including any user-defined colours which have
6061 * been loaded either on startup or during the session
6063 public void buildColourMenu()
6065 colourMenu.removeAll();
6067 colourMenu.add(applyToAllGroups);
6068 colourMenu.add(textColour);
6069 colourMenu.addSeparator();
6071 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6072 viewport.getAlignment(), false);
6074 colourMenu.add(annotationColour);
6075 bg.add(annotationColour);
6076 colourMenu.addSeparator();
6077 colourMenu.add(conservationMenuItem);
6078 colourMenu.add(modifyConservation);
6079 colourMenu.add(abovePIDThreshold);
6080 colourMenu.add(modifyPID);
6082 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6083 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6087 * Open a dialog (if not already open) that allows the user to select and
6088 * calculate PCA or Tree analysis
6090 protected void openTreePcaDialog()
6092 if (alignPanel.getCalculationDialog() == null)
6094 new CalculationChooser(AlignFrame.this);
6099 protected void loadVcf_actionPerformed()
6101 JalviewFileChooser chooser = new JalviewFileChooser(
6102 Cache.getProperty("LAST_DIRECTORY"));
6103 chooser.setFileView(new JalviewFileView());
6104 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6105 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6106 final AlignFrame us = this;
6107 chooser.setResponseHandler(0, () -> {
6108 String choice = chooser.getSelectedFile().getPath();
6109 Cache.setProperty("LAST_DIRECTORY", choice);
6110 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6111 new VCFLoader(choice).loadVCF(seqs, us);
6113 chooser.showOpenDialog(null);
6117 private Rectangle lastFeatureSettingsBounds = null;
6120 public void setFeatureSettingsGeometry(Rectangle bounds)
6122 lastFeatureSettingsBounds = bounds;
6126 public Rectangle getFeatureSettingsGeometry()
6128 return lastFeatureSettingsBounds;
6133 class PrintThread extends Thread
6137 public PrintThread(AlignmentPanel ap)
6142 static PageFormat pf;
6147 PrinterJob printJob = PrinterJob.getPrinterJob();
6151 printJob.setPrintable(ap, pf);
6155 printJob.setPrintable(ap);
6158 if (printJob.printDialog())
6163 } catch (Exception PrintException)
6165 PrintException.printStackTrace();