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.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
63 import javax.swing.ButtonGroup;
64 import javax.swing.JCheckBoxMenuItem;
65 import javax.swing.JComponent;
66 import javax.swing.JEditorPane;
67 import javax.swing.JInternalFrame;
68 import javax.swing.JLabel;
69 import javax.swing.JLayeredPane;
70 import javax.swing.JMenu;
71 import javax.swing.JMenuItem;
72 import javax.swing.JPanel;
73 import javax.swing.JScrollPane;
74 import javax.swing.SwingUtilities;
76 import ext.vamsas.ServiceHandle;
77 import jalview.analysis.AlignmentSorter;
78 import jalview.analysis.AlignmentUtils;
79 import jalview.analysis.CrossRef;
80 import jalview.analysis.Dna;
81 import jalview.analysis.GeneticCodeI;
82 import jalview.analysis.ParseProperties;
83 import jalview.analysis.SequenceIdMatcher;
84 import jalview.api.AlignExportSettingsI;
85 import jalview.api.AlignViewControllerGuiI;
86 import jalview.api.AlignViewControllerI;
87 import jalview.api.AlignViewportI;
88 import jalview.api.AlignmentViewPanel;
89 import jalview.api.FeatureSettingsControllerI;
90 import jalview.api.FeatureSettingsModelI;
91 import jalview.api.SplitContainerI;
92 import jalview.api.ViewStyleI;
93 import jalview.api.analysis.SimilarityParamsI;
94 import jalview.bin.Cache;
95 import jalview.bin.Console;
96 import jalview.bin.Jalview;
97 import jalview.commands.CommandI;
98 import jalview.commands.EditCommand;
99 import jalview.commands.EditCommand.Action;
100 import jalview.commands.OrderCommand;
101 import jalview.commands.RemoveGapColCommand;
102 import jalview.commands.RemoveGapsCommand;
103 import jalview.commands.SlideSequencesCommand;
104 import jalview.commands.TrimRegionCommand;
105 import jalview.datamodel.AlignExportSettingsAdapter;
106 import jalview.datamodel.AlignedCodonFrame;
107 import jalview.datamodel.Alignment;
108 import jalview.datamodel.AlignmentAnnotation;
109 import jalview.datamodel.AlignmentExportData;
110 import jalview.datamodel.AlignmentI;
111 import jalview.datamodel.AlignmentOrder;
112 import jalview.datamodel.AlignmentView;
113 import jalview.datamodel.ColumnSelection;
114 import jalview.datamodel.ContactMatrixI;
115 import jalview.datamodel.HiddenColumns;
116 import jalview.datamodel.PDBEntry;
117 import jalview.datamodel.SeqCigar;
118 import jalview.datamodel.Sequence;
119 import jalview.datamodel.SequenceGroup;
120 import jalview.datamodel.SequenceI;
121 import jalview.gui.ColourMenuHelper.ColourChangeListener;
122 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
123 import jalview.io.AlignmentProperties;
124 import jalview.io.AnnotationFile;
125 import jalview.io.BackupFiles;
126 import jalview.io.BioJsHTMLOutput;
127 import jalview.io.DataSourceType;
128 import jalview.io.FileFormat;
129 import jalview.io.FileFormatI;
130 import jalview.io.FileFormats;
131 import jalview.io.FileLoader;
132 import jalview.io.FileParse;
133 import jalview.io.FormatAdapter;
134 import jalview.io.HtmlSvgOutput;
135 import jalview.io.IdentifyFile;
136 import jalview.io.JPredFile;
137 import jalview.io.JalviewFileChooser;
138 import jalview.io.JalviewFileView;
139 import jalview.io.JnetAnnotationMaker;
140 import jalview.io.NewickFile;
141 import jalview.io.ScoreMatrixFile;
142 import jalview.io.TCoffeeScoreFile;
143 import jalview.io.exceptions.ImageOutputException;
144 import jalview.io.vcf.VCFLoader;
145 import jalview.jbgui.GAlignFrame;
146 import jalview.project.Jalview2XML;
147 import jalview.schemes.ColourSchemeI;
148 import jalview.schemes.ColourSchemes;
149 import jalview.schemes.ResidueColourScheme;
150 import jalview.schemes.TCoffeeColourScheme;
151 import jalview.util.HttpUtils;
152 import jalview.util.ImageMaker.TYPE;
153 import jalview.util.MessageManager;
154 import jalview.util.Platform;
155 import jalview.util.imagemaker.BitmapImageSizing;
156 import jalview.viewmodel.AlignmentViewport;
157 import jalview.viewmodel.ViewportRanges;
158 import jalview.ws.DBRefFetcher;
159 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
160 import jalview.ws.jws1.Discoverer;
161 import jalview.ws.jws2.Jws2Discoverer;
162 import jalview.ws.jws2.jabaws2.Jws2Instance;
163 import jalview.ws.seqfetcher.DbSourceProxy;
169 * @version $Revision$
171 @SuppressWarnings("serial")
172 public class AlignFrame extends GAlignFrame implements DropTargetListener,
173 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
176 public static final int DEFAULT_WIDTH = 700;
178 public static final int DEFAULT_HEIGHT = 500;
181 * The currently displayed panel (selected tabbed view if more than one)
183 public AlignmentPanel alignPanel;
185 AlignViewport viewport;
187 public AlignViewControllerI avc;
189 List<AlignmentPanel> alignPanels = new ArrayList<>();
192 * Last format used to load or save alignments in this window
194 FileFormatI currentFileFormat = null;
197 * Current filename for this alignment
199 String fileName = null;
204 * Creates a new AlignFrame object with specific width and height.
210 public AlignFrame(AlignmentI al, int width, int height)
212 this(al, null, width, height);
216 * Creates a new AlignFrame object with specific width, height and
222 * @param sequenceSetId
224 public AlignFrame(AlignmentI al, int width, int height,
225 String sequenceSetId)
227 this(al, null, width, height, sequenceSetId);
231 * Creates a new AlignFrame object with specific width, height and
237 * @param sequenceSetId
240 public AlignFrame(AlignmentI al, int width, int height,
241 String sequenceSetId, String viewId)
243 this(al, null, width, height, sequenceSetId, viewId);
247 * new alignment window with hidden columns
251 * @param hiddenColumns
252 * ColumnSelection or null
254 * Width of alignment frame
258 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
261 this(al, hiddenColumns, width, height, null);
265 * Create alignment frame for al with hiddenColumns, a specific width and
266 * height, and specific sequenceId
269 * @param hiddenColumns
272 * @param sequenceSetId
275 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
276 int height, String sequenceSetId)
278 this(al, hiddenColumns, width, height, sequenceSetId, null);
282 * Create alignment frame for al with hiddenColumns, a specific width and
283 * height, and specific sequenceId
286 * @param hiddenColumns
289 * @param sequenceSetId
294 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
295 int height, String sequenceSetId, String viewId)
297 setSize(width, height);
299 if (al.getDataset() == null)
304 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
306 alignPanel = new AlignmentPanel(this, viewport);
308 addAlignmentPanel(alignPanel, true);
312 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
313 HiddenColumns hiddenColumns, int width, int height)
315 setSize(width, height);
317 if (al.getDataset() == null)
322 viewport = new AlignViewport(al, hiddenColumns);
324 if (hiddenSeqs != null && hiddenSeqs.length > 0)
326 viewport.hideSequence(hiddenSeqs);
328 alignPanel = new AlignmentPanel(this, viewport);
329 addAlignmentPanel(alignPanel, true);
334 * Make a new AlignFrame from existing alignmentPanels
341 public AlignFrame(AlignmentPanel ap)
345 addAlignmentPanel(ap, false);
350 * initalise the alignframe from the underlying viewport data and the
357 // setBackground(Color.white); // BH 2019
359 if (!Jalview.isHeadlessMode())
361 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
364 avc = new jalview.controller.AlignViewController(this, viewport,
366 if (viewport.getAlignmentConservationAnnotation() == null)
368 // BLOSUM62Colour.setEnabled(false);
369 conservationMenuItem.setEnabled(false);
370 modifyConservation.setEnabled(false);
371 // PIDColour.setEnabled(false);
372 // abovePIDThreshold.setEnabled(false);
373 // modifyPID.setEnabled(false);
376 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
378 if (sortby.equals("Id"))
380 sortIDMenuItem_actionPerformed(null);
382 else if (sortby.equals("Pairwise Identity"))
384 sortPairwiseMenuItem_actionPerformed(null);
388 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
390 setMenusFromViewport(viewport);
391 buildSortByAnnotationScoresMenu();
392 calculateTree.addActionListener(new ActionListener()
396 public void actionPerformed(ActionEvent e)
403 if (Desktop.desktop != null)
405 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
406 if (!Platform.isJS())
408 addServiceListeners();
413 if (viewport.getWrapAlignment())
415 wrapMenuItem_actionPerformed(null);
418 if (Cache.getDefault("SHOW_OVERVIEW", false))
420 this.overviewMenuItem_actionPerformed(null);
425 final List<AlignmentViewPanel> selviews = new ArrayList<>();
426 final List<AlignmentPanel> origview = new ArrayList<>();
427 final String menuLabel = MessageManager
428 .getString("label.copy_format_from");
429 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
430 new ViewSetProvider()
434 public AlignmentPanel[] getAllAlignmentPanels()
437 origview.add(alignPanel);
438 // make an array of all alignment panels except for this one
439 List<AlignmentPanel> aps = new ArrayList<>(
440 Arrays.asList(Desktop.getAlignmentPanels(null)));
441 aps.remove(AlignFrame.this.alignPanel);
442 return aps.toArray(new AlignmentPanel[aps.size()]);
444 }, selviews, new ItemListener()
448 public void itemStateChanged(ItemEvent e)
450 if (origview.size() > 0)
452 final AlignmentPanel ap = origview.get(0);
455 * Copy the ViewStyle of the selected panel to 'this one'.
456 * Don't change value of 'scaleProteinAsCdna' unless copying
459 ViewStyleI vs = selviews.get(0).getAlignViewport()
461 boolean fromSplitFrame = selviews.get(0)
462 .getAlignViewport().getCodingComplement() != null;
465 vs.setScaleProteinAsCdna(ap.getAlignViewport()
466 .getViewStyle().isScaleProteinAsCdna());
468 ap.getAlignViewport().setViewStyle(vs);
471 * Also rescale ViewStyle of SplitFrame complement if there is
472 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
473 * the whole ViewStyle (allow cDNA protein to have different
476 AlignViewportI complement = ap.getAlignViewport()
477 .getCodingComplement();
478 if (complement != null && vs.isScaleProteinAsCdna())
480 AlignFrame af = Desktop.getAlignFrameFor(complement);
481 ((SplitFrame) af.getSplitViewContainer())
483 af.setMenusForViewport();
487 ap.setSelected(true);
488 ap.alignFrame.setMenusForViewport();
493 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
494 .indexOf("devel") > -1
495 || Cache.getDefault("VERSION", "DEVELOPMENT")
496 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
498 formatMenu.add(vsel);
500 addFocusListener(new FocusAdapter()
503 public void focusGained(FocusEvent e)
505 Jalview.setCurrentAlignFrame(AlignFrame.this);
512 * Change the filename and format for the alignment, and enable the 'reload'
513 * button functionality.
520 public void setFileName(String file, FileFormatI format)
523 setFileFormat(format);
524 reload.setEnabled(true);
528 * JavaScript will have this, maybe others. More dependable than a file name
529 * and maintains a reference to the actual bytes loaded.
533 public void setFileObject(File file)
535 this.fileObject = file;
539 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
542 void addKeyListener()
544 addKeyListener(new KeyAdapter()
547 public void keyPressed(KeyEvent evt)
549 if (viewport.cursorMode
550 && ((evt.getKeyCode() >= KeyEvent.VK_0
551 && evt.getKeyCode() <= KeyEvent.VK_9)
552 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
553 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
554 && Character.isDigit(evt.getKeyChar()))
556 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
559 switch (evt.getKeyCode())
562 case 27: // escape key
563 deselectAllSequenceMenuItem_actionPerformed(null);
567 case KeyEvent.VK_DOWN:
568 if (evt.isAltDown() || !viewport.cursorMode)
570 moveSelectedSequences(false);
572 if (viewport.cursorMode)
574 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
579 if (evt.isAltDown() || !viewport.cursorMode)
581 moveSelectedSequences(true);
583 if (viewport.cursorMode)
585 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
590 case KeyEvent.VK_LEFT:
591 if (evt.isAltDown() || !viewport.cursorMode)
593 slideSequences(false,
594 alignPanel.getSeqPanel().getKeyboardNo1());
598 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
603 case KeyEvent.VK_RIGHT:
604 if (evt.isAltDown() || !viewport.cursorMode)
606 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
610 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
614 case KeyEvent.VK_SPACE:
615 if (viewport.cursorMode)
617 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
618 || evt.isShiftDown() || evt.isAltDown());
622 // case KeyEvent.VK_A:
623 // if (viewport.cursorMode)
625 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
626 // //System.out.println("A");
630 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
631 * System.out.println("closing bracket"); } break;
633 case KeyEvent.VK_DELETE:
634 case KeyEvent.VK_BACK_SPACE:
635 if (!viewport.cursorMode)
637 cut_actionPerformed();
641 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
642 || evt.isShiftDown() || evt.isAltDown());
648 if (viewport.cursorMode)
650 alignPanel.getSeqPanel().setCursorRow();
654 if (viewport.cursorMode && !evt.isControlDown())
656 alignPanel.getSeqPanel().setCursorColumn();
660 if (viewport.cursorMode)
662 alignPanel.getSeqPanel().setCursorPosition();
666 case KeyEvent.VK_ENTER:
667 case KeyEvent.VK_COMMA:
668 if (viewport.cursorMode)
670 alignPanel.getSeqPanel().setCursorRowAndColumn();
675 if (viewport.cursorMode)
677 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
681 if (viewport.cursorMode)
683 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
688 viewport.cursorMode = !viewport.cursorMode;
689 setStatus(MessageManager
690 .formatMessage("label.keyboard_editing_mode", new String[]
691 { (viewport.cursorMode ? "on" : "off") }));
692 if (viewport.cursorMode)
694 ViewportRanges ranges = viewport.getRanges();
695 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
697 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
700 alignPanel.getSeqPanel().seqCanvas.repaint();
706 Help.showHelpWindow();
707 } catch (Exception ex)
709 ex.printStackTrace();
714 boolean toggleSeqs = !evt.isControlDown();
715 boolean toggleCols = !evt.isShiftDown();
716 toggleHiddenRegions(toggleSeqs, toggleCols);
721 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
722 boolean modifyExisting = true; // always modify, don't clear
723 // evt.isShiftDown();
724 boolean invertHighlighted = evt.isAltDown();
725 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
729 case KeyEvent.VK_PAGE_UP:
730 viewport.getRanges().pageUp();
732 case KeyEvent.VK_PAGE_DOWN:
733 viewport.getRanges().pageDown();
739 public void keyReleased(KeyEvent evt)
741 switch (evt.getKeyCode())
743 case KeyEvent.VK_LEFT:
744 if (evt.isAltDown() || !viewport.cursorMode)
746 viewport.firePropertyChange("alignment", null,
747 viewport.getAlignment().getSequences());
751 case KeyEvent.VK_RIGHT:
752 if (evt.isAltDown() || !viewport.cursorMode)
754 viewport.firePropertyChange("alignment", null,
755 viewport.getAlignment().getSequences());
763 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
765 ap.alignFrame = this;
766 avc = new jalview.controller.AlignViewController(this, viewport,
771 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
773 int aSize = alignPanels.size();
775 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
777 if (aSize == 1 && ap.av.getViewName() == null)
779 this.getContentPane().add(ap, BorderLayout.CENTER);
785 setInitialTabVisible();
788 expandViews.setEnabled(true);
789 gatherViews.setEnabled(true);
790 tabbedPane.addTab(ap.av.getViewName(), ap);
792 ap.setVisible(false);
797 if (ap.av.isPadGaps())
799 ap.av.getAlignment().padGaps();
801 ap.av.updateConservation(ap);
802 ap.av.updateConsensus(ap);
803 ap.av.updateStrucConsensus(ap);
807 public void setInitialTabVisible()
809 expandViews.setEnabled(true);
810 gatherViews.setEnabled(true);
811 tabbedPane.setVisible(true);
812 AlignmentPanel first = alignPanels.get(0);
813 tabbedPane.addTab(first.av.getViewName(), first);
814 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
817 public AlignViewport getViewport()
822 /* Set up intrinsic listeners for dynamically generated GUI bits. */
823 private void addServiceListeners()
825 final java.beans.PropertyChangeListener thisListener;
826 Desktop.instance.addJalviewPropertyChangeListener("services",
827 thisListener = new java.beans.PropertyChangeListener()
830 public void propertyChange(PropertyChangeEvent evt)
832 // // System.out.println("Discoverer property change.");
833 // if (evt.getPropertyName().equals("services"))
835 SwingUtilities.invokeLater(new Runnable()
842 "Rebuild WS Menu for service change");
843 BuildWebServiceMenu();
850 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
853 public void internalFrameClosed(
854 javax.swing.event.InternalFrameEvent evt)
856 // System.out.println("deregistering discoverer listener");
857 Desktop.instance.removeJalviewPropertyChangeListener("services",
859 closeMenuItem_actionPerformed(true);
862 // Finally, build the menu once to get current service state
863 new Thread(new Runnable()
868 BuildWebServiceMenu();
874 * Configure menu items that vary according to whether the alignment is
875 * nucleotide or protein
877 public void setGUINucleotide()
879 AlignmentI al = getViewport().getAlignment();
880 boolean nucleotide = al.isNucleotide();
882 loadVcf.setVisible(nucleotide);
883 showTranslation.setVisible(nucleotide);
884 showReverse.setVisible(nucleotide);
885 showReverseComplement.setVisible(nucleotide);
886 conservationMenuItem.setEnabled(!nucleotide);
888 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
889 showGroupConservation.setEnabled(!nucleotide);
891 showComplementMenuItem
892 .setText(nucleotide ? MessageManager.getString("label.protein")
893 : MessageManager.getString("label.nucleotide"));
897 * set up menus for the current viewport. This may be called after any
898 * operation that affects the data in the current view (selection changed,
899 * etc) to update the menus to reflect the new state.
902 public void setMenusForViewport()
904 setMenusFromViewport(viewport);
908 * Need to call this method when tabs are selected for multiple views, or when
909 * loading from Jalview2XML.java
914 public void setMenusFromViewport(AlignViewport av)
916 padGapsMenuitem.setSelected(av.isPadGaps());
917 colourTextMenuItem.setSelected(av.isShowColourText());
918 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
919 modifyPID.setEnabled(abovePIDThreshold.isSelected());
920 conservationMenuItem.setSelected(av.getConservationSelected());
921 modifyConservation.setEnabled(conservationMenuItem.isSelected());
922 seqLimits.setSelected(av.getShowJVSuffix());
923 idRightAlign.setSelected(av.isRightAlignIds());
924 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
925 renderGapsMenuItem.setSelected(av.isRenderGaps());
926 wrapMenuItem.setSelected(av.getWrapAlignment());
927 scaleAbove.setVisible(av.getWrapAlignment());
928 scaleLeft.setVisible(av.getWrapAlignment());
929 scaleRight.setVisible(av.getWrapAlignment());
930 annotationPanelMenuItem.setState(av.isShowAnnotation());
932 * Show/hide annotations only enabled if annotation panel is shown
934 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
935 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
936 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 viewBoxesMenuItem.setSelected(av.getShowBoxes());
939 viewTextMenuItem.setSelected(av.getShowText());
940 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
941 showGroupConsensus.setSelected(av.isShowGroupConsensus());
942 showGroupConservation.setSelected(av.isShowGroupConservation());
943 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
944 showSequenceLogo.setSelected(av.isShowSequenceLogo());
945 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
947 ColourMenuHelper.setColourSelected(colourMenu,
948 av.getGlobalColourScheme());
950 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
951 hiddenMarkers.setState(av.getShowHiddenMarkers());
952 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
953 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
954 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
955 autoCalculate.setSelected(av.autoCalculateConsensus);
956 sortByTree.setSelected(av.sortByTree);
957 listenToViewSelections.setSelected(av.followSelection);
959 showProducts.setEnabled(canShowProducts());
960 setGroovyEnabled(Desktop.getGroovyConsole() != null);
966 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
970 public void setGroovyEnabled(boolean b)
972 runGroovy.setEnabled(b);
975 private IProgressIndicator progressBar;
980 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
983 public void setProgressBar(String message, long id)
985 if (!Platform.isHeadless() && progressBar != null)
986 progressBar.setProgressBar(message, id);
990 public void registerHandler(final long id,
991 final IProgressIndicatorHandler handler)
993 if (progressBar != null)
994 progressBar.registerHandler(id, handler);
999 * @return true if any progress bars are still active
1002 public boolean operationInProgress()
1004 return progressBar == null ? false : progressBar.operationInProgress();
1008 * Sets the text of the status bar. Note that setting a null or empty value
1009 * will cause the status bar to be hidden, with possibly undesirable flicker
1010 * of the screen layout.
1013 public void setStatus(String text)
1015 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1019 * Added so Castor Mapping file can obtain Jalview Version
1021 public String getVersion()
1023 return Cache.getProperty("VERSION");
1026 public FeatureRenderer getFeatureRenderer()
1028 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1032 public void fetchSequence_actionPerformed()
1034 new SequenceFetcher(this);
1038 public void addFromFile_actionPerformed(ActionEvent e)
1040 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1044 public void reload_actionPerformed(ActionEvent e)
1046 if (fileName != null)
1048 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1049 // originating file's format
1050 // TODO: work out how to recover feature settings for correct view(s) when
1051 // file is reloaded.
1052 if (FileFormat.Jalview.equals(currentFileFormat))
1054 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1055 for (int i = 0; i < frames.length; i++)
1057 if (frames[i] instanceof AlignFrame && frames[i] != this
1058 && ((AlignFrame) frames[i]).fileName != null
1059 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1063 frames[i].setSelected(true);
1064 Desktop.instance.closeAssociatedWindows();
1065 } catch (java.beans.PropertyVetoException ex)
1071 Desktop.instance.closeAssociatedWindows();
1073 FileLoader loader = new FileLoader();
1074 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1075 ? DataSourceType.URL
1076 : DataSourceType.FILE;
1077 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1081 Rectangle bounds = this.getBounds();
1083 FileLoader loader = new FileLoader();
1085 AlignFrame newframe = null;
1087 if (fileObject == null)
1090 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1091 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1092 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1097 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1098 DataSourceType.FILE, currentFileFormat);
1101 newframe.setBounds(bounds);
1102 if (featureSettings != null && featureSettings.isShowing())
1104 final Rectangle fspos = featureSettings.frame.getBounds();
1105 // TODO: need a 'show feature settings' function that takes bounds -
1106 // need to refactor Desktop.addFrame
1107 newframe.featureSettings_actionPerformed(null);
1108 final FeatureSettings nfs = newframe.featureSettings;
1109 SwingUtilities.invokeLater(new Runnable()
1114 nfs.frame.setBounds(fspos);
1117 this.featureSettings.close();
1118 this.featureSettings = null;
1120 this.closeMenuItem_actionPerformed(true);
1126 public void addFromText_actionPerformed(ActionEvent e)
1129 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1133 public void addFromURL_actionPerformed(ActionEvent e)
1135 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1139 public void save_actionPerformed(ActionEvent e)
1141 if (fileName == null || (currentFileFormat == null)
1142 || HttpUtils.startsWithHttpOrHttps(fileName))
1144 saveAs_actionPerformed();
1148 saveAlignment(fileName, currentFileFormat);
1153 * Saves the alignment to a file with a name chosen by the user, if necessary
1154 * warning if a file would be overwritten
1157 public void saveAs_actionPerformed()
1159 String format = currentFileFormat == null ? null
1160 : currentFileFormat.getName();
1161 JalviewFileChooser chooser = JalviewFileChooser
1162 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1164 chooser.setFileView(new JalviewFileView());
1165 chooser.setDialogTitle(
1166 MessageManager.getString("label.save_alignment_to_file"));
1167 chooser.setToolTipText(MessageManager.getString("action.save"));
1169 int value = chooser.showSaveDialog(this);
1171 if (value != JalviewFileChooser.APPROVE_OPTION)
1175 currentFileFormat = chooser.getSelectedFormat();
1176 // todo is this (2005) test now obsolete - value is never null?
1177 while (currentFileFormat == null)
1179 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1181 .getString("label.select_file_format_before_saving"),
1182 MessageManager.getString("label.file_format_not_specified"),
1183 JvOptionPane.WARNING_MESSAGE);
1184 currentFileFormat = chooser.getSelectedFormat();
1185 value = chooser.showSaveDialog(this);
1186 if (value != JalviewFileChooser.APPROVE_OPTION)
1192 fileName = chooser.getSelectedFile().getPath();
1194 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1195 Cache.setProperty("LAST_DIRECTORY", fileName);
1196 saveAlignment(fileName, currentFileFormat);
1199 boolean lastSaveSuccessful = false;
1201 FileFormatI lastFormatSaved;
1203 String lastFilenameSaved;
1206 * Raise a dialog or status message for the last call to saveAlignment.
1208 * @return true if last call to saveAlignment(file, format) was successful.
1210 public boolean isSaveAlignmentSuccessful()
1213 if (!lastSaveSuccessful)
1215 if (!Platform.isHeadless())
1217 JvOptionPane.showInternalMessageDialog(this, MessageManager
1218 .formatMessage("label.couldnt_save_file", new Object[]
1219 { lastFilenameSaved }),
1220 MessageManager.getString("label.error_saving_file"),
1221 JvOptionPane.WARNING_MESSAGE);
1225 Console.error(MessageManager
1226 .formatMessage("label.couldnt_save_file", new Object[]
1227 { lastFilenameSaved }));
1233 setStatus(MessageManager.formatMessage(
1234 "label.successfully_saved_to_file_in_format", new Object[]
1235 { lastFilenameSaved, lastFormatSaved }));
1238 return lastSaveSuccessful;
1242 * Saves the alignment to the specified file path, in the specified format,
1243 * which may be an alignment format, or Jalview project format. If the
1244 * alignment has hidden regions, or the format is one capable of including
1245 * non-sequence data (features, annotations, groups), then the user may be
1246 * prompted to specify what to include in the output.
1251 public void saveAlignment(String file, FileFormatI format)
1253 lastSaveSuccessful = true;
1254 lastFilenameSaved = file;
1255 lastFormatSaved = format;
1257 if (FileFormat.Jalview.equals(format))
1259 String shortName = title;
1260 if (shortName.indexOf(File.separatorChar) > -1)
1262 shortName = shortName
1263 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1265 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1268 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1269 if (lastSaveSuccessful)
1271 this.getViewport().setSavedUpToDate(true);
1274 statusBar.setText(MessageManager.formatMessage(
1275 "label.successfully_saved_to_file_in_format", new Object[]
1281 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1282 Runnable cancelAction = () -> {
1283 lastSaveSuccessful = false;
1285 Runnable outputAction = () -> {
1286 // todo defer this to inside formatSequences (or later)
1287 AlignmentExportData exportData = viewport.getAlignExportData(options);
1288 String output = new FormatAdapter(alignPanel, options)
1289 .formatSequences(format, exportData.getAlignment(),
1290 exportData.getOmitHidden(),
1291 exportData.getStartEndPostions(),
1292 viewport.getAlignment().getHiddenColumns());
1295 lastSaveSuccessful = false;
1299 // create backupfiles object and get new temp filename destination
1300 boolean doBackup = BackupFiles.getEnabled();
1301 BackupFiles backupfiles = null;
1304 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1305 backupfiles = new BackupFiles(file);
1309 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1311 Console.trace("ALIGNFRAME setting PrintWriter");
1312 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1314 if (backupfiles != null)
1316 Console.trace("ALIGNFRAME about to write to temp file "
1317 + backupfiles.getTempFilePath());
1321 Console.trace("ALIGNFRAME about to close file");
1323 Console.trace("ALIGNFRAME closed file");
1324 AlignFrame.this.setTitle(file);
1325 statusBar.setText(MessageManager.formatMessage(
1326 "label.successfully_saved_to_file_in_format", new Object[]
1327 { fileName, format.getName() }));
1328 lastSaveSuccessful = true;
1329 } catch (IOException e)
1331 lastSaveSuccessful = false;
1333 "ALIGNFRAME Something happened writing the temp file");
1334 Console.error(e.getMessage());
1335 Console.debug(Cache.getStackTraceString(e));
1336 } catch (Exception ex)
1338 lastSaveSuccessful = false;
1340 "ALIGNFRAME Something unexpected happened writing the temp file");
1341 Console.error(ex.getMessage());
1342 Console.debug(Cache.getStackTraceString(ex));
1347 backupfiles.setWriteSuccess(lastSaveSuccessful);
1348 Console.debug("ALIGNFRAME writing temp file was "
1349 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1350 // do the backup file roll and rename the temp file to actual file
1351 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1352 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1353 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1354 + (lastSaveSuccessful ? "" : "un") + "successfully");
1357 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1358 if (lastSaveSuccessful)
1360 AlignFrame.this.getViewport().setSavedUpToDate(true);
1366 * show dialog with export options if applicable; else just do it
1368 if (AlignExportOptions.isNeeded(viewport, format))
1370 AlignExportOptions choices = new AlignExportOptions(
1371 alignPanel.getAlignViewport(), format, options);
1372 choices.setResponseAction(0, outputAction);
1373 choices.setResponseAction(1, cancelAction);
1374 choices.showDialog();
1381 } catch (Exception e)
1383 // TODO Auto-generated catch block
1384 e.printStackTrace();
1390 * Outputs the alignment to textbox in the requested format, if necessary
1391 * first prompting the user for whether to include hidden regions or
1394 * @param fileFormatName
1397 protected void outputText_actionPerformed(String fileFormatName)
1399 FileFormatI fileFormat = FileFormats.getInstance()
1400 .forName(fileFormatName);
1401 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1402 Runnable outputAction = () -> {
1403 // todo defer this to inside formatSequences (or later)
1404 AlignmentExportData exportData = viewport.getAlignExportData(options);
1405 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1406 cap.setForInput(null);
1409 FileFormatI format = fileFormat;
1410 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1411 format, exportData.getAlignment(),
1412 exportData.getOmitHidden(),
1413 exportData.getStartEndPostions(),
1414 viewport.getAlignment().getHiddenColumns()));
1415 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1416 "label.alignment_output_command", new Object[]
1417 { fileFormat.getName() }), 600, 500);
1418 } catch (OutOfMemoryError oom)
1420 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1427 * show dialog with export options if applicable; else just do it
1429 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1431 AlignExportOptions choices = new AlignExportOptions(
1432 alignPanel.getAlignViewport(), fileFormat, options);
1433 choices.setResponseAction(0, outputAction);
1434 choices.showDialog();
1441 } catch (Exception e)
1443 e.printStackTrace();
1455 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1457 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1460 htmlSVG.exportHTML(null);
1461 } catch (ImageOutputException x)
1463 // report problem to console and raise dialog
1468 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1470 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1473 bjs.exportHTML(null);
1474 } catch (ImageOutputException x)
1476 // report problem to console and raise dialog
1480 public void createImageMap(File file, String image)
1484 alignPanel.makePNGImageMap(file, image);
1485 } catch (ImageOutputException x)
1487 // report problem to console and raise dialog
1492 public void createPNG_actionPerformed(ActionEvent e)
1497 } catch (ImageOutputException ioex)
1499 // raise dialog, and report via console
1504 public void createEPS_actionPerformed(ActionEvent e)
1509 } catch (ImageOutputException ioex)
1511 // raise dialog, and report via console
1517 public void createSVG_actionPerformed(ActionEvent e)
1522 } catch (ImageOutputException ioex)
1524 // raise dialog, and report via console
1530 * Creates a PNG image of the alignment and writes it to the given file. If
1531 * the file is null, the user is prompted to choose a file.
1535 public void createPNG(File f) throws ImageOutputException
1537 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1540 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1541 throws ImageOutputException
1543 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1547 * Creates an EPS image of the alignment and writes it to the given file. If
1548 * the file is null, the user is prompted to choose a file.
1552 public void createEPS(File f) throws ImageOutputException
1557 public void createEPS(File f, String renderer) throws ImageOutputException
1559 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1563 * Creates an SVG image of the alignment and writes it to the given file. If
1564 * the file is null, the user is prompted to choose a file.
1568 public void createSVG(File f) throws ImageOutputException
1573 public void createSVG(File f, String renderer) throws ImageOutputException
1575 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1579 public void pageSetup_actionPerformed(ActionEvent e)
1581 PrinterJob printJob = PrinterJob.getPrinterJob();
1582 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1592 public void printMenuItem_actionPerformed(ActionEvent e)
1594 // Putting in a thread avoids Swing painting problems
1595 PrintThread thread = new PrintThread(alignPanel);
1600 public void exportFeatures_actionPerformed(ActionEvent e)
1602 new AnnotationExporter(alignPanel).exportFeatures();
1606 public void exportAnnotations_actionPerformed(ActionEvent e)
1608 new AnnotationExporter(alignPanel).exportAnnotations();
1612 public void associatedData_actionPerformed(ActionEvent e)
1614 final JalviewFileChooser chooser = new JalviewFileChooser(
1615 Cache.getProperty("LAST_DIRECTORY"));
1616 chooser.setFileView(new JalviewFileView());
1617 String tooltip = MessageManager
1618 .getString("label.load_jalview_annotations");
1619 chooser.setDialogTitle(tooltip);
1620 chooser.setToolTipText(tooltip);
1621 chooser.setResponseHandler(0, () -> {
1622 String choice = chooser.getSelectedFile().getPath();
1623 Cache.setProperty("LAST_DIRECTORY", choice);
1624 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1627 chooser.showOpenDialog(this);
1631 * Close the current view or all views in the alignment frame. If the frame
1632 * only contains one view then the alignment will be removed from memory.
1634 * @param closeAllTabs
1637 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1639 if (alignPanels != null && alignPanels.size() < 2)
1641 closeAllTabs = true;
1646 if (alignPanels != null)
1650 if (this.isClosed())
1652 // really close all the windows - otherwise wait till
1653 // setClosed(true) is called
1654 for (int i = 0; i < alignPanels.size(); i++)
1656 AlignmentPanel ap = alignPanels.get(i);
1663 closeView(alignPanel);
1668 if (featureSettings != null && featureSettings.isOpen())
1670 featureSettings.close();
1671 featureSettings = null;
1674 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1675 * be called recursively, with the frame now in 'closed' state
1677 this.setClosed(true);
1679 } catch (Exception ex)
1681 ex.printStackTrace();
1686 * Close the specified panel and close up tabs appropriately.
1688 * @param panelToClose
1690 public void closeView(AlignmentPanel panelToClose)
1692 int index = tabbedPane.getSelectedIndex();
1693 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1694 alignPanels.remove(panelToClose);
1695 panelToClose.closePanel();
1696 panelToClose = null;
1698 tabbedPane.removeTabAt(closedindex);
1699 tabbedPane.validate();
1701 if (index > closedindex || index == tabbedPane.getTabCount())
1703 // modify currently selected tab index if necessary.
1707 this.tabSelectionChanged(index);
1713 void updateEditMenuBar()
1716 if (viewport.getHistoryList().size() > 0)
1718 undoMenuItem.setEnabled(true);
1719 CommandI command = viewport.getHistoryList().peek();
1720 undoMenuItem.setText(MessageManager
1721 .formatMessage("label.undo_command", new Object[]
1722 { command.getDescription() }));
1726 undoMenuItem.setEnabled(false);
1727 undoMenuItem.setText(MessageManager.getString("action.undo"));
1730 if (viewport.getRedoList().size() > 0)
1732 redoMenuItem.setEnabled(true);
1734 CommandI command = viewport.getRedoList().peek();
1735 redoMenuItem.setText(MessageManager
1736 .formatMessage("label.redo_command", new Object[]
1737 { command.getDescription() }));
1741 redoMenuItem.setEnabled(false);
1742 redoMenuItem.setText(MessageManager.getString("action.redo"));
1747 public void addHistoryItem(CommandI command)
1749 if (command.getSize() > 0)
1751 viewport.addToHistoryList(command);
1752 viewport.clearRedoList();
1753 updateEditMenuBar();
1754 viewport.updateHiddenColumns();
1755 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1756 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1757 // viewport.getColumnSelection()
1758 // .getHiddenColumns().size() > 0);
1764 * @return alignment objects for all views
1766 AlignmentI[] getViewAlignments()
1768 if (alignPanels != null)
1770 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1772 for (AlignmentPanel ap : alignPanels)
1774 als[i++] = ap.av.getAlignment();
1778 if (viewport != null)
1780 return new AlignmentI[] { viewport.getAlignment() };
1792 protected void undoMenuItem_actionPerformed(ActionEvent e)
1794 if (viewport.getHistoryList().isEmpty())
1798 CommandI command = viewport.getHistoryList().pop();
1799 viewport.addToRedoList(command);
1800 command.undoCommand(getViewAlignments());
1802 AlignmentViewport originalSource = getOriginatingSource(command);
1803 updateEditMenuBar();
1805 if (originalSource != null)
1807 if (originalSource != viewport)
1810 "Implementation worry: mismatch of viewport origin for undo");
1812 originalSource.updateHiddenColumns();
1813 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1815 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1816 // viewport.getColumnSelection()
1817 // .getHiddenColumns().size() > 0);
1818 originalSource.firePropertyChange("alignment", null,
1819 originalSource.getAlignment().getSequences());
1830 protected void redoMenuItem_actionPerformed(ActionEvent e)
1832 if (viewport.getRedoList().size() < 1)
1837 CommandI command = viewport.getRedoList().pop();
1838 viewport.addToHistoryList(command);
1839 command.doCommand(getViewAlignments());
1841 AlignmentViewport originalSource = getOriginatingSource(command);
1842 updateEditMenuBar();
1844 if (originalSource != null)
1847 if (originalSource != viewport)
1850 "Implementation worry: mismatch of viewport origin for redo");
1852 originalSource.updateHiddenColumns();
1853 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1855 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1856 // viewport.getColumnSelection()
1857 // .getHiddenColumns().size() > 0);
1858 originalSource.firePropertyChange("alignment", null,
1859 originalSource.getAlignment().getSequences());
1863 AlignmentViewport getOriginatingSource(CommandI command)
1865 AlignmentViewport originalSource = null;
1866 // For sequence removal and addition, we need to fire
1867 // the property change event FROM the viewport where the
1868 // original alignment was altered
1869 AlignmentI al = null;
1870 if (command instanceof EditCommand)
1872 EditCommand editCommand = (EditCommand) command;
1873 al = editCommand.getAlignment();
1874 List<Component> comps = PaintRefresher.components
1875 .get(viewport.getSequenceSetId());
1877 for (Component comp : comps)
1879 if (comp instanceof AlignmentPanel)
1881 if (al == ((AlignmentPanel) comp).av.getAlignment())
1883 originalSource = ((AlignmentPanel) comp).av;
1890 if (originalSource == null)
1892 // The original view is closed, we must validate
1893 // the current view against the closed view first
1896 PaintRefresher.validateSequences(al, viewport.getAlignment());
1899 originalSource = viewport;
1902 return originalSource;
1906 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1907 * or the sequence under cursor in keyboard mode
1912 public void moveSelectedSequences(boolean up)
1914 SequenceGroup sg = viewport.getSelectionGroup();
1918 if (viewport.cursorMode)
1920 sg = new SequenceGroup();
1921 sg.addSequence(viewport.getAlignment().getSequenceAt(
1922 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1930 if (sg.getSize() < 1)
1935 // TODO: JAL-3733 - add an event to the undo buffer for this !
1937 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1938 viewport.getHiddenRepSequences(), up);
1939 alignPanel.paintAlignment(true, false);
1942 synchronized void slideSequences(boolean right, int size)
1944 List<SequenceI> sg = new ArrayList<>();
1945 if (viewport.cursorMode)
1947 sg.add(viewport.getAlignment()
1948 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1950 else if (viewport.getSelectionGroup() != null
1951 && viewport.getSelectionGroup().getSize() != viewport
1952 .getAlignment().getHeight())
1954 sg = viewport.getSelectionGroup()
1955 .getSequences(viewport.getHiddenRepSequences());
1963 List<SequenceI> invertGroup = new ArrayList<>();
1965 for (SequenceI seq : viewport.getAlignment().getSequences())
1967 if (!sg.contains(seq))
1969 invertGroup.add(seq);
1973 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1975 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1976 for (int i = 0; i < invertGroup.size(); i++)
1978 seqs2[i] = invertGroup.get(i);
1981 SlideSequencesCommand ssc;
1984 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1985 viewport.getGapCharacter());
1989 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1990 viewport.getGapCharacter());
1993 int groupAdjustment = 0;
1994 if (ssc.getGapsInsertedBegin() && right)
1996 if (viewport.cursorMode)
1998 alignPanel.getSeqPanel().moveCursor(size, 0);
2002 groupAdjustment = size;
2005 else if (!ssc.getGapsInsertedBegin() && !right)
2007 if (viewport.cursorMode)
2009 alignPanel.getSeqPanel().moveCursor(-size, 0);
2013 groupAdjustment = -size;
2017 if (groupAdjustment != 0)
2019 viewport.getSelectionGroup().setStartRes(
2020 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2021 viewport.getSelectionGroup().setEndRes(
2022 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2026 * just extend the last slide command if compatible; but not if in
2027 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2029 boolean appendHistoryItem = false;
2030 Deque<CommandI> historyList = viewport.getHistoryList();
2031 boolean inSplitFrame = getSplitViewContainer() != null;
2032 if (!inSplitFrame && historyList != null && historyList.size() > 0
2033 && historyList.peek() instanceof SlideSequencesCommand)
2035 appendHistoryItem = ssc.appendSlideCommand(
2036 (SlideSequencesCommand) historyList.peek());
2039 if (!appendHistoryItem)
2041 addHistoryItem(ssc);
2054 protected void copy_actionPerformed()
2056 if (viewport.getSelectionGroup() == null)
2060 // TODO: preserve the ordering of displayed alignment annotation in any
2061 // internal paste (particularly sequence associated annotation)
2062 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2063 String[] omitHidden = null;
2065 if (viewport.hasHiddenColumns())
2067 omitHidden = viewport.getViewAsString(true);
2070 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2071 seqs, omitHidden, null);
2073 StringSelection ss = new StringSelection(output);
2077 jalview.gui.Desktop.internalCopy = true;
2078 // Its really worth setting the clipboard contents
2079 // to empty before setting the large StringSelection!!
2080 Toolkit.getDefaultToolkit().getSystemClipboard()
2081 .setContents(new StringSelection(""), null);
2083 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2085 } catch (OutOfMemoryError er)
2087 new OOMWarning("copying region", er);
2091 HiddenColumns hiddenColumns = null;
2092 if (viewport.hasHiddenColumns())
2094 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2095 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2097 // create new HiddenColumns object with copy of hidden regions
2098 // between startRes and endRes, offset by startRes
2099 hiddenColumns = new HiddenColumns(
2100 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2101 hiddenCutoff, hiddenOffset);
2104 Desktop.jalviewClipboard = new Object[] { seqs,
2105 viewport.getAlignment().getDataset(), hiddenColumns };
2106 setStatus(MessageManager.formatMessage(
2107 "label.copied_sequences_to_clipboard", new Object[]
2108 { Integer.valueOf(seqs.length).toString() }));
2118 protected void pasteNew_actionPerformed(ActionEvent e)
2130 protected void pasteThis_actionPerformed(ActionEvent e)
2136 * Paste contents of Jalview clipboard
2138 * @param newAlignment
2139 * true to paste to a new alignment, otherwise add to this.
2141 void paste(boolean newAlignment)
2143 boolean externalPaste = true;
2146 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2147 Transferable contents = c.getContents(this);
2149 if (contents == null)
2158 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2159 if (str.length() < 1)
2164 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2166 } catch (OutOfMemoryError er)
2168 new OOMWarning("Out of memory pasting sequences!!", er);
2172 SequenceI[] sequences;
2173 boolean annotationAdded = false;
2174 AlignmentI alignment = null;
2176 if (Desktop.jalviewClipboard != null)
2178 // The clipboard was filled from within Jalview, we must use the
2180 // And dataset from the copied alignment
2181 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2182 // be doubly sure that we create *new* sequence objects.
2183 sequences = new SequenceI[newseq.length];
2184 for (int i = 0; i < newseq.length; i++)
2186 sequences[i] = new Sequence(newseq[i]);
2188 alignment = new Alignment(sequences);
2189 externalPaste = false;
2193 // parse the clipboard as an alignment.
2194 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2196 sequences = alignment.getSequencesArray();
2200 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2206 if (Desktop.jalviewClipboard != null)
2208 // dataset is inherited
2209 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2213 // new dataset is constructed
2214 alignment.setDataset(null);
2216 alwidth = alignment.getWidth() + 1;
2220 AlignmentI pastedal = alignment; // preserve pasted alignment object
2221 // Add pasted sequences and dataset into existing alignment.
2222 alignment = viewport.getAlignment();
2223 alwidth = alignment.getWidth() + 1;
2224 // decide if we need to import sequences from an existing dataset
2225 boolean importDs = Desktop.jalviewClipboard != null
2226 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2227 // importDs==true instructs us to copy over new dataset sequences from
2228 // an existing alignment
2229 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2231 // minimum dataset set
2233 for (int i = 0; i < sequences.length; i++)
2237 newDs.addElement(null);
2239 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2241 if (importDs && ds != null)
2243 if (!newDs.contains(ds))
2245 newDs.setElementAt(ds, i);
2246 ds = new Sequence(ds);
2247 // update with new dataset sequence
2248 sequences[i].setDatasetSequence(ds);
2252 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2257 // copy and derive new dataset sequence
2258 sequences[i] = sequences[i].deriveSequence();
2259 alignment.getDataset()
2260 .addSequence(sequences[i].getDatasetSequence());
2261 // TODO: avoid creation of duplicate dataset sequences with a
2262 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2264 alignment.addSequence(sequences[i]); // merges dataset
2268 newDs.clear(); // tidy up
2270 if (alignment.getAlignmentAnnotation() != null)
2272 for (AlignmentAnnotation alan : alignment
2273 .getAlignmentAnnotation())
2275 if (alan.graphGroup > fgroup)
2277 fgroup = alan.graphGroup;
2281 if (pastedal.getAlignmentAnnotation() != null)
2283 // Add any annotation attached to alignment.
2284 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2285 for (int i = 0; i < alann.length; i++)
2287 annotationAdded = true;
2288 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2290 AlignmentAnnotation newann = new AlignmentAnnotation(
2292 if (newann.graphGroup > -1)
2294 if (newGraphGroups.size() <= newann.graphGroup
2295 || newGraphGroups.get(newann.graphGroup) == null)
2297 for (int q = newGraphGroups
2298 .size(); q <= newann.graphGroup; q++)
2300 newGraphGroups.add(q, null);
2302 newGraphGroups.set(newann.graphGroup,
2303 Integer.valueOf(++fgroup));
2305 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2309 newann.padAnnotation(alwidth);
2310 alignment.addAnnotation(newann);
2320 addHistoryItem(new EditCommand(
2321 MessageManager.getString("label.add_sequences"),
2322 Action.PASTE, sequences, 0, alignment.getWidth(),
2325 // Add any annotations attached to sequences
2326 for (int i = 0; i < sequences.length; i++)
2328 if (sequences[i].getAnnotation() != null)
2330 AlignmentAnnotation newann;
2331 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2333 annotationAdded = true;
2334 newann = sequences[i].getAnnotation()[a];
2335 newann.adjustForAlignment();
2336 newann.padAnnotation(alwidth);
2337 if (newann.graphGroup > -1)
2339 if (newann.graphGroup > -1)
2341 if (newGraphGroups.size() <= newann.graphGroup
2342 || newGraphGroups.get(newann.graphGroup) == null)
2344 for (int q = newGraphGroups
2345 .size(); q <= newann.graphGroup; q++)
2347 newGraphGroups.add(q, null);
2349 newGraphGroups.set(newann.graphGroup,
2350 Integer.valueOf(++fgroup));
2352 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2356 // annotation was duplicated earlier
2357 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2358 // take care of contact matrix too
2359 ContactMatrixI cm = sequences[i]
2360 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2363 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2367 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2375 // propagate alignment changed.
2376 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2377 if (annotationAdded)
2379 // Duplicate sequence annotation in all views.
2380 AlignmentI[] alview = this.getViewAlignments();
2381 for (int i = 0; i < sequences.length; i++)
2383 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2388 for (int avnum = 0; avnum < alview.length; avnum++)
2390 if (alview[avnum] != alignment)
2392 // duplicate in a view other than the one with input focus
2393 int avwidth = alview[avnum].getWidth() + 1;
2394 // this relies on sann being preserved after we
2395 // modify the sequence's annotation array for each duplication
2396 for (int a = 0; a < sann.length; a++)
2398 AlignmentAnnotation newann = new AlignmentAnnotation(
2400 sequences[i].addAlignmentAnnotation(newann);
2401 newann.padAnnotation(avwidth);
2402 alview[avnum].addAnnotation(newann); // annotation was
2403 // duplicated earlier
2404 // TODO JAL-1145 graphGroups are not updated for sequence
2405 // annotation added to several views. This may cause
2407 alview[avnum].setAnnotationIndex(newann, a);
2412 buildSortByAnnotationScoresMenu();
2414 viewport.firePropertyChange("alignment", null,
2415 alignment.getSequences());
2416 if (alignPanels != null)
2418 for (AlignmentPanel ap : alignPanels)
2420 ap.validateAnnotationDimensions(false);
2425 alignPanel.validateAnnotationDimensions(false);
2431 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2433 String newtitle = new String("Copied sequences");
2435 if (Desktop.jalviewClipboard != null
2436 && Desktop.jalviewClipboard[2] != null)
2438 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2439 af.viewport.setHiddenColumns(hc);
2442 // >>>This is a fix for the moment, until a better solution is
2444 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2445 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2446 .getFeatureRenderer());
2448 // TODO: maintain provenance of an alignment, rather than just make the
2449 // title a concatenation of operations.
2452 if (title.startsWith("Copied sequences"))
2458 newtitle = newtitle.concat("- from " + title);
2463 newtitle = new String("Pasted sequences");
2466 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2471 } catch (Exception ex)
2473 ex.printStackTrace();
2474 System.out.println("Exception whilst pasting: " + ex);
2475 // could be anything being pasted in here
2481 protected void expand_newalign(ActionEvent e)
2485 AlignmentI alignment = AlignmentUtils
2486 .expandContext(getViewport().getAlignment(), -1);
2487 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2489 String newtitle = new String("Flanking alignment");
2491 if (Desktop.jalviewClipboard != null
2492 && Desktop.jalviewClipboard[2] != null)
2494 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2495 af.viewport.setHiddenColumns(hc);
2498 // >>>This is a fix for the moment, until a better solution is
2500 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2501 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2502 .getFeatureRenderer());
2504 // TODO: maintain provenance of an alignment, rather than just make the
2505 // title a concatenation of operations.
2507 if (title.startsWith("Copied sequences"))
2513 newtitle = newtitle.concat("- from " + title);
2517 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2519 } catch (Exception ex)
2521 ex.printStackTrace();
2522 System.out.println("Exception whilst pasting: " + ex);
2523 // could be anything being pasted in here
2524 } catch (OutOfMemoryError oom)
2526 new OOMWarning("Viewing flanking region of alignment", oom);
2531 * Action Cut (delete and copy) the selected region
2534 protected void cut_actionPerformed()
2536 copy_actionPerformed();
2537 delete_actionPerformed();
2541 * Performs menu option to Delete the currently selected region
2544 protected void delete_actionPerformed()
2547 SequenceGroup sg = viewport.getSelectionGroup();
2553 Runnable okAction = () -> {
2554 SequenceI[] cut = sg.getSequences()
2555 .toArray(new SequenceI[sg.getSize()]);
2557 addHistoryItem(new EditCommand(
2558 MessageManager.getString("label.cut_sequences"), Action.CUT,
2559 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2560 viewport.getAlignment()));
2562 viewport.setSelectionGroup(null);
2563 viewport.sendSelection();
2564 viewport.getAlignment().deleteGroup(sg);
2566 viewport.firePropertyChange("alignment", null,
2567 viewport.getAlignment().getSequences());
2568 if (viewport.getAlignment().getHeight() < 1)
2572 AlignFrame.this.setClosed(true);
2573 } catch (Exception ex)
2580 * If the cut affects all sequences, prompt for confirmation
2582 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2584 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2585 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2586 if (wholeHeight && wholeWidth)
2588 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2589 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2590 Object[] options = new Object[] {
2591 MessageManager.getString("action.ok"),
2592 MessageManager.getString("action.cancel") };
2593 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2594 MessageManager.getString("label.delete_all"),
2595 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2596 options, options[0]);
2603 } catch (Exception e)
2605 e.printStackTrace();
2617 protected void deleteGroups_actionPerformed(ActionEvent e)
2619 if (avc.deleteGroups())
2621 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2622 alignPanel.updateAnnotation();
2623 alignPanel.paintAlignment(true, true);
2634 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2636 SequenceGroup sg = new SequenceGroup(
2637 viewport.getAlignment().getSequences());
2639 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2640 viewport.setSelectionGroup(sg);
2641 viewport.isSelectionGroupChanged(true);
2642 viewport.sendSelection();
2643 // JAL-2034 - should delegate to
2644 // alignPanel to decide if overview needs
2646 alignPanel.paintAlignment(false, false);
2647 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2657 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2659 if (viewport.cursorMode)
2661 alignPanel.getSeqPanel().keyboardNo1 = null;
2662 alignPanel.getSeqPanel().keyboardNo2 = null;
2664 viewport.setSelectionGroup(null);
2665 viewport.getColumnSelection().clear();
2666 viewport.setSearchResults(null);
2667 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2668 // JAL-2034 - should delegate to
2669 // alignPanel to decide if overview needs
2671 alignPanel.paintAlignment(false, false);
2672 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2673 viewport.sendSelection();
2683 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2685 SequenceGroup sg = viewport.getSelectionGroup();
2689 selectAllSequenceMenuItem_actionPerformed(null);
2694 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2696 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2698 // JAL-2034 - should delegate to
2699 // alignPanel to decide if overview needs
2702 alignPanel.paintAlignment(true, false);
2703 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2704 viewport.sendSelection();
2708 public void invertColSel_actionPerformed(ActionEvent e)
2710 viewport.invertColumnSelection();
2711 alignPanel.paintAlignment(true, false);
2712 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2713 viewport.sendSelection();
2723 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2725 trimAlignment(true);
2735 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2737 trimAlignment(false);
2740 void trimAlignment(boolean trimLeft)
2742 ColumnSelection colSel = viewport.getColumnSelection();
2745 if (!colSel.isEmpty())
2749 column = colSel.getMin();
2753 column = colSel.getMax();
2757 if (viewport.getSelectionGroup() != null)
2759 seqs = viewport.getSelectionGroup()
2760 .getSequencesAsArray(viewport.getHiddenRepSequences());
2764 seqs = viewport.getAlignment().getSequencesArray();
2767 TrimRegionCommand trimRegion;
2770 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2771 column, viewport.getAlignment());
2772 viewport.getRanges().setStartRes(0);
2776 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2777 column, viewport.getAlignment());
2780 setStatus(MessageManager.formatMessage("label.removed_columns",
2782 { Integer.valueOf(trimRegion.getSize()).toString() }));
2784 addHistoryItem(trimRegion);
2786 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2788 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2789 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2791 viewport.getAlignment().deleteGroup(sg);
2795 viewport.firePropertyChange("alignment", null,
2796 viewport.getAlignment().getSequences());
2807 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2809 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2812 if (viewport.getSelectionGroup() != null)
2814 seqs = viewport.getSelectionGroup()
2815 .getSequencesAsArray(viewport.getHiddenRepSequences());
2816 start = viewport.getSelectionGroup().getStartRes();
2817 end = viewport.getSelectionGroup().getEndRes();
2821 seqs = viewport.getAlignment().getSequencesArray();
2824 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2825 "Remove Gapped Columns", seqs, start, end,
2826 viewport.getAlignment());
2828 addHistoryItem(removeGapCols);
2830 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2832 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2834 // This is to maintain viewport position on first residue
2835 // of first sequence
2836 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2837 ViewportRanges ranges = viewport.getRanges();
2838 int startRes = seq.findPosition(ranges.getStartRes());
2839 // ShiftList shifts;
2840 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2841 // edit.alColumnChanges=shifts.getInverse();
2842 // if (viewport.hasHiddenColumns)
2843 // viewport.getColumnSelection().compensateForEdits(shifts);
2844 ranges.setStartRes(seq.findIndex(startRes) - 1);
2845 viewport.firePropertyChange("alignment", null,
2846 viewport.getAlignment().getSequences());
2857 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2859 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2862 if (viewport.getSelectionGroup() != null)
2864 seqs = viewport.getSelectionGroup()
2865 .getSequencesAsArray(viewport.getHiddenRepSequences());
2866 start = viewport.getSelectionGroup().getStartRes();
2867 end = viewport.getSelectionGroup().getEndRes();
2871 seqs = viewport.getAlignment().getSequencesArray();
2874 // This is to maintain viewport position on first residue
2875 // of first sequence
2876 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2877 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2879 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2880 viewport.getAlignment()));
2882 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2884 viewport.firePropertyChange("alignment", null,
2885 viewport.getAlignment().getSequences());
2896 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2898 viewport.setPadGaps(padGapsMenuitem.isSelected());
2899 viewport.firePropertyChange("alignment", null,
2900 viewport.getAlignment().getSequences());
2904 * Opens a Finder dialog
2909 public void findMenuItem_actionPerformed(ActionEvent e)
2911 new Finder(alignPanel, false, null);
2915 * Create a new view of the current alignment.
2918 public void newView_actionPerformed(ActionEvent e)
2920 newView(null, true);
2924 * Creates and shows a new view of the current alignment.
2927 * title of newly created view; if null, one will be generated
2928 * @param copyAnnotation
2929 * if true then duplicate all annnotation, groups and settings
2930 * @return new alignment panel, already displayed.
2932 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2935 * Create a new AlignmentPanel (with its own, new Viewport)
2937 AlignmentPanel newap = new jalview.project.Jalview2XML()
2938 .copyAlignPanel(alignPanel);
2939 if (!copyAnnotation)
2942 * remove all groups and annotation except for the automatic stuff
2944 newap.av.getAlignment().deleteAllGroups();
2945 newap.av.getAlignment().deleteAllAnnotations(false);
2948 newap.av.setGatherViewsHere(false);
2950 if (viewport.getViewName() == null)
2952 viewport.setViewName(
2953 MessageManager.getString("label.view_name_original"));
2957 * Views share the same edits undo and redo stacks
2959 newap.av.setHistoryList(viewport.getHistoryList());
2960 newap.av.setRedoList(viewport.getRedoList());
2963 * copy any visualisation settings that are not saved in the project
2965 newap.av.setColourAppliesToAllGroups(
2966 viewport.getColourAppliesToAllGroups());
2969 * Views share the same mappings; need to deregister any new mappings
2970 * created by copyAlignPanel, and register the new reference to the shared
2973 newap.av.replaceMappings(viewport.getAlignment());
2976 * start up cDNA consensus (if applicable) now mappings are in place
2978 if (newap.av.initComplementConsensus())
2980 newap.refresh(true); // adjust layout of annotations
2983 newap.av.setViewName(getNewViewName(viewTitle));
2985 addAlignmentPanel(newap, true);
2986 newap.alignmentChanged();
2988 if (alignPanels.size() == 2)
2990 viewport.setGatherViewsHere(true);
2992 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2998 * Make a new name for the view, ensuring it is unique within the current
2999 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3000 * these now use viewId. Unique view names are still desirable for usability.)
3005 protected String getNewViewName(String viewTitle)
3007 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3008 boolean addFirstIndex = false;
3009 if (viewTitle == null || viewTitle.trim().length() == 0)
3011 viewTitle = MessageManager.getString("action.view");
3012 addFirstIndex = true;
3016 index = 1;// we count from 1 if given a specific name
3018 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3020 List<Component> comps = PaintRefresher.components
3021 .get(viewport.getSequenceSetId());
3023 List<String> existingNames = getExistingViewNames(comps);
3025 while (existingNames.contains(newViewName))
3027 newViewName = viewTitle + " " + (++index);
3033 * Returns a list of distinct view names found in the given list of
3034 * components. View names are held on the viewport of an AlignmentPanel.
3039 protected List<String> getExistingViewNames(List<Component> comps)
3041 List<String> existingNames = new ArrayList<>();
3042 for (Component comp : comps)
3044 if (comp instanceof AlignmentPanel)
3046 AlignmentPanel ap = (AlignmentPanel) comp;
3047 if (!existingNames.contains(ap.av.getViewName()))
3049 existingNames.add(ap.av.getViewName());
3053 return existingNames;
3057 * Explode tabbed views into separate windows.
3060 public void expandViews_actionPerformed(ActionEvent e)
3062 Desktop.explodeViews(this);
3066 * Gather views in separate windows back into a tabbed presentation.
3069 public void gatherViews_actionPerformed(ActionEvent e)
3071 Desktop.instance.gatherViews(this);
3081 public void font_actionPerformed(ActionEvent e)
3083 new FontChooser(alignPanel);
3093 protected void seqLimit_actionPerformed(ActionEvent e)
3095 viewport.setShowJVSuffix(seqLimits.isSelected());
3097 alignPanel.getIdPanel().getIdCanvas()
3098 .setPreferredSize(alignPanel.calculateIdWidth());
3099 alignPanel.paintAlignment(true, false);
3103 public void idRightAlign_actionPerformed(ActionEvent e)
3105 viewport.setRightAlignIds(idRightAlign.isSelected());
3106 alignPanel.paintAlignment(false, false);
3110 public void centreColumnLabels_actionPerformed(ActionEvent e)
3112 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3113 alignPanel.paintAlignment(false, false);
3119 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3122 protected void followHighlight_actionPerformed()
3125 * Set the 'follow' flag on the Viewport (and scroll to position if now
3128 final boolean state = this.followHighlightMenuItem.getState();
3129 viewport.setFollowHighlight(state);
3132 alignPanel.scrollToPosition(viewport.getSearchResults());
3143 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3145 viewport.setColourText(colourTextMenuItem.isSelected());
3146 alignPanel.paintAlignment(false, false);
3156 public void wrapMenuItem_actionPerformed(ActionEvent e)
3158 scaleAbove.setVisible(wrapMenuItem.isSelected());
3159 scaleLeft.setVisible(wrapMenuItem.isSelected());
3160 scaleRight.setVisible(wrapMenuItem.isSelected());
3161 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3162 alignPanel.updateLayout();
3166 public void showAllSeqs_actionPerformed(ActionEvent e)
3168 viewport.showAllHiddenSeqs();
3172 public void showAllColumns_actionPerformed(ActionEvent e)
3174 viewport.showAllHiddenColumns();
3175 alignPanel.paintAlignment(true, true);
3176 viewport.sendSelection();
3180 public void hideSelSequences_actionPerformed(ActionEvent e)
3182 viewport.hideAllSelectedSeqs();
3186 * called by key handler and the hide all/show all menu items
3191 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3194 boolean hide = false;
3195 SequenceGroup sg = viewport.getSelectionGroup();
3196 if (!toggleSeqs && !toggleCols)
3198 // Hide everything by the current selection - this is a hack - we do the
3199 // invert and then hide
3200 // first check that there will be visible columns after the invert.
3201 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3202 && sg.getStartRes() <= sg.getEndRes()))
3204 // now invert the sequence set, if required - empty selection implies
3205 // that no hiding is required.
3208 invertSequenceMenuItem_actionPerformed(null);
3209 sg = viewport.getSelectionGroup();
3213 viewport.expandColSelection(sg, true);
3214 // finally invert the column selection and get the new sequence
3216 invertColSel_actionPerformed(null);
3223 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3225 hideSelSequences_actionPerformed(null);
3228 else if (!(toggleCols && viewport.hasSelectedColumns()))
3230 showAllSeqs_actionPerformed(null);
3236 if (viewport.hasSelectedColumns())
3238 hideSelColumns_actionPerformed(null);
3241 viewport.setSelectionGroup(sg);
3246 showAllColumns_actionPerformed(null);
3255 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3256 * event.ActionEvent)
3259 public void hideAllButSelection_actionPerformed(ActionEvent e)
3261 toggleHiddenRegions(false, false);
3262 viewport.sendSelection();
3269 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3273 public void hideAllSelection_actionPerformed(ActionEvent e)
3275 SequenceGroup sg = viewport.getSelectionGroup();
3276 viewport.expandColSelection(sg, false);
3277 viewport.hideAllSelectedSeqs();
3278 viewport.hideSelectedColumns();
3279 alignPanel.updateLayout();
3280 alignPanel.paintAlignment(true, true);
3281 viewport.sendSelection();
3288 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3292 public void showAllhidden_actionPerformed(ActionEvent e)
3294 viewport.showAllHiddenColumns();
3295 viewport.showAllHiddenSeqs();
3296 alignPanel.paintAlignment(true, true);
3297 viewport.sendSelection();
3301 public void hideSelColumns_actionPerformed(ActionEvent e)
3303 viewport.hideSelectedColumns();
3304 alignPanel.updateLayout();
3305 alignPanel.paintAlignment(true, true);
3306 viewport.sendSelection();
3310 public void hiddenMarkers_actionPerformed(ActionEvent e)
3312 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3323 protected void scaleAbove_actionPerformed(ActionEvent e)
3325 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3326 alignPanel.updateLayout();
3327 alignPanel.paintAlignment(true, false);
3337 protected void scaleLeft_actionPerformed(ActionEvent e)
3339 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3340 alignPanel.updateLayout();
3341 alignPanel.paintAlignment(true, false);
3351 protected void scaleRight_actionPerformed(ActionEvent e)
3353 viewport.setScaleRightWrapped(scaleRight.isSelected());
3354 alignPanel.updateLayout();
3355 alignPanel.paintAlignment(true, false);
3365 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3367 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3368 alignPanel.paintAlignment(false, false);
3378 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3380 viewport.setShowText(viewTextMenuItem.isSelected());
3381 alignPanel.paintAlignment(false, false);
3391 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3393 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3394 alignPanel.paintAlignment(false, false);
3397 public FeatureSettings featureSettings;
3400 public FeatureSettingsControllerI getFeatureSettingsUI()
3402 return featureSettings;
3406 public void featureSettings_actionPerformed(ActionEvent e)
3408 showFeatureSettingsUI();
3412 public FeatureSettingsControllerI showFeatureSettingsUI()
3414 if (featureSettings != null)
3416 featureSettings.closeOldSettings();
3417 featureSettings = null;
3419 if (!showSeqFeatures.isSelected())
3421 // make sure features are actually displayed
3422 showSeqFeatures.setSelected(true);
3423 showSeqFeatures_actionPerformed(null);
3425 featureSettings = new FeatureSettings(this);
3426 return featureSettings;
3430 * Set or clear 'Show Sequence Features'
3436 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3438 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3439 alignPanel.paintAlignment(true, true);
3443 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3444 * the annotations panel as a whole.
3446 * The options to show/hide all annotations should be enabled when the panel
3447 * is shown, and disabled when the panel is hidden.
3452 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3454 final boolean setVisible = annotationPanelMenuItem.isSelected();
3455 viewport.setShowAnnotation(setVisible);
3456 this.showAllSeqAnnotations.setEnabled(setVisible);
3457 this.hideAllSeqAnnotations.setEnabled(setVisible);
3458 this.showAllAlAnnotations.setEnabled(setVisible);
3459 this.hideAllAlAnnotations.setEnabled(setVisible);
3460 alignPanel.updateLayout();
3464 public void alignmentProperties()
3467 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3470 String content = MessageManager.formatMessage("label.html_content",
3472 { contents.toString() });
3475 if (Platform.isJS())
3477 JLabel textLabel = new JLabel();
3478 textLabel.setText(content);
3479 textLabel.setBackground(Color.WHITE);
3481 pane = new JPanel(new BorderLayout());
3482 ((JPanel) pane).setOpaque(true);
3483 pane.setBackground(Color.WHITE);
3484 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3493 JEditorPane editPane = new JEditorPane("text/html", "");
3494 editPane.setEditable(false);
3495 editPane.setText(content);
3499 JInternalFrame frame = new JInternalFrame();
3500 frame.setFrameIcon(null);
3501 frame.getContentPane().add(new JScrollPane(pane));
3503 Desktop.addInternalFrame(frame, MessageManager
3504 .formatMessage("label.alignment_properties", new Object[]
3505 { getTitle() }), 500, 400);
3509 * Opens an Overview panel for the alignment, unless one is open already
3514 public void overviewMenuItem_actionPerformed(ActionEvent e)
3516 boolean showHiddenRegions = Cache
3517 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3518 openOverviewPanel(showHiddenRegions);
3521 public OverviewPanel openOverviewPanel(boolean showHidden)
3523 if (alignPanel.overviewPanel != null)
3525 return alignPanel.overviewPanel;
3527 JInternalFrame frame = new JInternalFrame();
3528 frame.setFrameIcon(null);
3529 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3531 frame.setContentPane(overview);
3532 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3533 frame.getHeight(), true, true);
3535 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3536 final AlignmentPanel thePanel = this.alignPanel;
3537 frame.addInternalFrameListener(
3538 new javax.swing.event.InternalFrameAdapter()
3541 public void internalFrameClosed(
3542 javax.swing.event.InternalFrameEvent evt)
3545 thePanel.setOverviewPanel(null);
3548 if (getKeyListeners().length > 0)
3550 frame.addKeyListener(getKeyListeners()[0]);
3553 alignPanel.setOverviewPanel(overview);
3554 alignPanel.setOverviewTitle(this);
3560 public void textColour_actionPerformed()
3562 new TextColourChooser().chooseColour(alignPanel, null);
3566 * public void covariationColour_actionPerformed() {
3568 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3572 public void annotationColour_actionPerformed()
3574 new AnnotationColourChooser(viewport, alignPanel);
3578 public void annotationColumn_actionPerformed(ActionEvent e)
3580 new AnnotationColumnChooser(viewport, alignPanel);
3584 * Action on the user checking or unchecking the option to apply the selected
3585 * colour scheme to all groups. If unchecked, groups may have their own
3586 * independent colour schemes.
3591 public void applyToAllGroups_actionPerformed(boolean selected)
3593 viewport.setColourAppliesToAllGroups(selected);
3597 * Action on user selecting a colour from the colour menu
3600 * the name (not the menu item label!) of the colour scheme
3603 public void changeColour_actionPerformed(String name)
3606 * 'User Defined' opens a panel to configure or load a
3607 * user-defined colour scheme
3609 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3611 new UserDefinedColours(alignPanel);
3616 * otherwise set the chosen colour scheme (or null for 'None')
3618 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3619 viewport, viewport.getAlignment(),
3620 viewport.getHiddenRepSequences());
3625 * Actions on setting or changing the alignment colour scheme
3630 public void changeColour(ColourSchemeI cs)
3632 // TODO: pull up to controller method
3633 ColourMenuHelper.setColourSelected(colourMenu, cs);
3635 viewport.setGlobalColourScheme(cs);
3637 alignPanel.paintAlignment(true, true);
3641 * Show the PID threshold slider panel
3644 protected void modifyPID_actionPerformed()
3646 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3647 alignPanel.getViewName());
3648 SliderPanel.showPIDSlider();
3652 * Show the Conservation slider panel
3655 protected void modifyConservation_actionPerformed()
3657 SliderPanel.setConservationSlider(alignPanel,
3658 viewport.getResidueShading(), alignPanel.getViewName());
3659 SliderPanel.showConservationSlider();
3663 * Action on selecting or deselecting (Colour) By Conservation
3666 public void conservationMenuItem_actionPerformed(boolean selected)
3668 modifyConservation.setEnabled(selected);
3669 viewport.setConservationSelected(selected);
3670 viewport.getResidueShading().setConservationApplied(selected);
3672 changeColour(viewport.getGlobalColourScheme());
3675 modifyConservation_actionPerformed();
3679 SliderPanel.hideConservationSlider();
3684 * Action on selecting or deselecting (Colour) Above PID Threshold
3687 public void abovePIDThreshold_actionPerformed(boolean selected)
3689 modifyPID.setEnabled(selected);
3690 viewport.setAbovePIDThreshold(selected);
3693 viewport.getResidueShading().setThreshold(0,
3694 viewport.isIgnoreGapsConsensus());
3697 changeColour(viewport.getGlobalColourScheme());
3700 modifyPID_actionPerformed();
3704 SliderPanel.hidePIDSlider();
3715 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3717 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3718 AlignmentSorter.sortByPID(viewport.getAlignment(),
3719 viewport.getAlignment().getSequenceAt(0));
3720 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3721 viewport.getAlignment()));
3722 alignPanel.paintAlignment(true, false);
3732 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3734 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3735 AlignmentSorter.sortByID(viewport.getAlignment());
3737 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3738 alignPanel.paintAlignment(true, false);
3748 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3750 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3751 AlignmentSorter.sortByLength(viewport.getAlignment());
3752 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3753 viewport.getAlignment()));
3754 alignPanel.paintAlignment(true, false);
3764 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3766 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3767 AlignmentSorter.sortByGroup(viewport.getAlignment());
3768 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3769 viewport.getAlignment()));
3771 alignPanel.paintAlignment(true, false);
3781 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3783 new RedundancyPanel(alignPanel, this);
3793 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3795 if ((viewport.getSelectionGroup() == null)
3796 || (viewport.getSelectionGroup().getSize() < 2))
3798 JvOptionPane.showInternalMessageDialog(this,
3799 MessageManager.getString(
3800 "label.you_must_select_least_two_sequences"),
3801 MessageManager.getString("label.invalid_selection"),
3802 JvOptionPane.WARNING_MESSAGE);
3806 JInternalFrame frame = new JInternalFrame();
3807 frame.setFrameIcon(null);
3808 frame.setContentPane(new PairwiseAlignPanel(viewport));
3809 Desktop.addInternalFrame(frame,
3810 MessageManager.getString("action.pairwise_alignment"), 600,
3816 public void autoCalculate_actionPerformed(ActionEvent e)
3818 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3819 if (viewport.autoCalculateConsensus)
3821 viewport.firePropertyChange("alignment", null,
3822 viewport.getAlignment().getSequences());
3827 public void sortByTreeOption_actionPerformed(ActionEvent e)
3829 viewport.sortByTree = sortByTree.isSelected();
3833 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3835 viewport.followSelection = listenToViewSelections.isSelected();
3839 * Constructs a tree panel and adds it to the desktop
3842 * tree type (NJ or AV)
3844 * name of score model used to compute the tree
3846 * parameters for the distance or similarity calculation
3848 void newTreePanel(String type, String modelName,
3849 SimilarityParamsI options)
3851 String frameTitle = "";
3854 boolean onSelection = false;
3855 if (viewport.getSelectionGroup() != null
3856 && viewport.getSelectionGroup().getSize() > 0)
3858 SequenceGroup sg = viewport.getSelectionGroup();
3860 /* Decide if the selection is a column region */
3861 for (SequenceI _s : sg.getSequences())
3863 if (_s.getLength() < sg.getEndRes())
3865 JvOptionPane.showMessageDialog(Desktop.desktop,
3866 MessageManager.getString(
3867 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3868 MessageManager.getString(
3869 "label.sequences_selection_not_aligned"),
3870 JvOptionPane.WARNING_MESSAGE);
3879 if (viewport.getAlignment().getHeight() < 2)
3885 tp = new TreePanel(alignPanel, type, modelName, options);
3886 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3888 frameTitle += " from ";
3890 if (viewport.getViewName() != null)
3892 frameTitle += viewport.getViewName() + " of ";
3895 frameTitle += this.title;
3897 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3908 public void addSortByOrderMenuItem(String title,
3909 final AlignmentOrder order)
3911 final JMenuItem item = new JMenuItem(MessageManager
3912 .formatMessage("action.by_title_param", new Object[]
3915 item.addActionListener(new java.awt.event.ActionListener()
3918 public void actionPerformed(ActionEvent e)
3920 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3922 // TODO: JBPNote - have to map order entries to curent SequenceI
3924 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3926 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3927 viewport.getAlignment()));
3929 alignPanel.paintAlignment(true, false);
3935 * Add a new sort by annotation score menu item
3938 * the menu to add the option to
3940 * the label used to retrieve scores for each sequence on the
3943 public void addSortByAnnotScoreMenuItem(JMenu sort,
3944 final String scoreLabel)
3946 final JMenuItem item = new JMenuItem(scoreLabel);
3948 item.addActionListener(new java.awt.event.ActionListener()
3951 public void actionPerformed(ActionEvent e)
3953 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3954 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3955 viewport.getAlignment());// ,viewport.getSelectionGroup());
3956 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3957 viewport.getAlignment()));
3958 alignPanel.paintAlignment(true, false);
3964 * last hash for alignment's annotation array - used to minimise cost of
3967 protected int _annotationScoreVectorHash;
3970 * search the alignment and rebuild the sort by annotation score submenu the
3971 * last alignment annotation vector hash is stored to minimize cost of
3972 * rebuilding in subsequence calls.
3976 public void buildSortByAnnotationScoresMenu()
3978 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3983 if (viewport.getAlignment().getAlignmentAnnotation()
3984 .hashCode() != _annotationScoreVectorHash)
3986 sortByAnnotScore.removeAll();
3987 // almost certainly a quicker way to do this - but we keep it simple
3988 Hashtable<String, String> scoreSorts = new Hashtable<>();
3989 AlignmentAnnotation aann[];
3990 for (SequenceI sqa : viewport.getAlignment().getSequences())
3992 aann = sqa.getAnnotation();
3993 for (int i = 0; aann != null && i < aann.length; i++)
3995 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3997 scoreSorts.put(aann[i].label, aann[i].label);
4001 Enumeration<String> labels = scoreSorts.keys();
4002 while (labels.hasMoreElements())
4004 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4006 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4009 _annotationScoreVectorHash = viewport.getAlignment()
4010 .getAlignmentAnnotation().hashCode();
4015 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4016 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4017 * call. Listeners are added to remove the menu item when the treePanel is
4018 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4022 public void buildTreeSortMenu()
4024 sortByTreeMenu.removeAll();
4026 List<Component> comps = PaintRefresher.components
4027 .get(viewport.getSequenceSetId());
4028 List<TreePanel> treePanels = new ArrayList<>();
4029 for (Component comp : comps)
4031 if (comp instanceof TreePanel)
4033 treePanels.add((TreePanel) comp);
4037 if (treePanels.size() < 1)
4039 sortByTreeMenu.setVisible(false);
4043 sortByTreeMenu.setVisible(true);
4045 for (final TreePanel tp : treePanels)
4047 final JMenuItem item = new JMenuItem(tp.getTitle());
4048 item.addActionListener(new java.awt.event.ActionListener()
4051 public void actionPerformed(ActionEvent e)
4053 tp.sortByTree_actionPerformed();
4054 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4059 sortByTreeMenu.add(item);
4063 public boolean sortBy(AlignmentOrder alorder, String undoname)
4065 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4066 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4067 if (undoname != null)
4069 addHistoryItem(new OrderCommand(undoname, oldOrder,
4070 viewport.getAlignment()));
4072 alignPanel.paintAlignment(true, false);
4077 * Work out whether the whole set of sequences or just the selected set will
4078 * be submitted for multiple alignment.
4081 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4083 // Now, check we have enough sequences
4084 AlignmentView msa = null;
4086 if ((viewport.getSelectionGroup() != null)
4087 && (viewport.getSelectionGroup().getSize() > 1))
4089 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4090 // some common interface!
4092 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4093 * SequenceI[sz = seqs.getSize(false)];
4095 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4096 * seqs.getSequenceAt(i); }
4098 msa = viewport.getAlignmentView(true);
4100 else if (viewport.getSelectionGroup() != null
4101 && viewport.getSelectionGroup().getSize() == 1)
4103 int option = JvOptionPane.showConfirmDialog(this,
4104 MessageManager.getString("warn.oneseq_msainput_selection"),
4105 MessageManager.getString("label.invalid_selection"),
4106 JvOptionPane.OK_CANCEL_OPTION);
4107 if (option == JvOptionPane.OK_OPTION)
4109 msa = viewport.getAlignmentView(false);
4114 msa = viewport.getAlignmentView(false);
4120 * Decides what is submitted to a secondary structure prediction service: the
4121 * first sequence in the alignment, or in the current selection, or, if the
4122 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4123 * region or the whole alignment. (where the first sequence in the set is the
4124 * one that the prediction will be for).
4126 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4128 AlignmentView seqs = null;
4130 if ((viewport.getSelectionGroup() != null)
4131 && (viewport.getSelectionGroup().getSize() > 0))
4133 seqs = viewport.getAlignmentView(true);
4137 seqs = viewport.getAlignmentView(false);
4139 // limit sequences - JBPNote in future - could spawn multiple prediction
4141 // TODO: viewport.getAlignment().isAligned is a global state - the local
4142 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4143 if (!viewport.getAlignment().isAligned(false))
4145 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4146 // TODO: if seqs.getSequences().length>1 then should really have warned
4160 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4162 // Pick the tree file
4163 JalviewFileChooser chooser = new JalviewFileChooser(
4164 Cache.getProperty("LAST_DIRECTORY"));
4165 chooser.setFileView(new JalviewFileView());
4166 chooser.setDialogTitle(
4167 MessageManager.getString("label.select_newick_like_tree_file"));
4168 chooser.setToolTipText(
4169 MessageManager.getString("label.load_tree_file"));
4171 chooser.setResponseHandler(0, () -> {
4172 String filePath = chooser.getSelectedFile().getPath();
4173 Cache.setProperty("LAST_DIRECTORY", filePath);
4174 NewickFile fin = null;
4177 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4178 DataSourceType.FILE));
4179 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4180 } catch (Exception ex)
4182 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4183 MessageManager.getString("label.problem_reading_tree_file"),
4184 JvOptionPane.WARNING_MESSAGE);
4185 ex.printStackTrace();
4187 if (fin != null && fin.hasWarningMessage())
4189 JvOptionPane.showMessageDialog(Desktop.desktop,
4190 fin.getWarningMessage(),
4192 .getString("label.possible_problem_with_tree_file"),
4193 JvOptionPane.WARNING_MESSAGE);
4196 chooser.showOpenDialog(this);
4199 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4201 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4204 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4205 int h, int x, int y)
4207 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4211 * Add a treeviewer for the tree extracted from a Newick file object to the
4212 * current alignment view
4219 * Associated alignment input data (or null)
4228 * @return TreePanel handle
4230 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4231 AlignmentView input, int w, int h, int x, int y)
4233 TreePanel tp = null;
4239 if (nf.getTree() != null)
4241 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4247 tp.setLocation(x, y);
4250 Desktop.addInternalFrame(tp, treeTitle, w, h);
4252 } catch (Exception ex)
4254 ex.printStackTrace();
4260 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4263 int w = 400, h = 500;
4267 NewickFile fin = new NewickFile(
4268 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4269 String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree"
4270 + aa.sequenceRef != null
4271 ? (" for " + aa.sequenceRef.getDisplayId(false))
4274 showColumnWiseTree(fin, aa, title, w, h, x, y);
4275 } catch (Throwable xx)
4277 Console.error("Unexpected exception showing tree for contact matrix",
4282 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4283 String treeTitle, int w, int h, int x, int y)
4288 if (nf.getTree() == null)
4292 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4298 tp.setLocation(x, y);
4301 Desktop.addInternalFrame(tp, title, w, h);
4303 } catch (Throwable xx)
4305 Console.error("Unexpected exception showing tree for contact matrix",
4311 private boolean buildingMenu = false;
4314 * Generates menu items and listener event actions for web service clients
4317 public void BuildWebServiceMenu()
4319 while (buildingMenu)
4323 System.err.println("Waiting for building menu to finish.");
4325 } catch (Exception e)
4329 final AlignFrame me = this;
4330 buildingMenu = true;
4331 new Thread(new Runnable()
4336 final List<JMenuItem> legacyItems = new ArrayList<>();
4339 // System.err.println("Building ws menu again "
4340 // + Thread.currentThread());
4341 // TODO: add support for context dependent disabling of services based
4343 // alignment and current selection
4344 // TODO: add additional serviceHandle parameter to specify abstract
4346 // class independently of AbstractName
4347 // TODO: add in rediscovery GUI function to restart discoverer
4348 // TODO: group services by location as well as function and/or
4350 // object broker mechanism.
4351 final Vector<JMenu> wsmenu = new Vector<>();
4352 final IProgressIndicator af = me;
4355 * do not i18n these strings - they are hard-coded in class
4356 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4357 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4359 final JMenu msawsmenu = new JMenu("Alignment");
4360 final JMenu secstrmenu = new JMenu(
4361 "Secondary Structure Prediction");
4362 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4363 final JMenu analymenu = new JMenu("Analysis");
4364 final JMenu dismenu = new JMenu("Protein Disorder");
4365 // JAL-940 - only show secondary structure prediction services from
4366 // the legacy server
4367 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4369 Discoverer.services != null && (Discoverer.services.size() > 0))
4371 // TODO: refactor to allow list of AbstractName/Handler bindings to
4373 // stored or retrieved from elsewhere
4374 // No MSAWS used any more:
4375 // Vector msaws = null; // (Vector)
4376 // Discoverer.services.get("MsaWS");
4377 Vector<ServiceHandle> secstrpr = Discoverer.services
4379 if (secstrpr != null)
4381 // Add any secondary structure prediction services
4382 for (int i = 0, j = secstrpr.size(); i < j; i++)
4384 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4385 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4386 .getServiceClient(sh);
4387 int p = secstrmenu.getItemCount();
4388 impl.attachWSMenuEntry(secstrmenu, me);
4389 int q = secstrmenu.getItemCount();
4390 for (int litm = p; litm < q; litm++)
4392 legacyItems.add(secstrmenu.getItem(litm));
4398 // Add all submenus in the order they should appear on the web
4400 wsmenu.add(msawsmenu);
4401 wsmenu.add(secstrmenu);
4402 wsmenu.add(dismenu);
4403 wsmenu.add(analymenu);
4404 // No search services yet
4405 // wsmenu.add(seqsrchmenu);
4407 javax.swing.SwingUtilities.invokeLater(new Runnable()
4414 webService.removeAll();
4415 // first, add discovered services onto the webservices menu
4416 if (wsmenu.size() > 0)
4418 for (int i = 0, j = wsmenu.size(); i < j; i++)
4420 webService.add(wsmenu.get(i));
4425 webService.add(me.webServiceNoServices);
4427 // TODO: move into separate menu builder class.
4429 // logic for 2.11.1.4 is
4430 // always look to see if there is a discover. if there isn't
4431 // we can't show any Jws2 services
4432 // if there are services available, show them - regardless of
4433 // the 'show JWS2 preference'
4434 // if the discoverer is running then say so
4435 // otherwise offer to trigger discovery if 'show JWS2' is not
4437 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4438 if (jws2servs != null)
4440 if (jws2servs.hasServices())
4442 jws2servs.attachWSMenuEntry(webService, me);
4443 for (Jws2Instance sv : jws2servs.getServices())
4445 if (sv.description.toLowerCase(Locale.ROOT)
4448 for (JMenuItem jmi : legacyItems)
4450 jmi.setVisible(false);
4456 if (jws2servs.isRunning())
4458 JMenuItem tm = new JMenuItem(
4459 "Still discovering JABA Services");
4460 tm.setEnabled(false);
4463 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4465 JMenuItem enableJws2 = new JMenuItem(
4466 "Discover Web Services");
4467 enableJws2.setToolTipText(
4468 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4469 enableJws2.setEnabled(true);
4470 enableJws2.addActionListener(new ActionListener()
4474 public void actionPerformed(ActionEvent e)
4476 // start service discoverer, but ignore preference
4477 Desktop.instance.startServiceDiscovery(false,
4481 webService.add(enableJws2);
4485 build_urlServiceMenu(me.webService);
4486 build_fetchdbmenu(webService);
4487 for (JMenu item : wsmenu)
4489 if (item.getItemCount() == 0)
4491 item.setEnabled(false);
4495 item.setEnabled(true);
4498 } catch (Exception e)
4501 "Exception during web service menu building process.",
4506 } catch (Exception e)
4509 buildingMenu = false;
4516 * construct any groupURL type service menu entries.
4520 protected void build_urlServiceMenu(JMenu webService)
4522 // TODO: remove this code when 2.7 is released
4523 // DEBUG - alignmentView
4525 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4526 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4528 * @Override public void actionPerformed(ActionEvent e) {
4529 * jalview.datamodel.AlignmentView
4530 * .testSelectionViews(af.viewport.getAlignment(),
4531 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4533 * }); webService.add(testAlView);
4535 // TODO: refactor to RestClient discoverer and merge menu entries for
4536 // rest-style services with other types of analysis/calculation service
4537 // SHmmr test client - still being implemented.
4538 // DEBUG - alignmentView
4540 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4543 client.attachWSMenuEntry(
4544 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4550 * Searches the alignment sequences for xRefs and builds the Show
4551 * Cross-References menu (formerly called Show Products), with database
4552 * sources for which cross-references are found (protein sources for a
4553 * nucleotide alignment and vice versa)
4555 * @return true if Show Cross-references menu should be enabled
4557 public boolean canShowProducts()
4559 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4560 AlignmentI dataset = viewport.getAlignment().getDataset();
4562 showProducts.removeAll();
4563 final boolean dna = viewport.getAlignment().isNucleotide();
4565 if (seqs == null || seqs.length == 0)
4567 // nothing to see here.
4571 boolean showp = false;
4574 List<String> ptypes = new CrossRef(seqs, dataset)
4575 .findXrefSourcesForSequences(dna);
4577 for (final String source : ptypes)
4580 final AlignFrame af = this;
4581 JMenuItem xtype = new JMenuItem(source);
4582 xtype.addActionListener(new ActionListener()
4585 public void actionPerformed(ActionEvent e)
4587 showProductsFor(af.viewport.getSequenceSelection(), dna,
4591 showProducts.add(xtype);
4593 showProducts.setVisible(showp);
4594 showProducts.setEnabled(showp);
4595 } catch (Exception e)
4598 "canShowProducts threw an exception - please report to help@jalview.org",
4606 * Finds and displays cross-references for the selected sequences (protein
4607 * products for nucleotide sequences, dna coding sequences for peptides).
4610 * the sequences to show cross-references for
4612 * true if from a nucleotide alignment (so showing proteins)
4614 * the database to show cross-references for
4616 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4617 final String source)
4619 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4624 * Construct and display a new frame containing the translation of this
4625 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4628 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4630 AlignmentI al = null;
4633 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4635 al = dna.translateCdna(codeTable);
4636 } catch (Exception ex)
4638 Console.error("Exception during translation. Please report this !",
4640 final String msg = MessageManager.getString(
4641 "label.error_when_translating_sequences_submit_bug_report");
4642 final String errorTitle = MessageManager
4643 .getString("label.implementation_error")
4644 + MessageManager.getString("label.translation_failed");
4645 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4646 JvOptionPane.ERROR_MESSAGE);
4649 if (al == null || al.getHeight() == 0)
4651 final String msg = MessageManager.getString(
4652 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4653 final String errorTitle = MessageManager
4654 .getString("label.translation_failed");
4655 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4656 JvOptionPane.WARNING_MESSAGE);
4660 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4661 af.setFileFormat(this.currentFileFormat);
4662 final String newTitle = MessageManager
4663 .formatMessage("label.translation_of_params", new Object[]
4664 { this.getTitle(), codeTable.getId() });
4665 af.setTitle(newTitle);
4666 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4668 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4669 viewport.openSplitFrame(af, new Alignment(seqs));
4673 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4680 * Set the file format
4684 public void setFileFormat(FileFormatI format)
4686 this.currentFileFormat = format;
4690 * Try to load a features file onto the alignment.
4693 * contents or path to retrieve file or a File object
4695 * access mode of file (see jalview.io.AlignFile)
4696 * @return true if features file was parsed correctly.
4698 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4701 return avc.parseFeaturesFile(file, sourceType,
4702 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4707 public void refreshFeatureUI(boolean enableIfNecessary)
4709 // note - currently this is only still here rather than in the controller
4710 // because of the featureSettings hard reference that is yet to be
4712 if (enableIfNecessary)
4714 viewport.setShowSequenceFeatures(true);
4715 showSeqFeatures.setSelected(true);
4721 public void dragEnter(DropTargetDragEvent evt)
4726 public void dragExit(DropTargetEvent evt)
4731 public void dragOver(DropTargetDragEvent evt)
4736 public void dropActionChanged(DropTargetDragEvent evt)
4741 public void drop(DropTargetDropEvent evt)
4743 // JAL-1552 - acceptDrop required before getTransferable call for
4744 // Java's Transferable for native dnd
4745 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4746 Transferable t = evt.getTransferable();
4748 final AlignFrame thisaf = this;
4749 final List<Object> files = new ArrayList<>();
4750 List<DataSourceType> protocols = new ArrayList<>();
4754 Desktop.transferFromDropTarget(files, protocols, evt, t);
4755 } catch (Exception e)
4757 e.printStackTrace();
4761 new Thread(new Runnable()
4768 // check to see if any of these files have names matching sequences
4771 SequenceIdMatcher idm = new SequenceIdMatcher(
4772 viewport.getAlignment().getSequencesArray());
4774 * Object[] { String,SequenceI}
4776 ArrayList<Object[]> filesmatched = new ArrayList<>();
4777 ArrayList<Object> filesnotmatched = new ArrayList<>();
4778 for (int i = 0; i < files.size(); i++)
4781 Object file = files.get(i);
4782 String fileName = file.toString();
4784 DataSourceType protocol = (file instanceof File
4785 ? DataSourceType.FILE
4786 : FormatAdapter.checkProtocol(fileName));
4787 if (protocol == DataSourceType.FILE)
4790 if (file instanceof File)
4793 Platform.cacheFileData(fl);
4797 fl = new File(fileName);
4799 pdbfn = fl.getName();
4801 else if (protocol == DataSourceType.URL)
4803 URL url = new URL(fileName);
4804 pdbfn = url.getFile();
4806 if (pdbfn.length() > 0)
4808 // attempt to find a match in the alignment
4809 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4810 int l = 0, c = pdbfn.indexOf(".");
4811 while (mtch == null && c != -1)
4816 } while ((c = pdbfn.indexOf(".", l)) > l);
4819 pdbfn = pdbfn.substring(0, l);
4821 mtch = idm.findAllIdMatches(pdbfn);
4828 type = new IdentifyFile().identify(file, protocol);
4829 } catch (Exception ex)
4833 if (type != null && type.isStructureFile())
4835 filesmatched.add(new Object[] { file, protocol, mtch });
4839 // File wasn't named like one of the sequences or wasn't a PDB
4841 filesnotmatched.add(file);
4845 if (filesmatched.size() > 0)
4847 boolean autoAssociate = Cache
4848 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4851 String msg = MessageManager.formatMessage(
4852 "label.automatically_associate_structure_files_with_sequences_same_name",
4854 { Integer.valueOf(filesmatched.size())
4856 String ttl = MessageManager.getString(
4857 "label.automatically_associate_structure_files_by_name");
4858 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4859 ttl, JvOptionPane.YES_NO_OPTION);
4860 autoAssociate = choice == JvOptionPane.YES_OPTION;
4864 for (Object[] fm : filesmatched)
4866 // try and associate
4867 // TODO: may want to set a standard ID naming formalism for
4868 // associating PDB files which have no IDs.
4869 for (SequenceI toassoc : (SequenceI[]) fm[2])
4871 PDBEntry pe = new AssociatePdbFileWithSeq()
4872 .associatePdbWithSeq(fm[0].toString(),
4873 (DataSourceType) fm[1], toassoc, false,
4877 System.err.println("Associated file : "
4878 + (fm[0].toString()) + " with "
4879 + toassoc.getDisplayId(true));
4883 // TODO: do we need to update overview ? only if features are
4885 alignPanel.paintAlignment(true, false);
4891 * add declined structures as sequences
4893 for (Object[] o : filesmatched)
4895 filesnotmatched.add(o[0]);
4899 if (filesnotmatched.size() > 0)
4901 if (assocfiles > 0 && (Cache.getDefault(
4902 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4903 || JvOptionPane.showConfirmDialog(thisaf,
4904 "<html>" + MessageManager.formatMessage(
4905 "label.ignore_unmatched_dropped_files_info",
4908 filesnotmatched.size())
4911 MessageManager.getString(
4912 "label.ignore_unmatched_dropped_files"),
4913 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4917 for (Object fn : filesnotmatched)
4919 loadJalviewDataFile(fn, null, null, null);
4923 } catch (Exception ex)
4925 ex.printStackTrace();
4933 * Attempt to load a "dropped" file or URL string, by testing in turn for
4935 * <li>an Annotation file</li>
4936 * <li>a JNet file</li>
4937 * <li>a features file</li>
4938 * <li>else try to interpret as an alignment file</li>
4942 * either a filename or a URL string.
4944 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4945 FileFormatI format, SequenceI assocSeq)
4947 // BH 2018 was String file
4950 if (sourceType == null)
4952 sourceType = FormatAdapter.checkProtocol(file);
4954 // if the file isn't identified, or not positively identified as some
4955 // other filetype (PFAM is default unidentified alignment file type) then
4956 // try to parse as annotation.
4957 boolean isAnnotation = (format == null
4958 || FileFormat.Pfam.equals(format))
4959 ? new AnnotationFile().annotateAlignmentView(viewport,
4965 // first see if its a T-COFFEE score file
4966 TCoffeeScoreFile tcf = null;
4969 tcf = new TCoffeeScoreFile(file, sourceType);
4972 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4976 new TCoffeeColourScheme(viewport.getAlignment()));
4977 isAnnotation = true;
4978 setStatus(MessageManager.getString(
4979 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4983 // some problem - if no warning its probable that the ID matching
4984 // process didn't work
4985 JvOptionPane.showMessageDialog(Desktop.desktop,
4986 tcf.getWarningMessage() == null
4987 ? MessageManager.getString(
4988 "label.check_file_matches_sequence_ids_alignment")
4989 : tcf.getWarningMessage(),
4990 MessageManager.getString(
4991 "label.problem_reading_tcoffee_score_file"),
4992 JvOptionPane.WARNING_MESSAGE);
4999 } catch (Exception x)
5002 "Exception when processing data source as T-COFFEE score file",
5008 // try to see if its a JNet 'concise' style annotation file *before*
5010 // try to parse it as a features file
5013 format = new IdentifyFile().identify(file, sourceType);
5015 if (FileFormat.ScoreMatrix == format)
5017 ScoreMatrixFile sm = new ScoreMatrixFile(
5018 new FileParse(file, sourceType));
5020 // todo: i18n this message
5021 setStatus(MessageManager.formatMessage(
5022 "label.successfully_loaded_matrix",
5023 sm.getMatrixName()));
5025 else if (FileFormat.Jnet.equals(format))
5027 JPredFile predictions = new JPredFile(file, sourceType);
5028 new JnetAnnotationMaker();
5029 JnetAnnotationMaker.add_annotation(predictions,
5030 viewport.getAlignment(), 0, false);
5031 viewport.getAlignment().setupJPredAlignment();
5032 isAnnotation = true;
5034 // else if (IdentifyFile.FeaturesFile.equals(format))
5035 else if (FileFormat.Features.equals(format))
5037 if (parseFeaturesFile(file, sourceType))
5039 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5040 if (splitFrame != null)
5042 splitFrame.repaint();
5046 alignPanel.paintAlignment(true, true);
5052 new FileLoader().LoadFile(viewport, file, sourceType, format);
5059 alignPanel.adjustAnnotationHeight();
5060 viewport.updateSequenceIdColours();
5061 buildSortByAnnotationScoresMenu();
5062 alignPanel.paintAlignment(true, true);
5064 } catch (Exception ex)
5066 ex.printStackTrace();
5067 } catch (OutOfMemoryError oom)
5072 } catch (Exception x)
5077 + (sourceType != null
5078 ? (sourceType == DataSourceType.PASTE
5080 : "using " + sourceType + " from "
5084 ? "(parsing as '" + format + "' file)"
5086 oom, Desktop.desktop);
5091 * Method invoked by the ChangeListener on the tabbed pane, in other words
5092 * when a different tabbed pane is selected by the user or programmatically.
5095 public void tabSelectionChanged(int index)
5100 * update current Overview window title (if there is one)
5101 * to add view name "Original" if necessary
5103 alignPanel.setOverviewTitle(this);
5106 * switch panels and set Overview title (if there is one
5107 * because it was opened automatically)
5109 alignPanel = alignPanels.get(index);
5110 alignPanel.setOverviewTitle(this);
5112 viewport = alignPanel.av;
5113 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5114 setMenusFromViewport(viewport);
5115 if (featureSettings != null && featureSettings.isOpen()
5116 && featureSettings.fr.getViewport() != viewport)
5118 if (viewport.isShowSequenceFeatures())
5120 // refresh the featureSettings to reflect UI change
5121 showFeatureSettingsUI();
5125 // close feature settings for this view.
5126 featureSettings.close();
5133 * 'focus' any colour slider that is open to the selected viewport
5135 if (viewport.getConservationSelected())
5137 SliderPanel.setConservationSlider(alignPanel,
5138 viewport.getResidueShading(), alignPanel.getViewName());
5142 SliderPanel.hideConservationSlider();
5144 if (viewport.getAbovePIDThreshold())
5146 SliderPanel.setPIDSliderSource(alignPanel,
5147 viewport.getResidueShading(), alignPanel.getViewName());
5151 SliderPanel.hidePIDSlider();
5155 * If there is a frame linked to this one in a SplitPane, switch it to the
5156 * same view tab index. No infinite recursion of calls should happen, since
5157 * tabSelectionChanged() should not get invoked on setting the selected
5158 * index to an unchanged value. Guard against setting an invalid index
5159 * before the new view peer tab has been created.
5161 final AlignViewportI peer = viewport.getCodingComplement();
5164 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5165 .getAlignPanel().alignFrame;
5166 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5168 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5174 * On right mouse click on view tab, prompt for and set new view name.
5177 public void tabbedPane_mousePressed(MouseEvent e)
5179 if (e.isPopupTrigger())
5181 String msg = MessageManager.getString("label.enter_view_name");
5182 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5183 String reply = JvOptionPane.showInputDialog(msg, ttl);
5187 viewport.setViewName(reply);
5188 // TODO warn if reply is in getExistingViewNames()?
5189 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5194 public AlignViewport getCurrentView()
5200 * Open the dialog for regex description parsing.
5203 protected void extractScores_actionPerformed(ActionEvent e)
5205 ParseProperties pp = new jalview.analysis.ParseProperties(
5206 viewport.getAlignment());
5207 // TODO: verify regex and introduce GUI dialog for version 2.5
5208 // if (pp.getScoresFromDescription("col", "score column ",
5209 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5211 if (pp.getScoresFromDescription("description column",
5212 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5214 buildSortByAnnotationScoresMenu();
5222 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5226 protected void showDbRefs_actionPerformed(ActionEvent e)
5228 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5234 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5238 protected void showNpFeats_actionPerformed(ActionEvent e)
5240 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5244 * find the viewport amongst the tabs in this alignment frame and close that
5249 public boolean closeView(AlignViewportI av)
5253 this.closeMenuItem_actionPerformed(false);
5256 Component[] comp = tabbedPane.getComponents();
5257 for (int i = 0; comp != null && i < comp.length; i++)
5259 if (comp[i] instanceof AlignmentPanel)
5261 if (((AlignmentPanel) comp[i]).av == av)
5264 closeView((AlignmentPanel) comp[i]);
5272 protected void build_fetchdbmenu(JMenu webService)
5274 // Temporary hack - DBRef Fetcher always top level ws entry.
5275 // TODO We probably want to store a sequence database checklist in
5276 // preferences and have checkboxes.. rather than individual sources selected
5278 final JMenu rfetch = new JMenu(
5279 MessageManager.getString("action.fetch_db_references"));
5280 rfetch.setToolTipText(MessageManager.getString(
5281 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5282 webService.add(rfetch);
5284 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5285 MessageManager.getString("option.trim_retrieved_seqs"));
5286 trimrs.setToolTipText(
5287 MessageManager.getString("label.trim_retrieved_sequences"));
5289 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5290 trimrs.addActionListener(new ActionListener()
5293 public void actionPerformed(ActionEvent e)
5295 trimrs.setSelected(trimrs.isSelected());
5296 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5297 Boolean.valueOf(trimrs.isSelected()).toString());
5301 JMenuItem fetchr = new JMenuItem(
5302 MessageManager.getString("label.standard_databases"));
5303 fetchr.setToolTipText(
5304 MessageManager.getString("label.fetch_embl_uniprot"));
5305 fetchr.addActionListener(new ActionListener()
5309 public void actionPerformed(ActionEvent e)
5311 new Thread(new Runnable()
5316 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5317 .getAlignment().isNucleotide();
5318 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5319 alignPanel.av.getSequenceSelection(),
5320 alignPanel.alignFrame, null,
5321 alignPanel.alignFrame.featureSettings, isNucleotide);
5322 dbRefFetcher.addListener(new FetchFinishedListenerI()
5325 public void finished()
5328 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5329 .getFeatureSettingsModels())
5332 alignPanel.av.mergeFeaturesStyle(srcSettings);
5334 AlignFrame.this.setMenusForViewport();
5337 dbRefFetcher.fetchDBRefs(false);
5345 new Thread(new Runnable()
5350 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5351 .getSequenceFetcherSingleton();
5352 javax.swing.SwingUtilities.invokeLater(new Runnable()
5357 String[] dbclasses = sf.getNonAlignmentSources();
5358 List<DbSourceProxy> otherdb;
5359 JMenu dfetch = new JMenu();
5360 JMenu ifetch = new JMenu();
5361 JMenuItem fetchr = null;
5362 int comp = 0, icomp = 0, mcomp = 15;
5363 String mname = null;
5365 for (String dbclass : dbclasses)
5367 otherdb = sf.getSourceProxy(dbclass);
5368 // add a single entry for this class, or submenu allowing 'fetch
5370 if (otherdb == null || otherdb.size() < 1)
5376 mname = "From " + dbclass;
5378 if (otherdb.size() == 1)
5380 final DbSourceProxy[] dassource = otherdb
5381 .toArray(new DbSourceProxy[0]);
5382 DbSourceProxy src = otherdb.get(0);
5383 fetchr = new JMenuItem(src.getDbSource());
5384 fetchr.addActionListener(new ActionListener()
5388 public void actionPerformed(ActionEvent e)
5390 new Thread(new Runnable()
5396 boolean isNucleotide = alignPanel.alignFrame
5397 .getViewport().getAlignment()
5399 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5400 alignPanel.av.getSequenceSelection(),
5401 alignPanel.alignFrame, dassource,
5402 alignPanel.alignFrame.featureSettings,
5405 .addListener(new FetchFinishedListenerI()
5408 public void finished()
5410 FeatureSettingsModelI srcSettings = dassource[0]
5411 .getFeatureColourScheme();
5412 alignPanel.av.mergeFeaturesStyle(
5414 AlignFrame.this.setMenusForViewport();
5417 dbRefFetcher.fetchDBRefs(false);
5423 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5424 MessageManager.formatMessage(
5425 "label.fetch_retrieve_from", new Object[]
5426 { src.getDbName() })));
5432 final DbSourceProxy[] dassource = otherdb
5433 .toArray(new DbSourceProxy[0]);
5435 DbSourceProxy src = otherdb.get(0);
5436 fetchr = new JMenuItem(MessageManager
5437 .formatMessage("label.fetch_all_param", new Object[]
5438 { src.getDbSource() }));
5439 fetchr.addActionListener(new ActionListener()
5442 public void actionPerformed(ActionEvent e)
5444 new Thread(new Runnable()
5450 boolean isNucleotide = alignPanel.alignFrame
5451 .getViewport().getAlignment()
5453 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5454 alignPanel.av.getSequenceSelection(),
5455 alignPanel.alignFrame, dassource,
5456 alignPanel.alignFrame.featureSettings,
5459 .addListener(new FetchFinishedListenerI()
5462 public void finished()
5464 AlignFrame.this.setMenusForViewport();
5467 dbRefFetcher.fetchDBRefs(false);
5473 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5474 MessageManager.formatMessage(
5475 "label.fetch_retrieve_from_all_sources",
5477 { Integer.valueOf(otherdb.size())
5479 src.getDbSource(), src.getDbName() })));
5482 // and then build the rest of the individual menus
5483 ifetch = new JMenu(MessageManager.formatMessage(
5484 "label.source_from_db_source", new Object[]
5485 { src.getDbSource() }));
5487 String imname = null;
5489 for (DbSourceProxy sproxy : otherdb)
5491 String dbname = sproxy.getDbName();
5492 String sname = dbname.length() > 5
5493 ? dbname.substring(0, 5) + "..."
5495 String msname = dbname.length() > 10
5496 ? dbname.substring(0, 10) + "..."
5500 imname = MessageManager
5501 .formatMessage("label.from_msname", new Object[]
5504 fetchr = new JMenuItem(msname);
5505 final DbSourceProxy[] dassrc = { sproxy };
5506 fetchr.addActionListener(new ActionListener()
5510 public void actionPerformed(ActionEvent e)
5512 new Thread(new Runnable()
5518 boolean isNucleotide = alignPanel.alignFrame
5519 .getViewport().getAlignment()
5521 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5522 alignPanel.av.getSequenceSelection(),
5523 alignPanel.alignFrame, dassrc,
5524 alignPanel.alignFrame.featureSettings,
5527 .addListener(new FetchFinishedListenerI()
5530 public void finished()
5532 AlignFrame.this.setMenusForViewport();
5535 dbRefFetcher.fetchDBRefs(false);
5541 fetchr.setToolTipText(
5542 "<html>" + MessageManager.formatMessage(
5543 "label.fetch_retrieve_from", new Object[]
5547 if (++icomp >= mcomp || i == (otherdb.size()))
5549 ifetch.setText(MessageManager.formatMessage(
5550 "label.source_to_target", imname, sname));
5552 ifetch = new JMenu();
5560 if (comp >= mcomp || dbi >= (dbclasses.length))
5562 dfetch.setText(MessageManager.formatMessage(
5563 "label.source_to_target", mname, dbclass));
5565 dfetch = new JMenu();
5578 * Left justify the whole alignment.
5581 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5583 AlignmentI al = viewport.getAlignment();
5585 viewport.firePropertyChange("alignment", null, al);
5589 * Right justify the whole alignment.
5592 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5594 AlignmentI al = viewport.getAlignment();
5596 viewport.firePropertyChange("alignment", null, al);
5600 public void setShowSeqFeatures(boolean b)
5602 showSeqFeatures.setSelected(b);
5603 viewport.setShowSequenceFeatures(b);
5610 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5611 * awt.event.ActionEvent)
5614 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5616 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5617 alignPanel.paintAlignment(false, false);
5624 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5628 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5630 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5631 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5639 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5640 * .event.ActionEvent)
5643 protected void showGroupConservation_actionPerformed(ActionEvent e)
5645 viewport.setShowGroupConservation(showGroupConservation.getState());
5646 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5653 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5654 * .event.ActionEvent)
5657 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5659 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5660 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5667 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5668 * .event.ActionEvent)
5671 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5673 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5674 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5678 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5680 showSequenceLogo.setState(true);
5681 viewport.setShowSequenceLogo(true);
5682 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5683 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5687 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5689 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5696 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5697 * .event.ActionEvent)
5700 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5702 if (avc.makeGroupsFromSelection())
5704 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5705 alignPanel.updateAnnotation();
5706 alignPanel.paintAlignment(true,
5707 viewport.needToUpdateStructureViews());
5711 public void clearAlignmentSeqRep()
5713 // TODO refactor alignmentseqrep to controller
5714 if (viewport.getAlignment().hasSeqrep())
5716 viewport.getAlignment().setSeqrep(null);
5717 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5718 alignPanel.updateAnnotation();
5719 alignPanel.paintAlignment(true, true);
5724 protected void createGroup_actionPerformed(ActionEvent e)
5726 if (avc.createGroup())
5728 if (applyAutoAnnotationSettings.isSelected())
5730 alignPanel.updateAnnotation(true, false);
5732 alignPanel.alignmentChanged();
5737 protected void unGroup_actionPerformed(ActionEvent e)
5741 alignPanel.alignmentChanged();
5746 * make the given alignmentPanel the currently selected tab
5748 * @param alignmentPanel
5750 public void setDisplayedView(AlignmentPanel alignmentPanel)
5752 if (!viewport.getSequenceSetId()
5753 .equals(alignmentPanel.av.getSequenceSetId()))
5755 throw new Error(MessageManager.getString(
5756 "error.implementation_error_cannot_show_view_alignment_frame"));
5758 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5759 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5761 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5766 * Action on selection of menu options to Show or Hide annotations.
5769 * @param forSequences
5770 * update sequence-related annotations
5771 * @param forAlignment
5772 * update non-sequence-related annotations
5775 public void setAnnotationsVisibility(boolean visible,
5776 boolean forSequences, boolean forAlignment)
5778 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5779 .getAlignmentAnnotation();
5784 for (AlignmentAnnotation aa : anns)
5787 * don't display non-positional annotations on an alignment
5789 if (aa.annotations == null)
5793 boolean apply = (aa.sequenceRef == null && forAlignment)
5794 || (aa.sequenceRef != null && forSequences);
5797 aa.visible = visible;
5800 alignPanel.validateAnnotationDimensions(true);
5801 alignPanel.alignmentChanged();
5805 * Store selected annotation sort order for the view and repaint.
5808 protected void sortAnnotations_actionPerformed()
5810 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5812 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5813 alignPanel.paintAlignment(false, false);
5818 * @return alignment panels in this alignment frame
5820 public List<? extends AlignmentViewPanel> getAlignPanels()
5822 // alignPanels is never null
5823 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5828 * Open a new alignment window, with the cDNA associated with this (protein)
5829 * alignment, aligned as is the protein.
5831 protected void viewAsCdna_actionPerformed()
5833 // TODO no longer a menu action - refactor as required
5834 final AlignmentI alignment = getViewport().getAlignment();
5835 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5836 if (mappings == null)
5840 List<SequenceI> cdnaSeqs = new ArrayList<>();
5841 for (SequenceI aaSeq : alignment.getSequences())
5843 for (AlignedCodonFrame acf : mappings)
5845 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5849 * There is a cDNA mapping for this protein sequence - add to new
5850 * alignment. It will share the same dataset sequence as other mapped
5851 * cDNA (no new mappings need to be created).
5853 final Sequence newSeq = new Sequence(dnaSeq);
5854 newSeq.setDatasetSequence(dnaSeq);
5855 cdnaSeqs.add(newSeq);
5859 if (cdnaSeqs.size() == 0)
5861 // show a warning dialog no mapped cDNA
5864 AlignmentI cdna = new Alignment(
5865 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5866 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5867 AlignFrame.DEFAULT_HEIGHT);
5868 cdna.alignAs(alignment);
5869 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5871 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5872 AlignFrame.DEFAULT_HEIGHT);
5876 * Set visibility of dna/protein complement view (available when shown in a
5882 protected void showComplement_actionPerformed(boolean show)
5884 SplitContainerI sf = getSplitViewContainer();
5887 sf.setComplementVisible(this, show);
5892 * Generate the reverse (optionally complemented) of the selected sequences,
5893 * and add them to the alignment
5896 protected void showReverse_actionPerformed(boolean complement)
5898 AlignmentI al = null;
5901 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5902 al = dna.reverseCdna(complement);
5903 viewport.addAlignment(al, "");
5904 addHistoryItem(new EditCommand(
5905 MessageManager.getString("label.add_sequences"), Action.PASTE,
5906 al.getSequencesArray(), 0, al.getWidth(),
5907 viewport.getAlignment()));
5908 } catch (Exception ex)
5910 System.err.println(ex.getMessage());
5916 * Try to run a script in the Groovy console, having first ensured that this
5917 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5918 * be targeted at this alignment.
5921 protected void runGroovy_actionPerformed()
5923 Jalview.setCurrentAlignFrame(this);
5924 groovy.ui.Console console = Desktop.getGroovyConsole();
5925 if (console != null)
5929 console.runScript();
5930 } catch (Exception ex)
5932 System.err.println((ex.toString()));
5933 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5934 MessageManager.getString("label.couldnt_run_groovy_script"),
5935 MessageManager.getString("label.groovy_support_failed"),
5936 JvOptionPane.ERROR_MESSAGE);
5941 System.err.println("Can't run Groovy script as console not found");
5946 * Hides columns containing (or not containing) a specified feature, provided
5947 * that would not leave all columns hidden
5949 * @param featureType
5950 * @param columnsContaining
5953 public boolean hideFeatureColumns(String featureType,
5954 boolean columnsContaining)
5956 boolean notForHiding = avc.markColumnsContainingFeatures(
5957 columnsContaining, false, false, featureType);
5960 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5961 false, featureType))
5963 getViewport().hideSelectedColumns();
5971 protected void selectHighlightedColumns_actionPerformed(
5972 ActionEvent actionEvent)
5974 // include key modifier check in case user selects from menu
5975 avc.markHighlightedColumns(
5976 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5977 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5978 | ActionEvent.CTRL_MASK)) != 0);
5982 protected void copyHighlightedColumns_actionPerformed(
5983 ActionEvent actionEvent)
5985 avc.copyHighlightedRegionsToClipboard();
5989 * Rebuilds the Colour menu, including any user-defined colours which have
5990 * been loaded either on startup or during the session
5992 public void buildColourMenu()
5994 colourMenu.removeAll();
5996 colourMenu.add(applyToAllGroups);
5997 colourMenu.add(textColour);
5998 colourMenu.addSeparator();
6000 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6001 viewport.getAlignment(), false);
6003 colourMenu.add(annotationColour);
6004 bg.add(annotationColour);
6005 colourMenu.addSeparator();
6006 colourMenu.add(conservationMenuItem);
6007 colourMenu.add(modifyConservation);
6008 colourMenu.add(abovePIDThreshold);
6009 colourMenu.add(modifyPID);
6011 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6012 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6016 * Open a dialog (if not already open) that allows the user to select and
6017 * calculate PCA or Tree analysis
6019 protected void openTreePcaDialog()
6021 if (alignPanel.getCalculationDialog() == null)
6023 new CalculationChooser(AlignFrame.this);
6028 protected void loadVcf_actionPerformed()
6030 JalviewFileChooser chooser = new JalviewFileChooser(
6031 Cache.getProperty("LAST_DIRECTORY"));
6032 chooser.setFileView(new JalviewFileView());
6033 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6034 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6035 final AlignFrame us = this;
6036 chooser.setResponseHandler(0, () -> {
6037 String choice = chooser.getSelectedFile().getPath();
6038 Cache.setProperty("LAST_DIRECTORY", choice);
6039 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6040 new VCFLoader(choice).loadVCF(seqs, us);
6042 chooser.showOpenDialog(null);
6046 private Rectangle lastFeatureSettingsBounds = null;
6049 public void setFeatureSettingsGeometry(Rectangle bounds)
6051 lastFeatureSettingsBounds = bounds;
6055 public Rectangle getFeatureSettingsGeometry()
6057 return lastFeatureSettingsBounds;
6062 class PrintThread extends Thread
6066 public PrintThread(AlignmentPanel ap)
6071 static PageFormat pf;
6076 PrinterJob printJob = PrinterJob.getPrinterJob();
6080 printJob.setPrintable(ap, pf);
6084 printJob.setPrintable(ap);
6087 if (printJob.printDialog())
6092 } catch (Exception PrintException)
6094 PrintException.printStackTrace();