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.datamodel.alphafold.PAEContactMatrix;
161 import jalview.ws.jws1.Discoverer;
162 import jalview.ws.jws2.Jws2Discoverer;
163 import jalview.ws.jws2.jabaws2.Jws2Instance;
164 import jalview.ws.seqfetcher.DbSourceProxy;
170 * @version $Revision$
172 @SuppressWarnings("serial")
173 public class AlignFrame extends GAlignFrame implements DropTargetListener,
174 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
177 public static final int DEFAULT_WIDTH = 700;
179 public static final int DEFAULT_HEIGHT = 500;
182 * The currently displayed panel (selected tabbed view if more than one)
184 public AlignmentPanel alignPanel;
186 AlignViewport viewport;
188 public AlignViewControllerI avc;
190 List<AlignmentPanel> alignPanels = new ArrayList<>();
193 * Last format used to load or save alignments in this window
195 FileFormatI currentFileFormat = null;
198 * Current filename for this alignment
200 String fileName = null;
205 * Creates a new AlignFrame object with specific width and height.
211 public AlignFrame(AlignmentI al, int width, int height)
213 this(al, null, width, height);
217 * Creates a new AlignFrame object with specific width, height and
223 * @param sequenceSetId
225 public AlignFrame(AlignmentI al, int width, int height,
226 String sequenceSetId)
228 this(al, null, width, height, sequenceSetId);
232 * Creates a new AlignFrame object with specific width, height and
238 * @param sequenceSetId
241 public AlignFrame(AlignmentI al, int width, int height,
242 String sequenceSetId, String viewId)
244 this(al, null, width, height, sequenceSetId, viewId);
248 * new alignment window with hidden columns
252 * @param hiddenColumns
253 * ColumnSelection or null
255 * Width of alignment frame
259 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
262 this(al, hiddenColumns, width, height, null);
266 * Create alignment frame for al with hiddenColumns, a specific width and
267 * height, and specific sequenceId
270 * @param hiddenColumns
273 * @param sequenceSetId
276 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
277 int height, String sequenceSetId)
279 this(al, hiddenColumns, width, height, sequenceSetId, null);
283 * Create alignment frame for al with hiddenColumns, a specific width and
284 * height, and specific sequenceId
287 * @param hiddenColumns
290 * @param sequenceSetId
295 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
296 int height, String sequenceSetId, String viewId)
298 setSize(width, height);
300 if (al.getDataset() == null)
305 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
307 alignPanel = new AlignmentPanel(this, viewport);
309 addAlignmentPanel(alignPanel, true);
313 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
314 HiddenColumns hiddenColumns, int width, int height)
316 setSize(width, height);
318 if (al.getDataset() == null)
323 viewport = new AlignViewport(al, hiddenColumns);
325 if (hiddenSeqs != null && hiddenSeqs.length > 0)
327 viewport.hideSequence(hiddenSeqs);
329 alignPanel = new AlignmentPanel(this, viewport);
330 addAlignmentPanel(alignPanel, true);
335 * Make a new AlignFrame from existing alignmentPanels
342 public AlignFrame(AlignmentPanel ap)
346 addAlignmentPanel(ap, false);
351 * initalise the alignframe from the underlying viewport data and the
358 // setBackground(Color.white); // BH 2019
360 if (!Jalview.isHeadlessMode())
362 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
365 avc = new jalview.controller.AlignViewController(this, viewport,
367 if (viewport.getAlignmentConservationAnnotation() == null)
369 // BLOSUM62Colour.setEnabled(false);
370 conservationMenuItem.setEnabled(false);
371 modifyConservation.setEnabled(false);
372 // PIDColour.setEnabled(false);
373 // abovePIDThreshold.setEnabled(false);
374 // modifyPID.setEnabled(false);
377 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
379 if (sortby.equals("Id"))
381 sortIDMenuItem_actionPerformed(null);
383 else if (sortby.equals("Pairwise Identity"))
385 sortPairwiseMenuItem_actionPerformed(null);
389 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
391 setMenusFromViewport(viewport);
392 buildSortByAnnotationScoresMenu();
393 calculateTree.addActionListener(new ActionListener()
397 public void actionPerformed(ActionEvent e)
404 if (Desktop.desktop != null)
406 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
407 if (!Platform.isJS())
409 addServiceListeners();
414 if (viewport.getWrapAlignment())
416 wrapMenuItem_actionPerformed(null);
419 if (Cache.getDefault("SHOW_OVERVIEW", false))
421 this.overviewMenuItem_actionPerformed(null);
426 final List<AlignmentViewPanel> selviews = new ArrayList<>();
427 final List<AlignmentPanel> origview = new ArrayList<>();
428 final String menuLabel = MessageManager
429 .getString("label.copy_format_from");
430 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
431 new ViewSetProvider()
435 public AlignmentPanel[] getAllAlignmentPanels()
438 origview.add(alignPanel);
439 // make an array of all alignment panels except for this one
440 List<AlignmentPanel> aps = new ArrayList<>(
441 Arrays.asList(Desktop.getAlignmentPanels(null)));
442 aps.remove(AlignFrame.this.alignPanel);
443 return aps.toArray(new AlignmentPanel[aps.size()]);
445 }, selviews, new ItemListener()
449 public void itemStateChanged(ItemEvent e)
451 if (origview.size() > 0)
453 final AlignmentPanel ap = origview.get(0);
456 * Copy the ViewStyle of the selected panel to 'this one'.
457 * Don't change value of 'scaleProteinAsCdna' unless copying
460 ViewStyleI vs = selviews.get(0).getAlignViewport()
462 boolean fromSplitFrame = selviews.get(0)
463 .getAlignViewport().getCodingComplement() != null;
466 vs.setScaleProteinAsCdna(ap.getAlignViewport()
467 .getViewStyle().isScaleProteinAsCdna());
469 ap.getAlignViewport().setViewStyle(vs);
472 * Also rescale ViewStyle of SplitFrame complement if there is
473 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
474 * the whole ViewStyle (allow cDNA protein to have different
477 AlignViewportI complement = ap.getAlignViewport()
478 .getCodingComplement();
479 if (complement != null && vs.isScaleProteinAsCdna())
481 AlignFrame af = Desktop.getAlignFrameFor(complement);
482 ((SplitFrame) af.getSplitViewContainer())
484 af.setMenusForViewport();
488 ap.setSelected(true);
489 ap.alignFrame.setMenusForViewport();
494 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
495 .indexOf("devel") > -1
496 || Cache.getDefault("VERSION", "DEVELOPMENT")
497 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
499 formatMenu.add(vsel);
501 addFocusListener(new FocusAdapter()
504 public void focusGained(FocusEvent e)
506 Jalview.setCurrentAlignFrame(AlignFrame.this);
513 * Change the filename and format for the alignment, and enable the 'reload'
514 * button functionality.
521 public void setFileName(String file, FileFormatI format)
524 setFileFormat(format);
525 reload.setEnabled(true);
529 * JavaScript will have this, maybe others. More dependable than a file name
530 * and maintains a reference to the actual bytes loaded.
534 public void setFileObject(File file)
536 this.fileObject = file;
540 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
543 void addKeyListener()
545 addKeyListener(new KeyAdapter()
548 public void keyPressed(KeyEvent evt)
550 if (viewport.cursorMode
551 && ((evt.getKeyCode() >= KeyEvent.VK_0
552 && evt.getKeyCode() <= KeyEvent.VK_9)
553 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
554 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
555 && Character.isDigit(evt.getKeyChar()))
557 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
560 switch (evt.getKeyCode())
563 case 27: // escape key
564 deselectAllSequenceMenuItem_actionPerformed(null);
568 case KeyEvent.VK_DOWN:
569 if (evt.isAltDown() || !viewport.cursorMode)
571 moveSelectedSequences(false);
573 if (viewport.cursorMode)
575 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
580 if (evt.isAltDown() || !viewport.cursorMode)
582 moveSelectedSequences(true);
584 if (viewport.cursorMode)
586 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
591 case KeyEvent.VK_LEFT:
592 if (evt.isAltDown() || !viewport.cursorMode)
594 slideSequences(false,
595 alignPanel.getSeqPanel().getKeyboardNo1());
599 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
604 case KeyEvent.VK_RIGHT:
605 if (evt.isAltDown() || !viewport.cursorMode)
607 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
611 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
615 case KeyEvent.VK_SPACE:
616 if (viewport.cursorMode)
618 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
619 || evt.isShiftDown() || evt.isAltDown());
623 // case KeyEvent.VK_A:
624 // if (viewport.cursorMode)
626 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
627 // //System.out.println("A");
631 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
632 * System.out.println("closing bracket"); } break;
634 case KeyEvent.VK_DELETE:
635 case KeyEvent.VK_BACK_SPACE:
636 if (!viewport.cursorMode)
638 cut_actionPerformed();
642 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
643 || evt.isShiftDown() || evt.isAltDown());
649 if (viewport.cursorMode)
651 alignPanel.getSeqPanel().setCursorRow();
655 if (viewport.cursorMode && !evt.isControlDown())
657 alignPanel.getSeqPanel().setCursorColumn();
661 if (viewport.cursorMode)
663 alignPanel.getSeqPanel().setCursorPosition();
667 case KeyEvent.VK_ENTER:
668 case KeyEvent.VK_COMMA:
669 if (viewport.cursorMode)
671 alignPanel.getSeqPanel().setCursorRowAndColumn();
676 if (viewport.cursorMode)
678 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
682 if (viewport.cursorMode)
684 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
689 viewport.cursorMode = !viewport.cursorMode;
690 setStatus(MessageManager
691 .formatMessage("label.keyboard_editing_mode", new String[]
692 { (viewport.cursorMode ? "on" : "off") }));
693 if (viewport.cursorMode)
695 ViewportRanges ranges = viewport.getRanges();
696 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
698 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
701 alignPanel.getSeqPanel().seqCanvas.repaint();
707 Help.showHelpWindow();
708 } catch (Exception ex)
710 ex.printStackTrace();
715 boolean toggleSeqs = !evt.isControlDown();
716 boolean toggleCols = !evt.isShiftDown();
717 toggleHiddenRegions(toggleSeqs, toggleCols);
722 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
723 boolean modifyExisting = true; // always modify, don't clear
724 // evt.isShiftDown();
725 boolean invertHighlighted = evt.isAltDown();
726 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
730 case KeyEvent.VK_PAGE_UP:
731 viewport.getRanges().pageUp();
733 case KeyEvent.VK_PAGE_DOWN:
734 viewport.getRanges().pageDown();
740 public void keyReleased(KeyEvent evt)
742 switch (evt.getKeyCode())
744 case KeyEvent.VK_LEFT:
745 if (evt.isAltDown() || !viewport.cursorMode)
747 viewport.firePropertyChange("alignment", null,
748 viewport.getAlignment().getSequences());
752 case KeyEvent.VK_RIGHT:
753 if (evt.isAltDown() || !viewport.cursorMode)
755 viewport.firePropertyChange("alignment", null,
756 viewport.getAlignment().getSequences());
764 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
766 ap.alignFrame = this;
767 avc = new jalview.controller.AlignViewController(this, viewport,
772 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
774 int aSize = alignPanels.size();
776 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
778 if (aSize == 1 && ap.av.getViewName() == null)
780 this.getContentPane().add(ap, BorderLayout.CENTER);
786 setInitialTabVisible();
789 expandViews.setEnabled(true);
790 gatherViews.setEnabled(true);
791 tabbedPane.addTab(ap.av.getViewName(), ap);
793 ap.setVisible(false);
798 if (ap.av.isPadGaps())
800 ap.av.getAlignment().padGaps();
802 ap.av.updateConservation(ap);
803 ap.av.updateConsensus(ap);
804 ap.av.updateStrucConsensus(ap);
808 public void setInitialTabVisible()
810 expandViews.setEnabled(true);
811 gatherViews.setEnabled(true);
812 tabbedPane.setVisible(true);
813 AlignmentPanel first = alignPanels.get(0);
814 tabbedPane.addTab(first.av.getViewName(), first);
815 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
818 public AlignViewport getViewport()
823 /* Set up intrinsic listeners for dynamically generated GUI bits. */
824 private void addServiceListeners()
826 final java.beans.PropertyChangeListener thisListener;
827 Desktop.instance.addJalviewPropertyChangeListener("services",
828 thisListener = new java.beans.PropertyChangeListener()
831 public void propertyChange(PropertyChangeEvent evt)
833 // // System.out.println("Discoverer property change.");
834 // if (evt.getPropertyName().equals("services"))
836 SwingUtilities.invokeLater(new Runnable()
843 "Rebuild WS Menu for service change");
844 BuildWebServiceMenu();
851 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
854 public void internalFrameClosed(
855 javax.swing.event.InternalFrameEvent evt)
857 // System.out.println("deregistering discoverer listener");
858 Desktop.instance.removeJalviewPropertyChangeListener("services",
860 closeMenuItem_actionPerformed(true);
863 // Finally, build the menu once to get current service state
864 new Thread(new Runnable()
869 BuildWebServiceMenu();
875 * Configure menu items that vary according to whether the alignment is
876 * nucleotide or protein
878 public void setGUINucleotide()
880 AlignmentI al = getViewport().getAlignment();
881 boolean nucleotide = al.isNucleotide();
883 loadVcf.setVisible(nucleotide);
884 showTranslation.setVisible(nucleotide);
885 showReverse.setVisible(nucleotide);
886 showReverseComplement.setVisible(nucleotide);
887 conservationMenuItem.setEnabled(!nucleotide);
889 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
890 showGroupConservation.setEnabled(!nucleotide);
892 showComplementMenuItem
893 .setText(nucleotide ? MessageManager.getString("label.protein")
894 : MessageManager.getString("label.nucleotide"));
898 * set up menus for the current viewport. This may be called after any
899 * operation that affects the data in the current view (selection changed,
900 * etc) to update the menus to reflect the new state.
903 public void setMenusForViewport()
905 setMenusFromViewport(viewport);
909 * Need to call this method when tabs are selected for multiple views, or when
910 * loading from Jalview2XML.java
915 public void setMenusFromViewport(AlignViewport av)
917 padGapsMenuitem.setSelected(av.isPadGaps());
918 colourTextMenuItem.setSelected(av.isShowColourText());
919 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
920 modifyPID.setEnabled(abovePIDThreshold.isSelected());
921 conservationMenuItem.setSelected(av.getConservationSelected());
922 modifyConservation.setEnabled(conservationMenuItem.isSelected());
923 seqLimits.setSelected(av.getShowJVSuffix());
924 idRightAlign.setSelected(av.isRightAlignIds());
925 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
926 renderGapsMenuItem.setSelected(av.isRenderGaps());
927 wrapMenuItem.setSelected(av.getWrapAlignment());
928 scaleAbove.setVisible(av.getWrapAlignment());
929 scaleLeft.setVisible(av.getWrapAlignment());
930 scaleRight.setVisible(av.getWrapAlignment());
931 annotationPanelMenuItem.setState(av.isShowAnnotation());
933 * Show/hide annotations only enabled if annotation panel is shown
935 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
936 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
939 viewBoxesMenuItem.setSelected(av.getShowBoxes());
940 viewTextMenuItem.setSelected(av.getShowText());
941 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
942 showGroupConsensus.setSelected(av.isShowGroupConsensus());
943 showGroupConservation.setSelected(av.isShowGroupConservation());
944 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
945 showSequenceLogo.setSelected(av.isShowSequenceLogo());
946 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
948 ColourMenuHelper.setColourSelected(colourMenu,
949 av.getGlobalColourScheme());
951 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
952 hiddenMarkers.setState(av.getShowHiddenMarkers());
953 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
954 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
955 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
956 autoCalculate.setSelected(av.autoCalculateConsensus);
957 sortByTree.setSelected(av.sortByTree);
958 listenToViewSelections.setSelected(av.followSelection);
960 showProducts.setEnabled(canShowProducts());
961 setGroovyEnabled(Desktop.getGroovyConsole() != null);
967 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
971 public void setGroovyEnabled(boolean b)
973 runGroovy.setEnabled(b);
976 private IProgressIndicator progressBar;
981 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
984 public void setProgressBar(String message, long id)
986 if (!Platform.isHeadless() && progressBar != null)
987 progressBar.setProgressBar(message, id);
991 public void registerHandler(final long id,
992 final IProgressIndicatorHandler handler)
994 if (progressBar != null)
995 progressBar.registerHandler(id, handler);
1000 * @return true if any progress bars are still active
1003 public boolean operationInProgress()
1005 return progressBar == null ? false : progressBar.operationInProgress();
1009 * Sets the text of the status bar. Note that setting a null or empty value
1010 * will cause the status bar to be hidden, with possibly undesirable flicker
1011 * of the screen layout.
1014 public void setStatus(String text)
1016 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1020 * Added so Castor Mapping file can obtain Jalview Version
1022 public String getVersion()
1024 return Cache.getProperty("VERSION");
1027 public FeatureRenderer getFeatureRenderer()
1029 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1033 public void fetchSequence_actionPerformed()
1035 new SequenceFetcher(this);
1039 public void addFromFile_actionPerformed(ActionEvent e)
1041 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1045 public void reload_actionPerformed(ActionEvent e)
1047 if (fileName != null)
1049 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1050 // originating file's format
1051 // TODO: work out how to recover feature settings for correct view(s) when
1052 // file is reloaded.
1053 if (FileFormat.Jalview.equals(currentFileFormat))
1055 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1056 for (int i = 0; i < frames.length; i++)
1058 if (frames[i] instanceof AlignFrame && frames[i] != this
1059 && ((AlignFrame) frames[i]).fileName != null
1060 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1064 frames[i].setSelected(true);
1065 Desktop.instance.closeAssociatedWindows();
1066 } catch (java.beans.PropertyVetoException ex)
1072 Desktop.instance.closeAssociatedWindows();
1074 FileLoader loader = new FileLoader();
1075 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1076 ? DataSourceType.URL
1077 : DataSourceType.FILE;
1078 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1082 Rectangle bounds = this.getBounds();
1084 FileLoader loader = new FileLoader();
1086 AlignFrame newframe = null;
1088 if (fileObject == null)
1091 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1092 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1093 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1098 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1099 DataSourceType.FILE, currentFileFormat);
1102 newframe.setBounds(bounds);
1103 if (featureSettings != null && featureSettings.isShowing())
1105 final Rectangle fspos = featureSettings.frame.getBounds();
1106 // TODO: need a 'show feature settings' function that takes bounds -
1107 // need to refactor Desktop.addFrame
1108 newframe.featureSettings_actionPerformed(null);
1109 final FeatureSettings nfs = newframe.featureSettings;
1110 SwingUtilities.invokeLater(new Runnable()
1115 nfs.frame.setBounds(fspos);
1118 this.featureSettings.close();
1119 this.featureSettings = null;
1121 this.closeMenuItem_actionPerformed(true);
1127 public void addFromText_actionPerformed(ActionEvent e)
1130 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1134 public void addFromURL_actionPerformed(ActionEvent e)
1136 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1140 public void save_actionPerformed(ActionEvent e)
1142 if (fileName == null || (currentFileFormat == null)
1143 || HttpUtils.startsWithHttpOrHttps(fileName))
1145 saveAs_actionPerformed();
1149 saveAlignment(fileName, currentFileFormat);
1154 * Saves the alignment to a file with a name chosen by the user, if necessary
1155 * warning if a file would be overwritten
1158 public void saveAs_actionPerformed()
1160 String format = currentFileFormat == null ? null
1161 : currentFileFormat.getName();
1162 JalviewFileChooser chooser = JalviewFileChooser
1163 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1165 chooser.setFileView(new JalviewFileView());
1166 chooser.setDialogTitle(
1167 MessageManager.getString("label.save_alignment_to_file"));
1168 chooser.setToolTipText(MessageManager.getString("action.save"));
1170 int value = chooser.showSaveDialog(this);
1172 if (value != JalviewFileChooser.APPROVE_OPTION)
1176 currentFileFormat = chooser.getSelectedFormat();
1177 // todo is this (2005) test now obsolete - value is never null?
1178 while (currentFileFormat == null)
1180 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1182 .getString("label.select_file_format_before_saving"),
1183 MessageManager.getString("label.file_format_not_specified"),
1184 JvOptionPane.WARNING_MESSAGE);
1185 currentFileFormat = chooser.getSelectedFormat();
1186 value = chooser.showSaveDialog(this);
1187 if (value != JalviewFileChooser.APPROVE_OPTION)
1193 fileName = chooser.getSelectedFile().getPath();
1195 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1196 Cache.setProperty("LAST_DIRECTORY", fileName);
1197 saveAlignment(fileName, currentFileFormat);
1200 boolean lastSaveSuccessful = false;
1202 FileFormatI lastFormatSaved;
1204 String lastFilenameSaved;
1207 * Raise a dialog or status message for the last call to saveAlignment.
1209 * @return true if last call to saveAlignment(file, format) was successful.
1211 public boolean isSaveAlignmentSuccessful()
1214 if (!lastSaveSuccessful)
1216 if (!Platform.isHeadless())
1218 JvOptionPane.showInternalMessageDialog(this, MessageManager
1219 .formatMessage("label.couldnt_save_file", new Object[]
1220 { lastFilenameSaved }),
1221 MessageManager.getString("label.error_saving_file"),
1222 JvOptionPane.WARNING_MESSAGE);
1226 Console.error(MessageManager
1227 .formatMessage("label.couldnt_save_file", new Object[]
1228 { lastFilenameSaved }));
1234 setStatus(MessageManager.formatMessage(
1235 "label.successfully_saved_to_file_in_format", new Object[]
1236 { lastFilenameSaved, lastFormatSaved }));
1239 return lastSaveSuccessful;
1243 * Saves the alignment to the specified file path, in the specified format,
1244 * which may be an alignment format, or Jalview project format. If the
1245 * alignment has hidden regions, or the format is one capable of including
1246 * non-sequence data (features, annotations, groups), then the user may be
1247 * prompted to specify what to include in the output.
1252 public void saveAlignment(String file, FileFormatI format)
1254 lastSaveSuccessful = true;
1255 lastFilenameSaved = file;
1256 lastFormatSaved = format;
1258 if (FileFormat.Jalview.equals(format))
1260 String shortName = title;
1261 if (shortName.indexOf(File.separatorChar) > -1)
1263 shortName = shortName
1264 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1266 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1269 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1270 if (lastSaveSuccessful)
1272 this.getViewport().setSavedUpToDate(true);
1275 statusBar.setText(MessageManager.formatMessage(
1276 "label.successfully_saved_to_file_in_format", new Object[]
1282 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1283 Runnable cancelAction = () -> {
1284 lastSaveSuccessful = false;
1286 Runnable outputAction = () -> {
1287 // todo defer this to inside formatSequences (or later)
1288 AlignmentExportData exportData = viewport.getAlignExportData(options);
1289 String output = new FormatAdapter(alignPanel, options)
1290 .formatSequences(format, exportData.getAlignment(),
1291 exportData.getOmitHidden(),
1292 exportData.getStartEndPostions(),
1293 viewport.getAlignment().getHiddenColumns());
1296 lastSaveSuccessful = false;
1300 // create backupfiles object and get new temp filename destination
1301 boolean doBackup = BackupFiles.getEnabled();
1302 BackupFiles backupfiles = null;
1305 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1306 backupfiles = new BackupFiles(file);
1310 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1312 Console.trace("ALIGNFRAME setting PrintWriter");
1313 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1315 if (backupfiles != null)
1317 Console.trace("ALIGNFRAME about to write to temp file "
1318 + backupfiles.getTempFilePath());
1322 Console.trace("ALIGNFRAME about to close file");
1324 Console.trace("ALIGNFRAME closed file");
1325 AlignFrame.this.setTitle(file);
1326 statusBar.setText(MessageManager.formatMessage(
1327 "label.successfully_saved_to_file_in_format", new Object[]
1328 { fileName, format.getName() }));
1329 lastSaveSuccessful = true;
1330 } catch (IOException e)
1332 lastSaveSuccessful = false;
1334 "ALIGNFRAME Something happened writing the temp file");
1335 Console.error(e.getMessage());
1336 Console.debug(Cache.getStackTraceString(e));
1337 } catch (Exception ex)
1339 lastSaveSuccessful = false;
1341 "ALIGNFRAME Something unexpected happened writing the temp file");
1342 Console.error(ex.getMessage());
1343 Console.debug(Cache.getStackTraceString(ex));
1348 backupfiles.setWriteSuccess(lastSaveSuccessful);
1349 Console.debug("ALIGNFRAME writing temp file was "
1350 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1351 // do the backup file roll and rename the temp file to actual file
1352 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1353 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1354 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1355 + (lastSaveSuccessful ? "" : "un") + "successfully");
1358 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1359 if (lastSaveSuccessful)
1361 AlignFrame.this.getViewport().setSavedUpToDate(true);
1367 * show dialog with export options if applicable; else just do it
1369 if (AlignExportOptions.isNeeded(viewport, format))
1371 AlignExportOptions choices = new AlignExportOptions(
1372 alignPanel.getAlignViewport(), format, options);
1373 choices.setResponseAction(0, outputAction);
1374 choices.setResponseAction(1, cancelAction);
1375 choices.showDialog();
1382 } catch (Exception e)
1384 // TODO Auto-generated catch block
1385 e.printStackTrace();
1391 * Outputs the alignment to textbox in the requested format, if necessary
1392 * first prompting the user for whether to include hidden regions or
1395 * @param fileFormatName
1398 protected void outputText_actionPerformed(String fileFormatName)
1400 FileFormatI fileFormat = FileFormats.getInstance()
1401 .forName(fileFormatName);
1402 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1403 Runnable outputAction = () -> {
1404 // todo defer this to inside formatSequences (or later)
1405 AlignmentExportData exportData = viewport.getAlignExportData(options);
1406 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1407 cap.setForInput(null);
1410 FileFormatI format = fileFormat;
1411 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1412 format, exportData.getAlignment(),
1413 exportData.getOmitHidden(),
1414 exportData.getStartEndPostions(),
1415 viewport.getAlignment().getHiddenColumns()));
1416 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1417 "label.alignment_output_command", new Object[]
1418 { fileFormat.getName() }), 600, 500);
1419 } catch (OutOfMemoryError oom)
1421 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1428 * show dialog with export options if applicable; else just do it
1430 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1432 AlignExportOptions choices = new AlignExportOptions(
1433 alignPanel.getAlignViewport(), fileFormat, options);
1434 choices.setResponseAction(0, outputAction);
1435 choices.showDialog();
1442 } catch (Exception e)
1444 e.printStackTrace();
1456 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1458 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1460 htmlSVG.exportHTML(null);
1461 } catch (ImageOutputException x) {
1462 // report problem to console and raise dialog
1467 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1469 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1471 bjs.exportHTML(null);
1472 } catch (ImageOutputException x) {
1473 // report problem to console and raise dialog
1477 public void createImageMap(File file, String image)
1480 alignPanel.makePNGImageMap(file, image);
1481 } catch (ImageOutputException x) {
1482 // report problem to console and raise dialog
1487 public void createPNG_actionPerformed(ActionEvent e) {
1490 } catch (ImageOutputException ioex)
1492 // raise dialog, and report via console
1496 public void createEPS_actionPerformed(ActionEvent e) {
1499 } catch (ImageOutputException ioex)
1501 // raise dialog, and report via console
1506 public void createSVG_actionPerformed(ActionEvent e) {
1509 } catch (ImageOutputException ioex)
1511 // raise dialog, and report via console
1516 * Creates a PNG image of the alignment and writes it to the given file. If
1517 * the file is null, the user is prompted to choose a file.
1521 public void createPNG(File f) throws ImageOutputException
1523 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1526 public void createPNG(File f, String renderer, BitmapImageSizing userBis) throws ImageOutputException
1528 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1532 * Creates an EPS image of the alignment and writes it to the given file. If
1533 * the file is null, the user is prompted to choose a file.
1537 public void createEPS(File f) throws ImageOutputException
1542 public void createEPS(File f, String renderer) throws ImageOutputException
1544 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1548 * Creates an SVG image of the alignment and writes it to the given file. If
1549 * the file is null, the user is prompted to choose a file.
1553 public void createSVG(File f) throws ImageOutputException
1558 public void createSVG(File f, String renderer) throws ImageOutputException
1560 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1564 public void pageSetup_actionPerformed(ActionEvent e)
1566 PrinterJob printJob = PrinterJob.getPrinterJob();
1567 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1577 public void printMenuItem_actionPerformed(ActionEvent e)
1579 // Putting in a thread avoids Swing painting problems
1580 PrintThread thread = new PrintThread(alignPanel);
1585 public void exportFeatures_actionPerformed(ActionEvent e)
1587 new AnnotationExporter(alignPanel).exportFeatures();
1591 public void exportAnnotations_actionPerformed(ActionEvent e)
1593 new AnnotationExporter(alignPanel).exportAnnotations();
1597 public void associatedData_actionPerformed(ActionEvent e)
1599 final JalviewFileChooser chooser = new JalviewFileChooser(
1600 Cache.getProperty("LAST_DIRECTORY"));
1601 chooser.setFileView(new JalviewFileView());
1602 String tooltip = MessageManager
1603 .getString("label.load_jalview_annotations");
1604 chooser.setDialogTitle(tooltip);
1605 chooser.setToolTipText(tooltip);
1606 chooser.setResponseHandler(0, () -> {
1607 String choice = chooser.getSelectedFile().getPath();
1608 Cache.setProperty("LAST_DIRECTORY", choice);
1609 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1612 chooser.showOpenDialog(this);
1616 * Close the current view or all views in the alignment frame. If the frame
1617 * only contains one view then the alignment will be removed from memory.
1619 * @param closeAllTabs
1622 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1624 if (alignPanels != null && alignPanels.size() < 2)
1626 closeAllTabs = true;
1631 if (alignPanels != null)
1635 if (this.isClosed())
1637 // really close all the windows - otherwise wait till
1638 // setClosed(true) is called
1639 for (int i = 0; i < alignPanels.size(); i++)
1641 AlignmentPanel ap = alignPanels.get(i);
1648 closeView(alignPanel);
1653 if (featureSettings != null && featureSettings.isOpen())
1655 featureSettings.close();
1656 featureSettings = null;
1659 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1660 * be called recursively, with the frame now in 'closed' state
1662 this.setClosed(true);
1664 } catch (Exception ex)
1666 ex.printStackTrace();
1671 * Close the specified panel and close up tabs appropriately.
1673 * @param panelToClose
1675 public void closeView(AlignmentPanel panelToClose)
1677 int index = tabbedPane.getSelectedIndex();
1678 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1679 alignPanels.remove(panelToClose);
1680 panelToClose.closePanel();
1681 panelToClose = null;
1683 tabbedPane.removeTabAt(closedindex);
1684 tabbedPane.validate();
1686 if (index > closedindex || index == tabbedPane.getTabCount())
1688 // modify currently selected tab index if necessary.
1692 this.tabSelectionChanged(index);
1698 void updateEditMenuBar()
1701 if (viewport.getHistoryList().size() > 0)
1703 undoMenuItem.setEnabled(true);
1704 CommandI command = viewport.getHistoryList().peek();
1705 undoMenuItem.setText(MessageManager
1706 .formatMessage("label.undo_command", new Object[]
1707 { command.getDescription() }));
1711 undoMenuItem.setEnabled(false);
1712 undoMenuItem.setText(MessageManager.getString("action.undo"));
1715 if (viewport.getRedoList().size() > 0)
1717 redoMenuItem.setEnabled(true);
1719 CommandI command = viewport.getRedoList().peek();
1720 redoMenuItem.setText(MessageManager
1721 .formatMessage("label.redo_command", new Object[]
1722 { command.getDescription() }));
1726 redoMenuItem.setEnabled(false);
1727 redoMenuItem.setText(MessageManager.getString("action.redo"));
1732 public void addHistoryItem(CommandI command)
1734 if (command.getSize() > 0)
1736 viewport.addToHistoryList(command);
1737 viewport.clearRedoList();
1738 updateEditMenuBar();
1739 viewport.updateHiddenColumns();
1740 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1741 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1742 // viewport.getColumnSelection()
1743 // .getHiddenColumns().size() > 0);
1749 * @return alignment objects for all views
1751 AlignmentI[] getViewAlignments()
1753 if (alignPanels != null)
1755 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1757 for (AlignmentPanel ap : alignPanels)
1759 als[i++] = ap.av.getAlignment();
1763 if (viewport != null)
1765 return new AlignmentI[] { viewport.getAlignment() };
1777 protected void undoMenuItem_actionPerformed(ActionEvent e)
1779 if (viewport.getHistoryList().isEmpty())
1783 CommandI command = viewport.getHistoryList().pop();
1784 viewport.addToRedoList(command);
1785 command.undoCommand(getViewAlignments());
1787 AlignmentViewport originalSource = getOriginatingSource(command);
1788 updateEditMenuBar();
1790 if (originalSource != null)
1792 if (originalSource != viewport)
1795 "Implementation worry: mismatch of viewport origin for undo");
1797 originalSource.updateHiddenColumns();
1798 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1800 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1801 // viewport.getColumnSelection()
1802 // .getHiddenColumns().size() > 0);
1803 originalSource.firePropertyChange("alignment", null,
1804 originalSource.getAlignment().getSequences());
1815 protected void redoMenuItem_actionPerformed(ActionEvent e)
1817 if (viewport.getRedoList().size() < 1)
1822 CommandI command = viewport.getRedoList().pop();
1823 viewport.addToHistoryList(command);
1824 command.doCommand(getViewAlignments());
1826 AlignmentViewport originalSource = getOriginatingSource(command);
1827 updateEditMenuBar();
1829 if (originalSource != null)
1832 if (originalSource != viewport)
1835 "Implementation worry: mismatch of viewport origin for redo");
1837 originalSource.updateHiddenColumns();
1838 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1840 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1841 // viewport.getColumnSelection()
1842 // .getHiddenColumns().size() > 0);
1843 originalSource.firePropertyChange("alignment", null,
1844 originalSource.getAlignment().getSequences());
1848 AlignmentViewport getOriginatingSource(CommandI command)
1850 AlignmentViewport originalSource = null;
1851 // For sequence removal and addition, we need to fire
1852 // the property change event FROM the viewport where the
1853 // original alignment was altered
1854 AlignmentI al = null;
1855 if (command instanceof EditCommand)
1857 EditCommand editCommand = (EditCommand) command;
1858 al = editCommand.getAlignment();
1859 List<Component> comps = PaintRefresher.components
1860 .get(viewport.getSequenceSetId());
1862 for (Component comp : comps)
1864 if (comp instanceof AlignmentPanel)
1866 if (al == ((AlignmentPanel) comp).av.getAlignment())
1868 originalSource = ((AlignmentPanel) comp).av;
1875 if (originalSource == null)
1877 // The original view is closed, we must validate
1878 // the current view against the closed view first
1881 PaintRefresher.validateSequences(al, viewport.getAlignment());
1884 originalSource = viewport;
1887 return originalSource;
1891 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1892 * or the sequence under cursor in keyboard mode
1897 public void moveSelectedSequences(boolean up)
1899 SequenceGroup sg = viewport.getSelectionGroup();
1903 if (viewport.cursorMode)
1905 sg = new SequenceGroup();
1906 sg.addSequence(viewport.getAlignment().getSequenceAt(
1907 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1915 if (sg.getSize() < 1)
1920 // TODO: JAL-3733 - add an event to the undo buffer for this !
1922 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1923 viewport.getHiddenRepSequences(), up);
1924 alignPanel.paintAlignment(true, false);
1927 synchronized void slideSequences(boolean right, int size)
1929 List<SequenceI> sg = new ArrayList<>();
1930 if (viewport.cursorMode)
1932 sg.add(viewport.getAlignment()
1933 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1935 else if (viewport.getSelectionGroup() != null
1936 && viewport.getSelectionGroup().getSize() != viewport
1937 .getAlignment().getHeight())
1939 sg = viewport.getSelectionGroup()
1940 .getSequences(viewport.getHiddenRepSequences());
1948 List<SequenceI> invertGroup = new ArrayList<>();
1950 for (SequenceI seq : viewport.getAlignment().getSequences())
1952 if (!sg.contains(seq))
1954 invertGroup.add(seq);
1958 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1960 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1961 for (int i = 0; i < invertGroup.size(); i++)
1963 seqs2[i] = invertGroup.get(i);
1966 SlideSequencesCommand ssc;
1969 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1970 viewport.getGapCharacter());
1974 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1975 viewport.getGapCharacter());
1978 int groupAdjustment = 0;
1979 if (ssc.getGapsInsertedBegin() && right)
1981 if (viewport.cursorMode)
1983 alignPanel.getSeqPanel().moveCursor(size, 0);
1987 groupAdjustment = size;
1990 else if (!ssc.getGapsInsertedBegin() && !right)
1992 if (viewport.cursorMode)
1994 alignPanel.getSeqPanel().moveCursor(-size, 0);
1998 groupAdjustment = -size;
2002 if (groupAdjustment != 0)
2004 viewport.getSelectionGroup().setStartRes(
2005 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2006 viewport.getSelectionGroup().setEndRes(
2007 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2011 * just extend the last slide command if compatible; but not if in
2012 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2014 boolean appendHistoryItem = false;
2015 Deque<CommandI> historyList = viewport.getHistoryList();
2016 boolean inSplitFrame = getSplitViewContainer() != null;
2017 if (!inSplitFrame && historyList != null && historyList.size() > 0
2018 && historyList.peek() instanceof SlideSequencesCommand)
2020 appendHistoryItem = ssc.appendSlideCommand(
2021 (SlideSequencesCommand) historyList.peek());
2024 if (!appendHistoryItem)
2026 addHistoryItem(ssc);
2039 protected void copy_actionPerformed()
2041 if (viewport.getSelectionGroup() == null)
2045 // TODO: preserve the ordering of displayed alignment annotation in any
2046 // internal paste (particularly sequence associated annotation)
2047 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2048 String[] omitHidden = null;
2050 if (viewport.hasHiddenColumns())
2052 omitHidden = viewport.getViewAsString(true);
2055 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2056 seqs, omitHidden, null);
2058 StringSelection ss = new StringSelection(output);
2062 jalview.gui.Desktop.internalCopy = true;
2063 // Its really worth setting the clipboard contents
2064 // to empty before setting the large StringSelection!!
2065 Toolkit.getDefaultToolkit().getSystemClipboard()
2066 .setContents(new StringSelection(""), null);
2068 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2070 } catch (OutOfMemoryError er)
2072 new OOMWarning("copying region", er);
2076 HiddenColumns hiddenColumns = null;
2077 if (viewport.hasHiddenColumns())
2079 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2080 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2082 // create new HiddenColumns object with copy of hidden regions
2083 // between startRes and endRes, offset by startRes
2084 hiddenColumns = new HiddenColumns(
2085 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2086 hiddenCutoff, hiddenOffset);
2089 Desktop.jalviewClipboard = new Object[] { seqs,
2090 viewport.getAlignment().getDataset(), hiddenColumns };
2091 setStatus(MessageManager.formatMessage(
2092 "label.copied_sequences_to_clipboard", new Object[]
2093 { Integer.valueOf(seqs.length).toString() }));
2103 protected void pasteNew_actionPerformed(ActionEvent e)
2115 protected void pasteThis_actionPerformed(ActionEvent e)
2121 * Paste contents of Jalview clipboard
2123 * @param newAlignment
2124 * true to paste to a new alignment, otherwise add to this.
2126 void paste(boolean newAlignment)
2128 boolean externalPaste = true;
2131 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2132 Transferable contents = c.getContents(this);
2134 if (contents == null)
2143 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2144 if (str.length() < 1)
2149 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2151 } catch (OutOfMemoryError er)
2153 new OOMWarning("Out of memory pasting sequences!!", er);
2157 SequenceI[] sequences;
2158 boolean annotationAdded = false;
2159 AlignmentI alignment = null;
2161 if (Desktop.jalviewClipboard != null)
2163 // The clipboard was filled from within Jalview, we must use the
2165 // And dataset from the copied alignment
2166 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2167 // be doubly sure that we create *new* sequence objects.
2168 sequences = new SequenceI[newseq.length];
2169 for (int i = 0; i < newseq.length; i++)
2171 sequences[i] = new Sequence(newseq[i]);
2173 alignment = new Alignment(sequences);
2174 externalPaste = false;
2178 // parse the clipboard as an alignment.
2179 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2181 sequences = alignment.getSequencesArray();
2185 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2191 if (Desktop.jalviewClipboard != null)
2193 // dataset is inherited
2194 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2198 // new dataset is constructed
2199 alignment.setDataset(null);
2201 alwidth = alignment.getWidth() + 1;
2205 AlignmentI pastedal = alignment; // preserve pasted alignment object
2206 // Add pasted sequences and dataset into existing alignment.
2207 alignment = viewport.getAlignment();
2208 alwidth = alignment.getWidth() + 1;
2209 // decide if we need to import sequences from an existing dataset
2210 boolean importDs = Desktop.jalviewClipboard != null
2211 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2212 // importDs==true instructs us to copy over new dataset sequences from
2213 // an existing alignment
2214 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2216 // minimum dataset set
2218 for (int i = 0; i < sequences.length; i++)
2222 newDs.addElement(null);
2224 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2226 if (importDs && ds != null)
2228 if (!newDs.contains(ds))
2230 newDs.setElementAt(ds, i);
2231 ds = new Sequence(ds);
2232 // update with new dataset sequence
2233 sequences[i].setDatasetSequence(ds);
2237 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2242 // copy and derive new dataset sequence
2243 sequences[i] = sequences[i].deriveSequence();
2244 alignment.getDataset()
2245 .addSequence(sequences[i].getDatasetSequence());
2246 // TODO: avoid creation of duplicate dataset sequences with a
2247 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2249 alignment.addSequence(sequences[i]); // merges dataset
2253 newDs.clear(); // tidy up
2255 if (alignment.getAlignmentAnnotation() != null)
2257 for (AlignmentAnnotation alan : alignment
2258 .getAlignmentAnnotation())
2260 if (alan.graphGroup > fgroup)
2262 fgroup = alan.graphGroup;
2266 if (pastedal.getAlignmentAnnotation() != null)
2268 // Add any annotation attached to alignment.
2269 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2270 for (int i = 0; i < alann.length; i++)
2272 annotationAdded = true;
2273 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2275 AlignmentAnnotation newann = new AlignmentAnnotation(
2277 if (newann.graphGroup > -1)
2279 if (newGraphGroups.size() <= newann.graphGroup
2280 || newGraphGroups.get(newann.graphGroup) == null)
2282 for (int q = newGraphGroups
2283 .size(); q <= newann.graphGroup; q++)
2285 newGraphGroups.add(q, null);
2287 newGraphGroups.set(newann.graphGroup,
2288 Integer.valueOf(++fgroup));
2290 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2294 newann.padAnnotation(alwidth);
2295 alignment.addAnnotation(newann);
2305 addHistoryItem(new EditCommand(
2306 MessageManager.getString("label.add_sequences"),
2307 Action.PASTE, sequences, 0, alignment.getWidth(),
2310 // Add any annotations attached to sequences
2311 for (int i = 0; i < sequences.length; i++)
2313 if (sequences[i].getAnnotation() != null)
2315 AlignmentAnnotation newann;
2316 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2318 annotationAdded = true;
2319 newann = sequences[i].getAnnotation()[a];
2320 newann.adjustForAlignment();
2321 newann.padAnnotation(alwidth);
2322 if (newann.graphGroup > -1)
2324 if (newann.graphGroup > -1)
2326 if (newGraphGroups.size() <= newann.graphGroup
2327 || newGraphGroups.get(newann.graphGroup) == null)
2329 for (int q = newGraphGroups
2330 .size(); q <= newann.graphGroup; q++)
2332 newGraphGroups.add(q, null);
2334 newGraphGroups.set(newann.graphGroup,
2335 Integer.valueOf(++fgroup));
2337 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2341 // annotation was duplicated earlier
2342 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2343 // take care of contact matrix too
2344 ContactMatrixI cm=sequences[i].getContactMatrixFor(sequences[i].getAnnotation()[a]);
2347 alignment.addContactListFor(sequences[i].getAnnotation()[a], cm);
2350 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2358 // propagate alignment changed.
2359 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2360 if (annotationAdded)
2362 // Duplicate sequence annotation in all views.
2363 AlignmentI[] alview = this.getViewAlignments();
2364 for (int i = 0; i < sequences.length; i++)
2366 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2371 for (int avnum = 0; avnum < alview.length; avnum++)
2373 if (alview[avnum] != alignment)
2375 // duplicate in a view other than the one with input focus
2376 int avwidth = alview[avnum].getWidth() + 1;
2377 // this relies on sann being preserved after we
2378 // modify the sequence's annotation array for each duplication
2379 for (int a = 0; a < sann.length; a++)
2381 AlignmentAnnotation newann = new AlignmentAnnotation(
2383 sequences[i].addAlignmentAnnotation(newann);
2384 newann.padAnnotation(avwidth);
2385 alview[avnum].addAnnotation(newann); // annotation was
2386 // duplicated earlier
2387 // TODO JAL-1145 graphGroups are not updated for sequence
2388 // annotation added to several views. This may cause
2390 alview[avnum].setAnnotationIndex(newann, a);
2395 buildSortByAnnotationScoresMenu();
2397 viewport.firePropertyChange("alignment", null,
2398 alignment.getSequences());
2399 if (alignPanels != null)
2401 for (AlignmentPanel ap : alignPanels)
2403 ap.validateAnnotationDimensions(false);
2408 alignPanel.validateAnnotationDimensions(false);
2414 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2416 String newtitle = new String("Copied sequences");
2418 if (Desktop.jalviewClipboard != null
2419 && Desktop.jalviewClipboard[2] != null)
2421 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2422 af.viewport.setHiddenColumns(hc);
2425 // >>>This is a fix for the moment, until a better solution is
2427 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2428 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2429 .getFeatureRenderer());
2431 // TODO: maintain provenance of an alignment, rather than just make the
2432 // title a concatenation of operations.
2435 if (title.startsWith("Copied sequences"))
2441 newtitle = newtitle.concat("- from " + title);
2446 newtitle = new String("Pasted sequences");
2449 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2454 } catch (Exception ex)
2456 ex.printStackTrace();
2457 System.out.println("Exception whilst pasting: " + ex);
2458 // could be anything being pasted in here
2464 protected void expand_newalign(ActionEvent e)
2468 AlignmentI alignment = AlignmentUtils
2469 .expandContext(getViewport().getAlignment(), -1);
2470 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2472 String newtitle = new String("Flanking alignment");
2474 if (Desktop.jalviewClipboard != null
2475 && Desktop.jalviewClipboard[2] != null)
2477 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2478 af.viewport.setHiddenColumns(hc);
2481 // >>>This is a fix for the moment, until a better solution is
2483 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2484 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2485 .getFeatureRenderer());
2487 // TODO: maintain provenance of an alignment, rather than just make the
2488 // title a concatenation of operations.
2490 if (title.startsWith("Copied sequences"))
2496 newtitle = newtitle.concat("- from " + title);
2500 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2502 } catch (Exception ex)
2504 ex.printStackTrace();
2505 System.out.println("Exception whilst pasting: " + ex);
2506 // could be anything being pasted in here
2507 } catch (OutOfMemoryError oom)
2509 new OOMWarning("Viewing flanking region of alignment", oom);
2514 * Action Cut (delete and copy) the selected region
2517 protected void cut_actionPerformed()
2519 copy_actionPerformed();
2520 delete_actionPerformed();
2524 * Performs menu option to Delete the currently selected region
2527 protected void delete_actionPerformed()
2530 SequenceGroup sg = viewport.getSelectionGroup();
2536 Runnable okAction = () -> {
2537 SequenceI[] cut = sg.getSequences()
2538 .toArray(new SequenceI[sg.getSize()]);
2540 addHistoryItem(new EditCommand(
2541 MessageManager.getString("label.cut_sequences"), Action.CUT,
2542 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2543 viewport.getAlignment()));
2545 viewport.setSelectionGroup(null);
2546 viewport.sendSelection();
2547 viewport.getAlignment().deleteGroup(sg);
2549 viewport.firePropertyChange("alignment", null,
2550 viewport.getAlignment().getSequences());
2551 if (viewport.getAlignment().getHeight() < 1)
2555 AlignFrame.this.setClosed(true);
2556 } catch (Exception ex)
2563 * If the cut affects all sequences, prompt for confirmation
2565 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2567 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2568 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2569 if (wholeHeight && wholeWidth)
2571 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2572 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2573 Object[] options = new Object[] {
2574 MessageManager.getString("action.ok"),
2575 MessageManager.getString("action.cancel") };
2576 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2577 MessageManager.getString("label.delete_all"),
2578 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2579 options, options[0]);
2586 } catch (Exception e)
2588 e.printStackTrace();
2600 protected void deleteGroups_actionPerformed(ActionEvent e)
2602 if (avc.deleteGroups())
2604 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2605 alignPanel.updateAnnotation();
2606 alignPanel.paintAlignment(true, true);
2617 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2619 SequenceGroup sg = new SequenceGroup(
2620 viewport.getAlignment().getSequences());
2622 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2623 viewport.setSelectionGroup(sg);
2624 viewport.isSelectionGroupChanged(true);
2625 viewport.sendSelection();
2626 // JAL-2034 - should delegate to
2627 // alignPanel to decide if overview needs
2629 alignPanel.paintAlignment(false, false);
2630 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2640 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2642 if (viewport.cursorMode)
2644 alignPanel.getSeqPanel().keyboardNo1 = null;
2645 alignPanel.getSeqPanel().keyboardNo2 = null;
2647 viewport.setSelectionGroup(null);
2648 viewport.getColumnSelection().clear();
2649 viewport.setSearchResults(null);
2650 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2651 // JAL-2034 - should delegate to
2652 // alignPanel to decide if overview needs
2654 alignPanel.paintAlignment(false, false);
2655 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2656 viewport.sendSelection();
2666 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2668 SequenceGroup sg = viewport.getSelectionGroup();
2672 selectAllSequenceMenuItem_actionPerformed(null);
2677 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2679 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2681 // JAL-2034 - should delegate to
2682 // alignPanel to decide if overview needs
2685 alignPanel.paintAlignment(true, false);
2686 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2687 viewport.sendSelection();
2691 public void invertColSel_actionPerformed(ActionEvent e)
2693 viewport.invertColumnSelection();
2694 alignPanel.paintAlignment(true, false);
2695 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2696 viewport.sendSelection();
2706 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2708 trimAlignment(true);
2718 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2720 trimAlignment(false);
2723 void trimAlignment(boolean trimLeft)
2725 ColumnSelection colSel = viewport.getColumnSelection();
2728 if (!colSel.isEmpty())
2732 column = colSel.getMin();
2736 column = colSel.getMax();
2740 if (viewport.getSelectionGroup() != null)
2742 seqs = viewport.getSelectionGroup()
2743 .getSequencesAsArray(viewport.getHiddenRepSequences());
2747 seqs = viewport.getAlignment().getSequencesArray();
2750 TrimRegionCommand trimRegion;
2753 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2754 column, viewport.getAlignment());
2755 viewport.getRanges().setStartRes(0);
2759 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2760 column, viewport.getAlignment());
2763 setStatus(MessageManager.formatMessage("label.removed_columns",
2765 { Integer.valueOf(trimRegion.getSize()).toString() }));
2767 addHistoryItem(trimRegion);
2769 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2771 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2772 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2774 viewport.getAlignment().deleteGroup(sg);
2778 viewport.firePropertyChange("alignment", null,
2779 viewport.getAlignment().getSequences());
2790 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2792 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2795 if (viewport.getSelectionGroup() != null)
2797 seqs = viewport.getSelectionGroup()
2798 .getSequencesAsArray(viewport.getHiddenRepSequences());
2799 start = viewport.getSelectionGroup().getStartRes();
2800 end = viewport.getSelectionGroup().getEndRes();
2804 seqs = viewport.getAlignment().getSequencesArray();
2807 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2808 "Remove Gapped Columns", seqs, start, end,
2809 viewport.getAlignment());
2811 addHistoryItem(removeGapCols);
2813 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2815 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2817 // This is to maintain viewport position on first residue
2818 // of first sequence
2819 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2820 ViewportRanges ranges = viewport.getRanges();
2821 int startRes = seq.findPosition(ranges.getStartRes());
2822 // ShiftList shifts;
2823 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2824 // edit.alColumnChanges=shifts.getInverse();
2825 // if (viewport.hasHiddenColumns)
2826 // viewport.getColumnSelection().compensateForEdits(shifts);
2827 ranges.setStartRes(seq.findIndex(startRes) - 1);
2828 viewport.firePropertyChange("alignment", null,
2829 viewport.getAlignment().getSequences());
2840 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2842 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2845 if (viewport.getSelectionGroup() != null)
2847 seqs = viewport.getSelectionGroup()
2848 .getSequencesAsArray(viewport.getHiddenRepSequences());
2849 start = viewport.getSelectionGroup().getStartRes();
2850 end = viewport.getSelectionGroup().getEndRes();
2854 seqs = viewport.getAlignment().getSequencesArray();
2857 // This is to maintain viewport position on first residue
2858 // of first sequence
2859 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2860 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2862 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2863 viewport.getAlignment()));
2865 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2867 viewport.firePropertyChange("alignment", null,
2868 viewport.getAlignment().getSequences());
2879 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2881 viewport.setPadGaps(padGapsMenuitem.isSelected());
2882 viewport.firePropertyChange("alignment", null,
2883 viewport.getAlignment().getSequences());
2887 * Opens a Finder dialog
2892 public void findMenuItem_actionPerformed(ActionEvent e)
2894 new Finder(alignPanel, false, null);
2898 * Create a new view of the current alignment.
2901 public void newView_actionPerformed(ActionEvent e)
2903 newView(null, true);
2907 * Creates and shows a new view of the current alignment.
2910 * title of newly created view; if null, one will be generated
2911 * @param copyAnnotation
2912 * if true then duplicate all annnotation, groups and settings
2913 * @return new alignment panel, already displayed.
2915 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2918 * Create a new AlignmentPanel (with its own, new Viewport)
2920 AlignmentPanel newap = new jalview.project.Jalview2XML()
2921 .copyAlignPanel(alignPanel);
2922 if (!copyAnnotation)
2925 * remove all groups and annotation except for the automatic stuff
2927 newap.av.getAlignment().deleteAllGroups();
2928 newap.av.getAlignment().deleteAllAnnotations(false);
2931 newap.av.setGatherViewsHere(false);
2933 if (viewport.getViewName() == null)
2935 viewport.setViewName(
2936 MessageManager.getString("label.view_name_original"));
2940 * Views share the same edits undo and redo stacks
2942 newap.av.setHistoryList(viewport.getHistoryList());
2943 newap.av.setRedoList(viewport.getRedoList());
2946 * copy any visualisation settings that are not saved in the project
2948 newap.av.setColourAppliesToAllGroups(
2949 viewport.getColourAppliesToAllGroups());
2952 * Views share the same mappings; need to deregister any new mappings
2953 * created by copyAlignPanel, and register the new reference to the shared
2956 newap.av.replaceMappings(viewport.getAlignment());
2959 * start up cDNA consensus (if applicable) now mappings are in place
2961 if (newap.av.initComplementConsensus())
2963 newap.refresh(true); // adjust layout of annotations
2966 newap.av.setViewName(getNewViewName(viewTitle));
2968 addAlignmentPanel(newap, true);
2969 newap.alignmentChanged();
2971 if (alignPanels.size() == 2)
2973 viewport.setGatherViewsHere(true);
2975 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2981 * Make a new name for the view, ensuring it is unique within the current
2982 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2983 * these now use viewId. Unique view names are still desirable for usability.)
2988 protected String getNewViewName(String viewTitle)
2990 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2991 boolean addFirstIndex = false;
2992 if (viewTitle == null || viewTitle.trim().length() == 0)
2994 viewTitle = MessageManager.getString("action.view");
2995 addFirstIndex = true;
2999 index = 1;// we count from 1 if given a specific name
3001 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3003 List<Component> comps = PaintRefresher.components
3004 .get(viewport.getSequenceSetId());
3006 List<String> existingNames = getExistingViewNames(comps);
3008 while (existingNames.contains(newViewName))
3010 newViewName = viewTitle + " " + (++index);
3016 * Returns a list of distinct view names found in the given list of
3017 * components. View names are held on the viewport of an AlignmentPanel.
3022 protected List<String> getExistingViewNames(List<Component> comps)
3024 List<String> existingNames = new ArrayList<>();
3025 for (Component comp : comps)
3027 if (comp instanceof AlignmentPanel)
3029 AlignmentPanel ap = (AlignmentPanel) comp;
3030 if (!existingNames.contains(ap.av.getViewName()))
3032 existingNames.add(ap.av.getViewName());
3036 return existingNames;
3040 * Explode tabbed views into separate windows.
3043 public void expandViews_actionPerformed(ActionEvent e)
3045 Desktop.explodeViews(this);
3049 * Gather views in separate windows back into a tabbed presentation.
3052 public void gatherViews_actionPerformed(ActionEvent e)
3054 Desktop.instance.gatherViews(this);
3064 public void font_actionPerformed(ActionEvent e)
3066 new FontChooser(alignPanel);
3076 protected void seqLimit_actionPerformed(ActionEvent e)
3078 viewport.setShowJVSuffix(seqLimits.isSelected());
3080 alignPanel.getIdPanel().getIdCanvas()
3081 .setPreferredSize(alignPanel.calculateIdWidth());
3082 alignPanel.paintAlignment(true, false);
3086 public void idRightAlign_actionPerformed(ActionEvent e)
3088 viewport.setRightAlignIds(idRightAlign.isSelected());
3089 alignPanel.paintAlignment(false, false);
3093 public void centreColumnLabels_actionPerformed(ActionEvent e)
3095 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3096 alignPanel.paintAlignment(false, false);
3102 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3105 protected void followHighlight_actionPerformed()
3108 * Set the 'follow' flag on the Viewport (and scroll to position if now
3111 final boolean state = this.followHighlightMenuItem.getState();
3112 viewport.setFollowHighlight(state);
3115 alignPanel.scrollToPosition(viewport.getSearchResults());
3126 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3128 viewport.setColourText(colourTextMenuItem.isSelected());
3129 alignPanel.paintAlignment(false, false);
3139 public void wrapMenuItem_actionPerformed(ActionEvent e)
3141 scaleAbove.setVisible(wrapMenuItem.isSelected());
3142 scaleLeft.setVisible(wrapMenuItem.isSelected());
3143 scaleRight.setVisible(wrapMenuItem.isSelected());
3144 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3145 alignPanel.updateLayout();
3149 public void showAllSeqs_actionPerformed(ActionEvent e)
3151 viewport.showAllHiddenSeqs();
3155 public void showAllColumns_actionPerformed(ActionEvent e)
3157 viewport.showAllHiddenColumns();
3158 alignPanel.paintAlignment(true, true);
3159 viewport.sendSelection();
3163 public void hideSelSequences_actionPerformed(ActionEvent e)
3165 viewport.hideAllSelectedSeqs();
3169 * called by key handler and the hide all/show all menu items
3174 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3177 boolean hide = false;
3178 SequenceGroup sg = viewport.getSelectionGroup();
3179 if (!toggleSeqs && !toggleCols)
3181 // Hide everything by the current selection - this is a hack - we do the
3182 // invert and then hide
3183 // first check that there will be visible columns after the invert.
3184 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3185 && sg.getStartRes() <= sg.getEndRes()))
3187 // now invert the sequence set, if required - empty selection implies
3188 // that no hiding is required.
3191 invertSequenceMenuItem_actionPerformed(null);
3192 sg = viewport.getSelectionGroup();
3196 viewport.expandColSelection(sg, true);
3197 // finally invert the column selection and get the new sequence
3199 invertColSel_actionPerformed(null);
3206 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3208 hideSelSequences_actionPerformed(null);
3211 else if (!(toggleCols && viewport.hasSelectedColumns()))
3213 showAllSeqs_actionPerformed(null);
3219 if (viewport.hasSelectedColumns())
3221 hideSelColumns_actionPerformed(null);
3224 viewport.setSelectionGroup(sg);
3229 showAllColumns_actionPerformed(null);
3238 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3239 * event.ActionEvent)
3242 public void hideAllButSelection_actionPerformed(ActionEvent e)
3244 toggleHiddenRegions(false, false);
3245 viewport.sendSelection();
3252 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3256 public void hideAllSelection_actionPerformed(ActionEvent e)
3258 SequenceGroup sg = viewport.getSelectionGroup();
3259 viewport.expandColSelection(sg, false);
3260 viewport.hideAllSelectedSeqs();
3261 viewport.hideSelectedColumns();
3262 alignPanel.updateLayout();
3263 alignPanel.paintAlignment(true, true);
3264 viewport.sendSelection();
3271 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3275 public void showAllhidden_actionPerformed(ActionEvent e)
3277 viewport.showAllHiddenColumns();
3278 viewport.showAllHiddenSeqs();
3279 alignPanel.paintAlignment(true, true);
3280 viewport.sendSelection();
3284 public void hideSelColumns_actionPerformed(ActionEvent e)
3286 viewport.hideSelectedColumns();
3287 alignPanel.updateLayout();
3288 alignPanel.paintAlignment(true, true);
3289 viewport.sendSelection();
3293 public void hiddenMarkers_actionPerformed(ActionEvent e)
3295 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3306 protected void scaleAbove_actionPerformed(ActionEvent e)
3308 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3309 alignPanel.updateLayout();
3310 alignPanel.paintAlignment(true, false);
3320 protected void scaleLeft_actionPerformed(ActionEvent e)
3322 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3323 alignPanel.updateLayout();
3324 alignPanel.paintAlignment(true, false);
3334 protected void scaleRight_actionPerformed(ActionEvent e)
3336 viewport.setScaleRightWrapped(scaleRight.isSelected());
3337 alignPanel.updateLayout();
3338 alignPanel.paintAlignment(true, false);
3348 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3350 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3351 alignPanel.paintAlignment(false, false);
3361 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3363 viewport.setShowText(viewTextMenuItem.isSelected());
3364 alignPanel.paintAlignment(false, false);
3374 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3376 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3377 alignPanel.paintAlignment(false, false);
3380 public FeatureSettings featureSettings;
3383 public FeatureSettingsControllerI getFeatureSettingsUI()
3385 return featureSettings;
3389 public void featureSettings_actionPerformed(ActionEvent e)
3391 showFeatureSettingsUI();
3395 public FeatureSettingsControllerI showFeatureSettingsUI()
3397 if (featureSettings != null)
3399 featureSettings.closeOldSettings();
3400 featureSettings = null;
3402 if (!showSeqFeatures.isSelected())
3404 // make sure features are actually displayed
3405 showSeqFeatures.setSelected(true);
3406 showSeqFeatures_actionPerformed(null);
3408 featureSettings = new FeatureSettings(this);
3409 return featureSettings;
3413 * Set or clear 'Show Sequence Features'
3419 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3421 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3422 alignPanel.paintAlignment(true, true);
3426 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3427 * the annotations panel as a whole.
3429 * The options to show/hide all annotations should be enabled when the panel
3430 * is shown, and disabled when the panel is hidden.
3435 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3437 final boolean setVisible = annotationPanelMenuItem.isSelected();
3438 viewport.setShowAnnotation(setVisible);
3439 this.showAllSeqAnnotations.setEnabled(setVisible);
3440 this.hideAllSeqAnnotations.setEnabled(setVisible);
3441 this.showAllAlAnnotations.setEnabled(setVisible);
3442 this.hideAllAlAnnotations.setEnabled(setVisible);
3443 alignPanel.updateLayout();
3447 public void alignmentProperties()
3450 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3453 String content = MessageManager.formatMessage("label.html_content",
3455 { contents.toString() });
3458 if (Platform.isJS())
3460 JLabel textLabel = new JLabel();
3461 textLabel.setText(content);
3462 textLabel.setBackground(Color.WHITE);
3464 pane = new JPanel(new BorderLayout());
3465 ((JPanel) pane).setOpaque(true);
3466 pane.setBackground(Color.WHITE);
3467 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3476 JEditorPane editPane = new JEditorPane("text/html", "");
3477 editPane.setEditable(false);
3478 editPane.setText(content);
3482 JInternalFrame frame = new JInternalFrame();
3484 frame.getContentPane().add(new JScrollPane(pane));
3486 Desktop.addInternalFrame(frame, MessageManager
3487 .formatMessage("label.alignment_properties", new Object[]
3488 { getTitle() }), 500, 400);
3492 * Opens an Overview panel for the alignment, unless one is open already
3497 public void overviewMenuItem_actionPerformed(ActionEvent e)
3499 boolean showHiddenRegions = Cache
3500 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3501 openOverviewPanel(showHiddenRegions);
3504 public OverviewPanel openOverviewPanel(boolean showHidden)
3506 if (alignPanel.overviewPanel != null)
3508 return alignPanel.overviewPanel;
3510 JInternalFrame frame = new JInternalFrame();
3511 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3513 frame.setContentPane(overview);
3514 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3515 frame.getHeight(), true, true);
3516 frame.setFrameIcon(null);
3518 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3519 final AlignmentPanel thePanel = this.alignPanel;
3520 frame.addInternalFrameListener(
3521 new javax.swing.event.InternalFrameAdapter()
3524 public void internalFrameClosed(
3525 javax.swing.event.InternalFrameEvent evt)
3528 thePanel.setOverviewPanel(null);
3531 if (getKeyListeners().length > 0)
3533 frame.addKeyListener(getKeyListeners()[0]);
3536 alignPanel.setOverviewPanel(overview);
3537 alignPanel.setOverviewTitle(this);
3543 public void textColour_actionPerformed()
3545 new TextColourChooser().chooseColour(alignPanel, null);
3549 * public void covariationColour_actionPerformed() {
3551 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3555 public void annotationColour_actionPerformed()
3557 new AnnotationColourChooser(viewport, alignPanel);
3561 public void annotationColumn_actionPerformed(ActionEvent e)
3563 new AnnotationColumnChooser(viewport, alignPanel);
3567 * Action on the user checking or unchecking the option to apply the selected
3568 * colour scheme to all groups. If unchecked, groups may have their own
3569 * independent colour schemes.
3574 public void applyToAllGroups_actionPerformed(boolean selected)
3576 viewport.setColourAppliesToAllGroups(selected);
3580 * Action on user selecting a colour from the colour menu
3583 * the name (not the menu item label!) of the colour scheme
3586 public void changeColour_actionPerformed(String name)
3589 * 'User Defined' opens a panel to configure or load a
3590 * user-defined colour scheme
3592 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3594 new UserDefinedColours(alignPanel);
3599 * otherwise set the chosen colour scheme (or null for 'None')
3601 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3602 viewport, viewport.getAlignment(),
3603 viewport.getHiddenRepSequences());
3608 * Actions on setting or changing the alignment colour scheme
3613 public void changeColour(ColourSchemeI cs)
3615 // TODO: pull up to controller method
3616 ColourMenuHelper.setColourSelected(colourMenu, cs);
3618 viewport.setGlobalColourScheme(cs);
3620 alignPanel.paintAlignment(true, true);
3624 * Show the PID threshold slider panel
3627 protected void modifyPID_actionPerformed()
3629 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3630 alignPanel.getViewName());
3631 SliderPanel.showPIDSlider();
3635 * Show the Conservation slider panel
3638 protected void modifyConservation_actionPerformed()
3640 SliderPanel.setConservationSlider(alignPanel,
3641 viewport.getResidueShading(), alignPanel.getViewName());
3642 SliderPanel.showConservationSlider();
3646 * Action on selecting or deselecting (Colour) By Conservation
3649 public void conservationMenuItem_actionPerformed(boolean selected)
3651 modifyConservation.setEnabled(selected);
3652 viewport.setConservationSelected(selected);
3653 viewport.getResidueShading().setConservationApplied(selected);
3655 changeColour(viewport.getGlobalColourScheme());
3658 modifyConservation_actionPerformed();
3662 SliderPanel.hideConservationSlider();
3667 * Action on selecting or deselecting (Colour) Above PID Threshold
3670 public void abovePIDThreshold_actionPerformed(boolean selected)
3672 modifyPID.setEnabled(selected);
3673 viewport.setAbovePIDThreshold(selected);
3676 viewport.getResidueShading().setThreshold(0,
3677 viewport.isIgnoreGapsConsensus());
3680 changeColour(viewport.getGlobalColourScheme());
3683 modifyPID_actionPerformed();
3687 SliderPanel.hidePIDSlider();
3698 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3700 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3701 AlignmentSorter.sortByPID(viewport.getAlignment(),
3702 viewport.getAlignment().getSequenceAt(0));
3703 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3704 viewport.getAlignment()));
3705 alignPanel.paintAlignment(true, false);
3715 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3717 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3718 AlignmentSorter.sortByID(viewport.getAlignment());
3720 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3721 alignPanel.paintAlignment(true, false);
3731 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3733 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3734 AlignmentSorter.sortByLength(viewport.getAlignment());
3735 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3736 viewport.getAlignment()));
3737 alignPanel.paintAlignment(true, false);
3747 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3749 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3750 AlignmentSorter.sortByGroup(viewport.getAlignment());
3751 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3752 viewport.getAlignment()));
3754 alignPanel.paintAlignment(true, false);
3764 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3766 new RedundancyPanel(alignPanel, this);
3776 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3778 if ((viewport.getSelectionGroup() == null)
3779 || (viewport.getSelectionGroup().getSize() < 2))
3781 JvOptionPane.showInternalMessageDialog(this,
3782 MessageManager.getString(
3783 "label.you_must_select_least_two_sequences"),
3784 MessageManager.getString("label.invalid_selection"),
3785 JvOptionPane.WARNING_MESSAGE);
3789 JInternalFrame frame = new JInternalFrame();
3790 frame.setContentPane(new PairwiseAlignPanel(viewport));
3791 Desktop.addInternalFrame(frame,
3792 MessageManager.getString("action.pairwise_alignment"), 600,
3798 public void autoCalculate_actionPerformed(ActionEvent e)
3800 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3801 if (viewport.autoCalculateConsensus)
3803 viewport.firePropertyChange("alignment", null,
3804 viewport.getAlignment().getSequences());
3809 public void sortByTreeOption_actionPerformed(ActionEvent e)
3811 viewport.sortByTree = sortByTree.isSelected();
3815 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3817 viewport.followSelection = listenToViewSelections.isSelected();
3821 * Constructs a tree panel and adds it to the desktop
3824 * tree type (NJ or AV)
3826 * name of score model used to compute the tree
3828 * parameters for the distance or similarity calculation
3830 void newTreePanel(String type, String modelName,
3831 SimilarityParamsI options)
3833 String frameTitle = "";
3836 boolean onSelection = false;
3837 if (viewport.getSelectionGroup() != null
3838 && viewport.getSelectionGroup().getSize() > 0)
3840 SequenceGroup sg = viewport.getSelectionGroup();
3842 /* Decide if the selection is a column region */
3843 for (SequenceI _s : sg.getSequences())
3845 if (_s.getLength() < sg.getEndRes())
3847 JvOptionPane.showMessageDialog(Desktop.desktop,
3848 MessageManager.getString(
3849 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3850 MessageManager.getString(
3851 "label.sequences_selection_not_aligned"),
3852 JvOptionPane.WARNING_MESSAGE);
3861 if (viewport.getAlignment().getHeight() < 2)
3867 tp = new TreePanel(alignPanel, type, modelName, options);
3868 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3870 frameTitle += " from ";
3872 if (viewport.getViewName() != null)
3874 frameTitle += viewport.getViewName() + " of ";
3877 frameTitle += this.title;
3879 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3890 public void addSortByOrderMenuItem(String title,
3891 final AlignmentOrder order)
3893 final JMenuItem item = new JMenuItem(MessageManager
3894 .formatMessage("action.by_title_param", new Object[]
3897 item.addActionListener(new java.awt.event.ActionListener()
3900 public void actionPerformed(ActionEvent e)
3902 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3904 // TODO: JBPNote - have to map order entries to curent SequenceI
3906 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3908 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3909 viewport.getAlignment()));
3911 alignPanel.paintAlignment(true, false);
3917 * Add a new sort by annotation score menu item
3920 * the menu to add the option to
3922 * the label used to retrieve scores for each sequence on the
3925 public void addSortByAnnotScoreMenuItem(JMenu sort,
3926 final String scoreLabel)
3928 final JMenuItem item = new JMenuItem(scoreLabel);
3930 item.addActionListener(new java.awt.event.ActionListener()
3933 public void actionPerformed(ActionEvent e)
3935 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3936 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3937 viewport.getAlignment());// ,viewport.getSelectionGroup());
3938 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3939 viewport.getAlignment()));
3940 alignPanel.paintAlignment(true, false);
3946 * last hash for alignment's annotation array - used to minimise cost of
3949 protected int _annotationScoreVectorHash;
3952 * search the alignment and rebuild the sort by annotation score submenu the
3953 * last alignment annotation vector hash is stored to minimize cost of
3954 * rebuilding in subsequence calls.
3958 public void buildSortByAnnotationScoresMenu()
3960 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3965 if (viewport.getAlignment().getAlignmentAnnotation()
3966 .hashCode() != _annotationScoreVectorHash)
3968 sortByAnnotScore.removeAll();
3969 // almost certainly a quicker way to do this - but we keep it simple
3970 Hashtable<String, String> scoreSorts = new Hashtable<>();
3971 AlignmentAnnotation aann[];
3972 for (SequenceI sqa : viewport.getAlignment().getSequences())
3974 aann = sqa.getAnnotation();
3975 for (int i = 0; aann != null && i < aann.length; i++)
3977 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3979 scoreSorts.put(aann[i].label, aann[i].label);
3983 Enumeration<String> labels = scoreSorts.keys();
3984 while (labels.hasMoreElements())
3986 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3988 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3991 _annotationScoreVectorHash = viewport.getAlignment()
3992 .getAlignmentAnnotation().hashCode();
3997 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3998 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3999 * call. Listeners are added to remove the menu item when the treePanel is
4000 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4004 public void buildTreeSortMenu()
4006 sortByTreeMenu.removeAll();
4008 List<Component> comps = PaintRefresher.components
4009 .get(viewport.getSequenceSetId());
4010 List<TreePanel> treePanels = new ArrayList<>();
4011 for (Component comp : comps)
4013 if (comp instanceof TreePanel)
4015 treePanels.add((TreePanel) comp);
4019 if (treePanels.size() < 1)
4021 sortByTreeMenu.setVisible(false);
4025 sortByTreeMenu.setVisible(true);
4027 for (final TreePanel tp : treePanels)
4029 final JMenuItem item = new JMenuItem(tp.getTitle());
4030 item.addActionListener(new java.awt.event.ActionListener()
4033 public void actionPerformed(ActionEvent e)
4035 tp.sortByTree_actionPerformed();
4036 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4041 sortByTreeMenu.add(item);
4045 public boolean sortBy(AlignmentOrder alorder, String undoname)
4047 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4048 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4049 if (undoname != null)
4051 addHistoryItem(new OrderCommand(undoname, oldOrder,
4052 viewport.getAlignment()));
4054 alignPanel.paintAlignment(true, false);
4059 * Work out whether the whole set of sequences or just the selected set will
4060 * be submitted for multiple alignment.
4063 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4065 // Now, check we have enough sequences
4066 AlignmentView msa = null;
4068 if ((viewport.getSelectionGroup() != null)
4069 && (viewport.getSelectionGroup().getSize() > 1))
4071 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4072 // some common interface!
4074 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4075 * SequenceI[sz = seqs.getSize(false)];
4077 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4078 * seqs.getSequenceAt(i); }
4080 msa = viewport.getAlignmentView(true);
4082 else if (viewport.getSelectionGroup() != null
4083 && viewport.getSelectionGroup().getSize() == 1)
4085 int option = JvOptionPane.showConfirmDialog(this,
4086 MessageManager.getString("warn.oneseq_msainput_selection"),
4087 MessageManager.getString("label.invalid_selection"),
4088 JvOptionPane.OK_CANCEL_OPTION);
4089 if (option == JvOptionPane.OK_OPTION)
4091 msa = viewport.getAlignmentView(false);
4096 msa = viewport.getAlignmentView(false);
4102 * Decides what is submitted to a secondary structure prediction service: the
4103 * first sequence in the alignment, or in the current selection, or, if the
4104 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4105 * region or the whole alignment. (where the first sequence in the set is the
4106 * one that the prediction will be for).
4108 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4110 AlignmentView seqs = null;
4112 if ((viewport.getSelectionGroup() != null)
4113 && (viewport.getSelectionGroup().getSize() > 0))
4115 seqs = viewport.getAlignmentView(true);
4119 seqs = viewport.getAlignmentView(false);
4121 // limit sequences - JBPNote in future - could spawn multiple prediction
4123 // TODO: viewport.getAlignment().isAligned is a global state - the local
4124 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4125 if (!viewport.getAlignment().isAligned(false))
4127 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4128 // TODO: if seqs.getSequences().length>1 then should really have warned
4142 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4144 // Pick the tree file
4145 JalviewFileChooser chooser = new JalviewFileChooser(
4146 Cache.getProperty("LAST_DIRECTORY"));
4147 chooser.setFileView(new JalviewFileView());
4148 chooser.setDialogTitle(
4149 MessageManager.getString("label.select_newick_like_tree_file"));
4150 chooser.setToolTipText(
4151 MessageManager.getString("label.load_tree_file"));
4153 chooser.setResponseHandler(0, () -> {
4154 String filePath = chooser.getSelectedFile().getPath();
4155 Cache.setProperty("LAST_DIRECTORY", filePath);
4156 NewickFile fin = null;
4159 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4160 DataSourceType.FILE));
4161 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4162 } catch (Exception ex)
4164 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4165 MessageManager.getString("label.problem_reading_tree_file"),
4166 JvOptionPane.WARNING_MESSAGE);
4167 ex.printStackTrace();
4169 if (fin != null && fin.hasWarningMessage())
4171 JvOptionPane.showMessageDialog(Desktop.desktop,
4172 fin.getWarningMessage(),
4174 .getString("label.possible_problem_with_tree_file"),
4175 JvOptionPane.WARNING_MESSAGE);
4178 chooser.showOpenDialog(this);
4181 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4183 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4186 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4187 int h, int x, int y)
4189 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4193 * Add a treeviewer for the tree extracted from a Newick file object to the
4194 * current alignment view
4201 * Associated alignment input data (or null)
4210 * @return TreePanel handle
4212 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4213 AlignmentView input, int w, int h, int x, int y)
4215 TreePanel tp = null;
4221 if (nf.getTree() != null)
4223 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4229 tp.setLocation(x, y);
4232 Desktop.addInternalFrame(tp, treeTitle, w, h);
4234 } catch (Exception ex)
4236 ex.printStackTrace();
4242 public void showContactMapTree(AlignmentAnnotation aa,
4246 int w = 400, h = 500;
4250 NewickFile fin = new NewickFile(
4251 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4252 String title = aa.label + " "
4253 + cm.getTreeMethod() + " tree" + (aa.sequenceRef != null
4254 ? (" for " + aa.sequenceRef.getDisplayId(false))
4257 showColumnWiseTree(fin, aa, title, w, h, x, y);
4258 } catch (Throwable xx)
4260 Console.error("Unexpected exception showing tree for contact matrix",
4265 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4266 String treeTitle, int w, int h, int x, int y)
4271 if (nf.getTree() == null)
4275 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4281 tp.setLocation(x, y);
4284 Desktop.addInternalFrame(tp, treeTitle, w, h);
4286 } catch (Throwable xx)
4288 Console.error("Unexpected exception showing tree for contact matrix",
4294 private boolean buildingMenu = false;
4297 * Generates menu items and listener event actions for web service clients
4300 public void BuildWebServiceMenu()
4302 while (buildingMenu)
4306 System.err.println("Waiting for building menu to finish.");
4308 } catch (Exception e)
4312 final AlignFrame me = this;
4313 buildingMenu = true;
4314 new Thread(new Runnable()
4319 final List<JMenuItem> legacyItems = new ArrayList<>();
4322 // System.err.println("Building ws menu again "
4323 // + Thread.currentThread());
4324 // TODO: add support for context dependent disabling of services based
4326 // alignment and current selection
4327 // TODO: add additional serviceHandle parameter to specify abstract
4329 // class independently of AbstractName
4330 // TODO: add in rediscovery GUI function to restart discoverer
4331 // TODO: group services by location as well as function and/or
4333 // object broker mechanism.
4334 final Vector<JMenu> wsmenu = new Vector<>();
4335 final IProgressIndicator af = me;
4338 * do not i18n these strings - they are hard-coded in class
4339 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4340 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4342 final JMenu msawsmenu = new JMenu("Alignment");
4343 final JMenu secstrmenu = new JMenu(
4344 "Secondary Structure Prediction");
4345 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4346 final JMenu analymenu = new JMenu("Analysis");
4347 final JMenu dismenu = new JMenu("Protein Disorder");
4348 // JAL-940 - only show secondary structure prediction services from
4349 // the legacy server
4350 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4352 Discoverer.services != null && (Discoverer.services.size() > 0))
4354 // TODO: refactor to allow list of AbstractName/Handler bindings to
4356 // stored or retrieved from elsewhere
4357 // No MSAWS used any more:
4358 // Vector msaws = null; // (Vector)
4359 // Discoverer.services.get("MsaWS");
4360 Vector<ServiceHandle> secstrpr = Discoverer.services
4362 if (secstrpr != null)
4364 // Add any secondary structure prediction services
4365 for (int i = 0, j = secstrpr.size(); i < j; i++)
4367 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4368 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4369 .getServiceClient(sh);
4370 int p = secstrmenu.getItemCount();
4371 impl.attachWSMenuEntry(secstrmenu, me);
4372 int q = secstrmenu.getItemCount();
4373 for (int litm = p; litm < q; litm++)
4375 legacyItems.add(secstrmenu.getItem(litm));
4381 // Add all submenus in the order they should appear on the web
4383 wsmenu.add(msawsmenu);
4384 wsmenu.add(secstrmenu);
4385 wsmenu.add(dismenu);
4386 wsmenu.add(analymenu);
4387 // No search services yet
4388 // wsmenu.add(seqsrchmenu);
4390 javax.swing.SwingUtilities.invokeLater(new Runnable()
4397 webService.removeAll();
4398 // first, add discovered services onto the webservices menu
4399 if (wsmenu.size() > 0)
4401 for (int i = 0, j = wsmenu.size(); i < j; i++)
4403 webService.add(wsmenu.get(i));
4408 webService.add(me.webServiceNoServices);
4410 // TODO: move into separate menu builder class.
4412 // logic for 2.11.1.4 is
4413 // always look to see if there is a discover. if there isn't
4414 // we can't show any Jws2 services
4415 // if there are services available, show them - regardless of
4416 // the 'show JWS2 preference'
4417 // if the discoverer is running then say so
4418 // otherwise offer to trigger discovery if 'show JWS2' is not
4420 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4421 if (jws2servs != null)
4423 if (jws2servs.hasServices())
4425 jws2servs.attachWSMenuEntry(webService, me);
4426 for (Jws2Instance sv : jws2servs.getServices())
4428 if (sv.description.toLowerCase(Locale.ROOT)
4431 for (JMenuItem jmi : legacyItems)
4433 jmi.setVisible(false);
4439 if (jws2servs.isRunning())
4441 JMenuItem tm = new JMenuItem(
4442 "Still discovering JABA Services");
4443 tm.setEnabled(false);
4446 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4448 JMenuItem enableJws2 = new JMenuItem(
4449 "Discover Web Services");
4450 enableJws2.setToolTipText(
4451 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4452 enableJws2.setEnabled(true);
4453 enableJws2.addActionListener(new ActionListener()
4457 public void actionPerformed(ActionEvent e)
4459 // start service discoverer, but ignore preference
4460 Desktop.instance.startServiceDiscovery(false,
4464 webService.add(enableJws2);
4468 build_urlServiceMenu(me.webService);
4469 build_fetchdbmenu(webService);
4470 for (JMenu item : wsmenu)
4472 if (item.getItemCount() == 0)
4474 item.setEnabled(false);
4478 item.setEnabled(true);
4481 } catch (Exception e)
4484 "Exception during web service menu building process.",
4489 } catch (Exception e)
4492 buildingMenu = false;
4499 * construct any groupURL type service menu entries.
4503 protected void build_urlServiceMenu(JMenu webService)
4505 // TODO: remove this code when 2.7 is released
4506 // DEBUG - alignmentView
4508 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4509 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4511 * @Override public void actionPerformed(ActionEvent e) {
4512 * jalview.datamodel.AlignmentView
4513 * .testSelectionViews(af.viewport.getAlignment(),
4514 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4516 * }); webService.add(testAlView);
4518 // TODO: refactor to RestClient discoverer and merge menu entries for
4519 // rest-style services with other types of analysis/calculation service
4520 // SHmmr test client - still being implemented.
4521 // DEBUG - alignmentView
4523 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4526 client.attachWSMenuEntry(
4527 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4533 * Searches the alignment sequences for xRefs and builds the Show
4534 * Cross-References menu (formerly called Show Products), with database
4535 * sources for which cross-references are found (protein sources for a
4536 * nucleotide alignment and vice versa)
4538 * @return true if Show Cross-references menu should be enabled
4540 public boolean canShowProducts()
4542 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4543 AlignmentI dataset = viewport.getAlignment().getDataset();
4545 showProducts.removeAll();
4546 final boolean dna = viewport.getAlignment().isNucleotide();
4548 if (seqs == null || seqs.length == 0)
4550 // nothing to see here.
4554 boolean showp = false;
4557 List<String> ptypes = new CrossRef(seqs, dataset)
4558 .findXrefSourcesForSequences(dna);
4560 for (final String source : ptypes)
4563 final AlignFrame af = this;
4564 JMenuItem xtype = new JMenuItem(source);
4565 xtype.addActionListener(new ActionListener()
4568 public void actionPerformed(ActionEvent e)
4570 showProductsFor(af.viewport.getSequenceSelection(), dna,
4574 showProducts.add(xtype);
4576 showProducts.setVisible(showp);
4577 showProducts.setEnabled(showp);
4578 } catch (Exception e)
4581 "canShowProducts threw an exception - please report to help@jalview.org",
4589 * Finds and displays cross-references for the selected sequences (protein
4590 * products for nucleotide sequences, dna coding sequences for peptides).
4593 * the sequences to show cross-references for
4595 * true if from a nucleotide alignment (so showing proteins)
4597 * the database to show cross-references for
4599 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4600 final String source)
4602 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4607 * Construct and display a new frame containing the translation of this
4608 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4611 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4613 AlignmentI al = null;
4616 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4618 al = dna.translateCdna(codeTable);
4619 } catch (Exception ex)
4621 Console.error("Exception during translation. Please report this !",
4623 final String msg = MessageManager.getString(
4624 "label.error_when_translating_sequences_submit_bug_report");
4625 final String errorTitle = MessageManager
4626 .getString("label.implementation_error")
4627 + MessageManager.getString("label.translation_failed");
4628 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4629 JvOptionPane.ERROR_MESSAGE);
4632 if (al == null || al.getHeight() == 0)
4634 final String msg = MessageManager.getString(
4635 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4636 final String errorTitle = MessageManager
4637 .getString("label.translation_failed");
4638 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4639 JvOptionPane.WARNING_MESSAGE);
4643 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4644 af.setFileFormat(this.currentFileFormat);
4645 final String newTitle = MessageManager
4646 .formatMessage("label.translation_of_params", new Object[]
4647 { this.getTitle(), codeTable.getId() });
4648 af.setTitle(newTitle);
4649 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4651 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4652 viewport.openSplitFrame(af, new Alignment(seqs));
4656 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4663 * Set the file format
4667 public void setFileFormat(FileFormatI format)
4669 this.currentFileFormat = format;
4673 * Try to load a features file onto the alignment.
4676 * contents or path to retrieve file or a File object
4678 * access mode of file (see jalview.io.AlignFile)
4679 * @return true if features file was parsed correctly.
4681 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4684 return avc.parseFeaturesFile(file, sourceType,
4685 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4690 public void refreshFeatureUI(boolean enableIfNecessary)
4692 // note - currently this is only still here rather than in the controller
4693 // because of the featureSettings hard reference that is yet to be
4695 if (enableIfNecessary)
4697 viewport.setShowSequenceFeatures(true);
4698 showSeqFeatures.setSelected(true);
4704 public void dragEnter(DropTargetDragEvent evt)
4709 public void dragExit(DropTargetEvent evt)
4714 public void dragOver(DropTargetDragEvent evt)
4719 public void dropActionChanged(DropTargetDragEvent evt)
4724 public void drop(DropTargetDropEvent evt)
4726 // JAL-1552 - acceptDrop required before getTransferable call for
4727 // Java's Transferable for native dnd
4728 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4729 Transferable t = evt.getTransferable();
4731 final AlignFrame thisaf = this;
4732 final List<Object> files = new ArrayList<>();
4733 List<DataSourceType> protocols = new ArrayList<>();
4737 Desktop.transferFromDropTarget(files, protocols, evt, t);
4738 } catch (Exception e)
4740 e.printStackTrace();
4744 new Thread(new Runnable()
4751 // check to see if any of these files have names matching sequences
4754 SequenceIdMatcher idm = new SequenceIdMatcher(
4755 viewport.getAlignment().getSequencesArray());
4757 * Object[] { String,SequenceI}
4759 ArrayList<Object[]> filesmatched = new ArrayList<>();
4760 ArrayList<Object> filesnotmatched = new ArrayList<>();
4761 for (int i = 0; i < files.size(); i++)
4764 Object file = files.get(i);
4765 String fileName = file.toString();
4767 DataSourceType protocol = (file instanceof File
4768 ? DataSourceType.FILE
4769 : FormatAdapter.checkProtocol(fileName));
4770 if (protocol == DataSourceType.FILE)
4773 if (file instanceof File)
4776 Platform.cacheFileData(fl);
4780 fl = new File(fileName);
4782 pdbfn = fl.getName();
4784 else if (protocol == DataSourceType.URL)
4786 URL url = new URL(fileName);
4787 pdbfn = url.getFile();
4789 if (pdbfn.length() > 0)
4791 // attempt to find a match in the alignment
4792 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4793 int l = 0, c = pdbfn.indexOf(".");
4794 while (mtch == null && c != -1)
4799 } while ((c = pdbfn.indexOf(".", l)) > l);
4802 pdbfn = pdbfn.substring(0, l);
4804 mtch = idm.findAllIdMatches(pdbfn);
4811 type = new IdentifyFile().identify(file, protocol);
4812 } catch (Exception ex)
4816 if (type != null && type.isStructureFile())
4818 filesmatched.add(new Object[] { file, protocol, mtch });
4822 // File wasn't named like one of the sequences or wasn't a PDB
4824 filesnotmatched.add(file);
4828 if (filesmatched.size() > 0)
4830 boolean autoAssociate = Cache
4831 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4834 String msg = MessageManager.formatMessage(
4835 "label.automatically_associate_structure_files_with_sequences_same_name",
4837 { Integer.valueOf(filesmatched.size())
4839 String ttl = MessageManager.getString(
4840 "label.automatically_associate_structure_files_by_name");
4841 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4842 ttl, JvOptionPane.YES_NO_OPTION);
4843 autoAssociate = choice == JvOptionPane.YES_OPTION;
4847 for (Object[] fm : filesmatched)
4849 // try and associate
4850 // TODO: may want to set a standard ID naming formalism for
4851 // associating PDB files which have no IDs.
4852 for (SequenceI toassoc : (SequenceI[]) fm[2])
4854 PDBEntry pe = new AssociatePdbFileWithSeq()
4855 .associatePdbWithSeq(fm[0].toString(),
4856 (DataSourceType) fm[1], toassoc, false,
4860 System.err.println("Associated file : "
4861 + (fm[0].toString()) + " with "
4862 + toassoc.getDisplayId(true));
4866 // TODO: do we need to update overview ? only if features are
4868 alignPanel.paintAlignment(true, false);
4874 * add declined structures as sequences
4876 for (Object[] o : filesmatched)
4878 filesnotmatched.add(o[0]);
4882 if (filesnotmatched.size() > 0)
4884 if (assocfiles > 0 && (Cache.getDefault(
4885 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4886 || JvOptionPane.showConfirmDialog(thisaf,
4887 "<html>" + MessageManager.formatMessage(
4888 "label.ignore_unmatched_dropped_files_info",
4891 filesnotmatched.size())
4894 MessageManager.getString(
4895 "label.ignore_unmatched_dropped_files"),
4896 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4900 for (Object fn : filesnotmatched)
4902 loadJalviewDataFile(fn, null, null, null);
4906 } catch (Exception ex)
4908 ex.printStackTrace();
4916 * Attempt to load a "dropped" file or URL string, by testing in turn for
4918 * <li>an Annotation file</li>
4919 * <li>a JNet file</li>
4920 * <li>a features file</li>
4921 * <li>else try to interpret as an alignment file</li>
4925 * either a filename or a URL string.
4927 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4928 FileFormatI format, SequenceI assocSeq)
4930 // BH 2018 was String file
4933 if (sourceType == null)
4935 sourceType = FormatAdapter.checkProtocol(file);
4937 // if the file isn't identified, or not positively identified as some
4938 // other filetype (PFAM is default unidentified alignment file type) then
4939 // try to parse as annotation.
4940 boolean isAnnotation = (format == null
4941 || FileFormat.Pfam.equals(format))
4942 ? new AnnotationFile().annotateAlignmentView(viewport,
4948 // first see if its a T-COFFEE score file
4949 TCoffeeScoreFile tcf = null;
4952 tcf = new TCoffeeScoreFile(file, sourceType);
4955 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4959 new TCoffeeColourScheme(viewport.getAlignment()));
4960 isAnnotation = true;
4961 setStatus(MessageManager.getString(
4962 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4966 // some problem - if no warning its probable that the ID matching
4967 // process didn't work
4968 JvOptionPane.showMessageDialog(Desktop.desktop,
4969 tcf.getWarningMessage() == null
4970 ? MessageManager.getString(
4971 "label.check_file_matches_sequence_ids_alignment")
4972 : tcf.getWarningMessage(),
4973 MessageManager.getString(
4974 "label.problem_reading_tcoffee_score_file"),
4975 JvOptionPane.WARNING_MESSAGE);
4982 } catch (Exception x)
4985 "Exception when processing data source as T-COFFEE score file",
4991 // try to see if its a JNet 'concise' style annotation file *before*
4993 // try to parse it as a features file
4996 format = new IdentifyFile().identify(file, sourceType);
4998 if (FileFormat.ScoreMatrix == format)
5000 ScoreMatrixFile sm = new ScoreMatrixFile(
5001 new FileParse(file, sourceType));
5003 // todo: i18n this message
5004 setStatus(MessageManager.formatMessage(
5005 "label.successfully_loaded_matrix",
5006 sm.getMatrixName()));
5008 else if (FileFormat.Jnet.equals(format))
5010 JPredFile predictions = new JPredFile(file, sourceType);
5011 new JnetAnnotationMaker();
5012 JnetAnnotationMaker.add_annotation(predictions,
5013 viewport.getAlignment(), 0, false);
5014 viewport.getAlignment().setupJPredAlignment();
5015 isAnnotation = true;
5017 // else if (IdentifyFile.FeaturesFile.equals(format))
5018 else if (FileFormat.Features.equals(format))
5020 if (parseFeaturesFile(file, sourceType))
5022 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5023 if (splitFrame != null)
5025 splitFrame.repaint();
5029 alignPanel.paintAlignment(true, true);
5035 new FileLoader().LoadFile(viewport, file, sourceType, format);
5042 alignPanel.adjustAnnotationHeight();
5043 viewport.updateSequenceIdColours();
5044 buildSortByAnnotationScoresMenu();
5045 alignPanel.paintAlignment(true, true);
5047 } catch (Exception ex)
5049 ex.printStackTrace();
5050 } catch (OutOfMemoryError oom)
5055 } catch (Exception x)
5060 + (sourceType != null
5061 ? (sourceType == DataSourceType.PASTE
5063 : "using " + sourceType + " from "
5067 ? "(parsing as '" + format + "' file)"
5069 oom, Desktop.desktop);
5074 * Method invoked by the ChangeListener on the tabbed pane, in other words
5075 * when a different tabbed pane is selected by the user or programmatically.
5078 public void tabSelectionChanged(int index)
5083 * update current Overview window title (if there is one)
5084 * to add view name "Original" if necessary
5086 alignPanel.setOverviewTitle(this);
5089 * switch panels and set Overview title (if there is one
5090 * because it was opened automatically)
5092 alignPanel = alignPanels.get(index);
5093 alignPanel.setOverviewTitle(this);
5095 viewport = alignPanel.av;
5096 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5097 setMenusFromViewport(viewport);
5098 if (featureSettings != null && featureSettings.isOpen()
5099 && featureSettings.fr.getViewport() != viewport)
5101 if (viewport.isShowSequenceFeatures())
5103 // refresh the featureSettings to reflect UI change
5104 showFeatureSettingsUI();
5108 // close feature settings for this view.
5109 featureSettings.close();
5116 * 'focus' any colour slider that is open to the selected viewport
5118 if (viewport.getConservationSelected())
5120 SliderPanel.setConservationSlider(alignPanel,
5121 viewport.getResidueShading(), alignPanel.getViewName());
5125 SliderPanel.hideConservationSlider();
5127 if (viewport.getAbovePIDThreshold())
5129 SliderPanel.setPIDSliderSource(alignPanel,
5130 viewport.getResidueShading(), alignPanel.getViewName());
5134 SliderPanel.hidePIDSlider();
5138 * If there is a frame linked to this one in a SplitPane, switch it to the
5139 * same view tab index. No infinite recursion of calls should happen, since
5140 * tabSelectionChanged() should not get invoked on setting the selected
5141 * index to an unchanged value. Guard against setting an invalid index
5142 * before the new view peer tab has been created.
5144 final AlignViewportI peer = viewport.getCodingComplement();
5147 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5148 .getAlignPanel().alignFrame;
5149 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5151 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5157 * On right mouse click on view tab, prompt for and set new view name.
5160 public void tabbedPane_mousePressed(MouseEvent e)
5162 if (e.isPopupTrigger())
5164 String msg = MessageManager.getString("label.enter_view_name");
5165 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5166 String reply = JvOptionPane.showInputDialog(msg, ttl);
5170 viewport.setViewName(reply);
5171 // TODO warn if reply is in getExistingViewNames()?
5172 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5177 public AlignViewport getCurrentView()
5183 * Open the dialog for regex description parsing.
5186 protected void extractScores_actionPerformed(ActionEvent e)
5188 ParseProperties pp = new jalview.analysis.ParseProperties(
5189 viewport.getAlignment());
5190 // TODO: verify regex and introduce GUI dialog for version 2.5
5191 // if (pp.getScoresFromDescription("col", "score column ",
5192 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5194 if (pp.getScoresFromDescription("description column",
5195 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5197 buildSortByAnnotationScoresMenu();
5205 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5209 protected void showDbRefs_actionPerformed(ActionEvent e)
5211 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5217 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5221 protected void showNpFeats_actionPerformed(ActionEvent e)
5223 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5227 * find the viewport amongst the tabs in this alignment frame and close that
5232 public boolean closeView(AlignViewportI av)
5236 this.closeMenuItem_actionPerformed(false);
5239 Component[] comp = tabbedPane.getComponents();
5240 for (int i = 0; comp != null && i < comp.length; i++)
5242 if (comp[i] instanceof AlignmentPanel)
5244 if (((AlignmentPanel) comp[i]).av == av)
5247 closeView((AlignmentPanel) comp[i]);
5255 protected void build_fetchdbmenu(JMenu webService)
5257 // Temporary hack - DBRef Fetcher always top level ws entry.
5258 // TODO We probably want to store a sequence database checklist in
5259 // preferences and have checkboxes.. rather than individual sources selected
5261 final JMenu rfetch = new JMenu(
5262 MessageManager.getString("action.fetch_db_references"));
5263 rfetch.setToolTipText(MessageManager.getString(
5264 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5265 webService.add(rfetch);
5267 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5268 MessageManager.getString("option.trim_retrieved_seqs"));
5269 trimrs.setToolTipText(
5270 MessageManager.getString("label.trim_retrieved_sequences"));
5272 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5273 trimrs.addActionListener(new ActionListener()
5276 public void actionPerformed(ActionEvent e)
5278 trimrs.setSelected(trimrs.isSelected());
5279 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5280 Boolean.valueOf(trimrs.isSelected()).toString());
5284 JMenuItem fetchr = new JMenuItem(
5285 MessageManager.getString("label.standard_databases"));
5286 fetchr.setToolTipText(
5287 MessageManager.getString("label.fetch_embl_uniprot"));
5288 fetchr.addActionListener(new ActionListener()
5292 public void actionPerformed(ActionEvent e)
5294 new Thread(new Runnable()
5299 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5300 .getAlignment().isNucleotide();
5301 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5302 alignPanel.av.getSequenceSelection(),
5303 alignPanel.alignFrame, null,
5304 alignPanel.alignFrame.featureSettings, isNucleotide);
5305 dbRefFetcher.addListener(new FetchFinishedListenerI()
5308 public void finished()
5311 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5312 .getFeatureSettingsModels())
5315 alignPanel.av.mergeFeaturesStyle(srcSettings);
5317 AlignFrame.this.setMenusForViewport();
5320 dbRefFetcher.fetchDBRefs(false);
5328 new Thread(new Runnable()
5333 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5334 .getSequenceFetcherSingleton();
5335 javax.swing.SwingUtilities.invokeLater(new Runnable()
5340 String[] dbclasses = sf.getNonAlignmentSources();
5341 List<DbSourceProxy> otherdb;
5342 JMenu dfetch = new JMenu();
5343 JMenu ifetch = new JMenu();
5344 JMenuItem fetchr = null;
5345 int comp = 0, icomp = 0, mcomp = 15;
5346 String mname = null;
5348 for (String dbclass : dbclasses)
5350 otherdb = sf.getSourceProxy(dbclass);
5351 // add a single entry for this class, or submenu allowing 'fetch
5353 if (otherdb == null || otherdb.size() < 1)
5359 mname = "From " + dbclass;
5361 if (otherdb.size() == 1)
5363 final DbSourceProxy[] dassource = otherdb
5364 .toArray(new DbSourceProxy[0]);
5365 DbSourceProxy src = otherdb.get(0);
5366 fetchr = new JMenuItem(src.getDbSource());
5367 fetchr.addActionListener(new ActionListener()
5371 public void actionPerformed(ActionEvent e)
5373 new Thread(new Runnable()
5379 boolean isNucleotide = alignPanel.alignFrame
5380 .getViewport().getAlignment()
5382 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5383 alignPanel.av.getSequenceSelection(),
5384 alignPanel.alignFrame, dassource,
5385 alignPanel.alignFrame.featureSettings,
5388 .addListener(new FetchFinishedListenerI()
5391 public void finished()
5393 FeatureSettingsModelI srcSettings = dassource[0]
5394 .getFeatureColourScheme();
5395 alignPanel.av.mergeFeaturesStyle(
5397 AlignFrame.this.setMenusForViewport();
5400 dbRefFetcher.fetchDBRefs(false);
5406 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5407 MessageManager.formatMessage(
5408 "label.fetch_retrieve_from", new Object[]
5409 { src.getDbName() })));
5415 final DbSourceProxy[] dassource = otherdb
5416 .toArray(new DbSourceProxy[0]);
5418 DbSourceProxy src = otherdb.get(0);
5419 fetchr = new JMenuItem(MessageManager
5420 .formatMessage("label.fetch_all_param", new Object[]
5421 { src.getDbSource() }));
5422 fetchr.addActionListener(new ActionListener()
5425 public void actionPerformed(ActionEvent e)
5427 new Thread(new Runnable()
5433 boolean isNucleotide = alignPanel.alignFrame
5434 .getViewport().getAlignment()
5436 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5437 alignPanel.av.getSequenceSelection(),
5438 alignPanel.alignFrame, dassource,
5439 alignPanel.alignFrame.featureSettings,
5442 .addListener(new FetchFinishedListenerI()
5445 public void finished()
5447 AlignFrame.this.setMenusForViewport();
5450 dbRefFetcher.fetchDBRefs(false);
5456 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5457 MessageManager.formatMessage(
5458 "label.fetch_retrieve_from_all_sources",
5460 { Integer.valueOf(otherdb.size())
5462 src.getDbSource(), src.getDbName() })));
5465 // and then build the rest of the individual menus
5466 ifetch = new JMenu(MessageManager.formatMessage(
5467 "label.source_from_db_source", new Object[]
5468 { src.getDbSource() }));
5470 String imname = null;
5472 for (DbSourceProxy sproxy : otherdb)
5474 String dbname = sproxy.getDbName();
5475 String sname = dbname.length() > 5
5476 ? dbname.substring(0, 5) + "..."
5478 String msname = dbname.length() > 10
5479 ? dbname.substring(0, 10) + "..."
5483 imname = MessageManager
5484 .formatMessage("label.from_msname", new Object[]
5487 fetchr = new JMenuItem(msname);
5488 final DbSourceProxy[] dassrc = { sproxy };
5489 fetchr.addActionListener(new ActionListener()
5493 public void actionPerformed(ActionEvent e)
5495 new Thread(new Runnable()
5501 boolean isNucleotide = alignPanel.alignFrame
5502 .getViewport().getAlignment()
5504 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5505 alignPanel.av.getSequenceSelection(),
5506 alignPanel.alignFrame, dassrc,
5507 alignPanel.alignFrame.featureSettings,
5510 .addListener(new FetchFinishedListenerI()
5513 public void finished()
5515 AlignFrame.this.setMenusForViewport();
5518 dbRefFetcher.fetchDBRefs(false);
5524 fetchr.setToolTipText(
5525 "<html>" + MessageManager.formatMessage(
5526 "label.fetch_retrieve_from", new Object[]
5530 if (++icomp >= mcomp || i == (otherdb.size()))
5532 ifetch.setText(MessageManager.formatMessage(
5533 "label.source_to_target", imname, sname));
5535 ifetch = new JMenu();
5543 if (comp >= mcomp || dbi >= (dbclasses.length))
5545 dfetch.setText(MessageManager.formatMessage(
5546 "label.source_to_target", mname, dbclass));
5548 dfetch = new JMenu();
5561 * Left justify the whole alignment.
5564 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5566 AlignmentI al = viewport.getAlignment();
5568 viewport.firePropertyChange("alignment", null, al);
5572 * Right justify the whole alignment.
5575 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5577 AlignmentI al = viewport.getAlignment();
5579 viewport.firePropertyChange("alignment", null, al);
5583 public void setShowSeqFeatures(boolean b)
5585 showSeqFeatures.setSelected(b);
5586 viewport.setShowSequenceFeatures(b);
5593 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5594 * awt.event.ActionEvent)
5597 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5599 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5600 alignPanel.paintAlignment(false, false);
5607 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5611 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5613 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5614 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5622 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5623 * .event.ActionEvent)
5626 protected void showGroupConservation_actionPerformed(ActionEvent e)
5628 viewport.setShowGroupConservation(showGroupConservation.getState());
5629 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5636 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5637 * .event.ActionEvent)
5640 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5642 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5643 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5650 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5651 * .event.ActionEvent)
5654 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5656 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5657 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5661 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5663 showSequenceLogo.setState(true);
5664 viewport.setShowSequenceLogo(true);
5665 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5666 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5670 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5672 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5679 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5680 * .event.ActionEvent)
5683 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5685 if (avc.makeGroupsFromSelection())
5687 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5688 alignPanel.updateAnnotation();
5689 alignPanel.paintAlignment(true,
5690 viewport.needToUpdateStructureViews());
5694 public void clearAlignmentSeqRep()
5696 // TODO refactor alignmentseqrep to controller
5697 if (viewport.getAlignment().hasSeqrep())
5699 viewport.getAlignment().setSeqrep(null);
5700 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5701 alignPanel.updateAnnotation();
5702 alignPanel.paintAlignment(true, true);
5707 protected void createGroup_actionPerformed(ActionEvent e)
5709 if (avc.createGroup())
5711 if (applyAutoAnnotationSettings.isSelected())
5713 alignPanel.updateAnnotation(true, false);
5715 alignPanel.alignmentChanged();
5720 protected void unGroup_actionPerformed(ActionEvent e)
5724 alignPanel.alignmentChanged();
5729 * make the given alignmentPanel the currently selected tab
5731 * @param alignmentPanel
5733 public void setDisplayedView(AlignmentPanel alignmentPanel)
5735 if (!viewport.getSequenceSetId()
5736 .equals(alignmentPanel.av.getSequenceSetId()))
5738 throw new Error(MessageManager.getString(
5739 "error.implementation_error_cannot_show_view_alignment_frame"));
5741 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5742 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5744 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5749 * Action on selection of menu options to Show or Hide annotations.
5752 * @param forSequences
5753 * update sequence-related annotations
5754 * @param forAlignment
5755 * update non-sequence-related annotations
5758 public void setAnnotationsVisibility(boolean visible,
5759 boolean forSequences, boolean forAlignment)
5761 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5762 .getAlignmentAnnotation();
5767 for (AlignmentAnnotation aa : anns)
5770 * don't display non-positional annotations on an alignment
5772 if (aa.annotations == null)
5776 boolean apply = (aa.sequenceRef == null && forAlignment)
5777 || (aa.sequenceRef != null && forSequences);
5780 aa.visible = visible;
5783 alignPanel.validateAnnotationDimensions(true);
5784 alignPanel.alignmentChanged();
5788 * Store selected annotation sort order for the view and repaint.
5791 protected void sortAnnotations_actionPerformed()
5793 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5795 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5796 alignPanel.paintAlignment(false, false);
5801 * @return alignment panels in this alignment frame
5803 public List<? extends AlignmentViewPanel> getAlignPanels()
5805 // alignPanels is never null
5806 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5811 * Open a new alignment window, with the cDNA associated with this (protein)
5812 * alignment, aligned as is the protein.
5814 protected void viewAsCdna_actionPerformed()
5816 // TODO no longer a menu action - refactor as required
5817 final AlignmentI alignment = getViewport().getAlignment();
5818 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5819 if (mappings == null)
5823 List<SequenceI> cdnaSeqs = new ArrayList<>();
5824 for (SequenceI aaSeq : alignment.getSequences())
5826 for (AlignedCodonFrame acf : mappings)
5828 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5832 * There is a cDNA mapping for this protein sequence - add to new
5833 * alignment. It will share the same dataset sequence as other mapped
5834 * cDNA (no new mappings need to be created).
5836 final Sequence newSeq = new Sequence(dnaSeq);
5837 newSeq.setDatasetSequence(dnaSeq);
5838 cdnaSeqs.add(newSeq);
5842 if (cdnaSeqs.size() == 0)
5844 // show a warning dialog no mapped cDNA
5847 AlignmentI cdna = new Alignment(
5848 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5849 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5850 AlignFrame.DEFAULT_HEIGHT);
5851 cdna.alignAs(alignment);
5852 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5854 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5855 AlignFrame.DEFAULT_HEIGHT);
5859 * Set visibility of dna/protein complement view (available when shown in a
5865 protected void showComplement_actionPerformed(boolean show)
5867 SplitContainerI sf = getSplitViewContainer();
5870 sf.setComplementVisible(this, show);
5875 * Generate the reverse (optionally complemented) of the selected sequences,
5876 * and add them to the alignment
5879 protected void showReverse_actionPerformed(boolean complement)
5881 AlignmentI al = null;
5884 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5885 al = dna.reverseCdna(complement);
5886 viewport.addAlignment(al, "");
5887 addHistoryItem(new EditCommand(
5888 MessageManager.getString("label.add_sequences"), Action.PASTE,
5889 al.getSequencesArray(), 0, al.getWidth(),
5890 viewport.getAlignment()));
5891 } catch (Exception ex)
5893 System.err.println(ex.getMessage());
5899 * Try to run a script in the Groovy console, having first ensured that this
5900 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5901 * be targeted at this alignment.
5904 protected void runGroovy_actionPerformed()
5906 Jalview.setCurrentAlignFrame(this);
5907 groovy.ui.Console console = Desktop.getGroovyConsole();
5908 if (console != null)
5912 console.runScript();
5913 } catch (Exception ex)
5915 System.err.println((ex.toString()));
5916 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5917 MessageManager.getString("label.couldnt_run_groovy_script"),
5918 MessageManager.getString("label.groovy_support_failed"),
5919 JvOptionPane.ERROR_MESSAGE);
5924 System.err.println("Can't run Groovy script as console not found");
5929 * Hides columns containing (or not containing) a specified feature, provided
5930 * that would not leave all columns hidden
5932 * @param featureType
5933 * @param columnsContaining
5936 public boolean hideFeatureColumns(String featureType,
5937 boolean columnsContaining)
5939 boolean notForHiding = avc.markColumnsContainingFeatures(
5940 columnsContaining, false, false, featureType);
5943 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5944 false, featureType))
5946 getViewport().hideSelectedColumns();
5954 protected void selectHighlightedColumns_actionPerformed(
5955 ActionEvent actionEvent)
5957 // include key modifier check in case user selects from menu
5958 avc.markHighlightedColumns(
5959 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5960 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5961 | ActionEvent.CTRL_MASK)) != 0);
5965 protected void copyHighlightedColumns_actionPerformed(
5966 ActionEvent actionEvent)
5968 avc.copyHighlightedRegionsToClipboard();
5972 * Rebuilds the Colour menu, including any user-defined colours which have
5973 * been loaded either on startup or during the session
5975 public void buildColourMenu()
5977 colourMenu.removeAll();
5979 colourMenu.add(applyToAllGroups);
5980 colourMenu.add(textColour);
5981 colourMenu.addSeparator();
5983 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5984 viewport.getAlignment(), false);
5986 colourMenu.add(annotationColour);
5987 bg.add(annotationColour);
5988 colourMenu.addSeparator();
5989 colourMenu.add(conservationMenuItem);
5990 colourMenu.add(modifyConservation);
5991 colourMenu.add(abovePIDThreshold);
5992 colourMenu.add(modifyPID);
5994 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5995 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5999 * Open a dialog (if not already open) that allows the user to select and
6000 * calculate PCA or Tree analysis
6002 protected void openTreePcaDialog()
6004 if (alignPanel.getCalculationDialog() == null)
6006 new CalculationChooser(AlignFrame.this);
6011 protected void loadVcf_actionPerformed()
6013 JalviewFileChooser chooser = new JalviewFileChooser(
6014 Cache.getProperty("LAST_DIRECTORY"));
6015 chooser.setFileView(new JalviewFileView());
6016 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6017 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6018 final AlignFrame us = this;
6019 chooser.setResponseHandler(0, () -> {
6020 String choice = chooser.getSelectedFile().getPath();
6021 Cache.setProperty("LAST_DIRECTORY", choice);
6022 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6023 new VCFLoader(choice).loadVCF(seqs, us);
6025 chooser.showOpenDialog(null);
6029 private Rectangle lastFeatureSettingsBounds = null;
6032 public void setFeatureSettingsGeometry(Rectangle bounds)
6034 lastFeatureSettingsBounds = bounds;
6038 public Rectangle getFeatureSettingsGeometry()
6040 return lastFeatureSettingsBounds;
6045 class PrintThread extends Thread
6049 public PrintThread(AlignmentPanel ap)
6054 static PageFormat pf;
6059 PrinterJob printJob = PrinterJob.getPrinterJob();
6063 printJob.setPrintable(ap, pf);
6067 printJob.setPrintable(ap);
6070 if (printJob.printDialog())
6075 } catch (Exception PrintException)
6077 PrintException.printStackTrace();