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;
62 import java.util.concurrent.Callable;
64 import javax.swing.ButtonGroup;
65 import javax.swing.JCheckBoxMenuItem;
66 import javax.swing.JComponent;
67 import javax.swing.JEditorPane;
68 import javax.swing.JInternalFrame;
69 import javax.swing.JLabel;
70 import javax.swing.JLayeredPane;
71 import javax.swing.JMenu;
72 import javax.swing.JMenuItem;
73 import javax.swing.JPanel;
74 import javax.swing.JScrollPane;
75 import javax.swing.SwingUtilities;
77 import ext.vamsas.ServiceHandle;
78 import jalview.analysis.AlignmentSorter;
79 import jalview.analysis.AlignmentUtils;
80 import jalview.analysis.CrossRef;
81 import jalview.analysis.Dna;
82 import jalview.analysis.GeneticCodeI;
83 import jalview.analysis.ParseProperties;
84 import jalview.analysis.SequenceIdMatcher;
85 import jalview.api.AlignExportSettingsI;
86 import jalview.api.AlignViewControllerGuiI;
87 import jalview.api.AlignViewControllerI;
88 import jalview.api.AlignViewportI;
89 import jalview.api.AlignmentViewPanel;
90 import jalview.api.FeatureSettingsControllerI;
91 import jalview.api.FeatureSettingsModelI;
92 import jalview.api.SplitContainerI;
93 import jalview.api.ViewStyleI;
94 import jalview.api.analysis.SimilarityParamsI;
95 import jalview.bin.Cache;
96 import jalview.bin.Console;
97 import jalview.bin.Jalview;
98 import jalview.commands.CommandI;
99 import jalview.commands.EditCommand;
100 import jalview.commands.EditCommand.Action;
101 import jalview.commands.OrderCommand;
102 import jalview.commands.RemoveGapColCommand;
103 import jalview.commands.RemoveGapsCommand;
104 import jalview.commands.SlideSequencesCommand;
105 import jalview.commands.TrimRegionCommand;
106 import jalview.datamodel.AlignExportSettingsAdapter;
107 import jalview.datamodel.AlignedCodonFrame;
108 import jalview.datamodel.Alignment;
109 import jalview.datamodel.AlignmentAnnotation;
110 import jalview.datamodel.AlignmentExportData;
111 import jalview.datamodel.AlignmentI;
112 import jalview.datamodel.AlignmentOrder;
113 import jalview.datamodel.AlignmentView;
114 import jalview.datamodel.ColumnSelection;
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.vcf.VCFLoader;
144 import jalview.jbgui.GAlignFrame;
145 import jalview.project.Jalview2XML;
146 import jalview.schemes.ColourSchemeI;
147 import jalview.schemes.ColourSchemes;
148 import jalview.schemes.ResidueColourScheme;
149 import jalview.schemes.TCoffeeColourScheme;
150 import jalview.util.HttpUtils;
151 import jalview.util.ImageMaker.TYPE;
152 import jalview.util.MessageManager;
153 import jalview.util.Platform;
154 import jalview.viewmodel.AlignmentViewport;
155 import jalview.viewmodel.ViewportRanges;
156 import jalview.ws.DBRefFetcher;
157 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
158 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
159 import jalview.ws.jws1.Discoverer;
160 import jalview.ws.jws2.Jws2Discoverer;
161 import jalview.ws.jws2.jabaws2.Jws2Instance;
162 import jalview.ws.seqfetcher.DbSourceProxy;
168 * @version $Revision$
170 @SuppressWarnings("serial")
171 public class AlignFrame extends GAlignFrame implements DropTargetListener,
172 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
175 public static final int DEFAULT_WIDTH = 700;
177 public static final int DEFAULT_HEIGHT = 500;
180 * The currently displayed panel (selected tabbed view if more than one)
182 public AlignmentPanel alignPanel;
184 AlignViewport viewport;
186 public AlignViewControllerI avc;
188 List<AlignmentPanel> alignPanels = new ArrayList<>();
191 * Last format used to load or save alignments in this window
193 FileFormatI currentFileFormat = null;
196 * Current filename for this alignment
198 String fileName = null;
203 * Creates a new AlignFrame object with specific width and height.
209 public AlignFrame(AlignmentI al, int width, int height)
211 this(al, null, width, height);
215 * Creates a new AlignFrame object with specific width, height and
221 * @param sequenceSetId
223 public AlignFrame(AlignmentI al, int width, int height,
224 String sequenceSetId)
226 this(al, null, width, height, sequenceSetId);
230 * Creates a new AlignFrame object with specific width, height and
236 * @param sequenceSetId
239 public AlignFrame(AlignmentI al, int width, int height,
240 String sequenceSetId, String viewId)
242 this(al, null, width, height, sequenceSetId, viewId);
246 * new alignment window with hidden columns
250 * @param hiddenColumns
251 * ColumnSelection or null
253 * Width of alignment frame
257 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
260 this(al, hiddenColumns, width, height, null);
264 * Create alignment frame for al with hiddenColumns, a specific width and
265 * height, and specific sequenceId
268 * @param hiddenColumns
271 * @param sequenceSetId
274 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
275 int height, String sequenceSetId)
277 this(al, hiddenColumns, width, height, sequenceSetId, null);
281 * Create alignment frame for al with hiddenColumns, a specific width and
282 * height, and specific sequenceId
285 * @param hiddenColumns
288 * @param sequenceSetId
293 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
294 int height, String sequenceSetId, String viewId)
296 setSize(width, height);
298 if (al.getDataset() == null)
303 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
305 alignPanel = new AlignmentPanel(this, viewport);
307 addAlignmentPanel(alignPanel, true);
311 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
312 HiddenColumns hiddenColumns, int width, int height)
314 setSize(width, height);
316 if (al.getDataset() == null)
321 viewport = new AlignViewport(al, hiddenColumns);
323 if (hiddenSeqs != null && hiddenSeqs.length > 0)
325 viewport.hideSequence(hiddenSeqs);
327 alignPanel = new AlignmentPanel(this, viewport);
328 addAlignmentPanel(alignPanel, true);
333 * Make a new AlignFrame from existing alignmentPanels
340 public AlignFrame(AlignmentPanel ap)
344 addAlignmentPanel(ap, false);
349 * initalise the alignframe from the underlying viewport data and the
356 // setBackground(Color.white); // BH 2019
358 if (!Jalview.isHeadlessMode())
360 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
363 avc = new jalview.controller.AlignViewController(this, viewport,
365 if (viewport.getAlignmentConservationAnnotation() == null)
367 // BLOSUM62Colour.setEnabled(false);
368 conservationMenuItem.setEnabled(false);
369 modifyConservation.setEnabled(false);
370 // PIDColour.setEnabled(false);
371 // abovePIDThreshold.setEnabled(false);
372 // modifyPID.setEnabled(false);
375 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
377 if (sortby.equals("Id"))
379 sortIDMenuItem_actionPerformed(null);
381 else if (sortby.equals("Pairwise Identity"))
383 sortPairwiseMenuItem_actionPerformed(null);
387 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
389 setMenusFromViewport(viewport);
390 buildSortByAnnotationScoresMenu();
391 calculateTree.addActionListener(new ActionListener()
395 public void actionPerformed(ActionEvent e)
402 if (Desktop.desktop != null)
404 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
405 if (!Platform.isJS())
407 addServiceListeners();
412 if (viewport.getWrapAlignment())
414 wrapMenuItem_actionPerformed(null);
417 if (Cache.getDefault("SHOW_OVERVIEW", false))
419 this.overviewMenuItem_actionPerformed(null);
424 final List<AlignmentViewPanel> selviews = new ArrayList<>();
425 final List<AlignmentPanel> origview = new ArrayList<>();
426 final String menuLabel = MessageManager
427 .getString("label.copy_format_from");
428 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
429 new ViewSetProvider()
433 public AlignmentPanel[] getAllAlignmentPanels()
436 origview.add(alignPanel);
437 // make an array of all alignment panels except for this one
438 List<AlignmentPanel> aps = new ArrayList<>(
439 Arrays.asList(Desktop.getAlignmentPanels(null)));
440 aps.remove(AlignFrame.this.alignPanel);
441 return aps.toArray(new AlignmentPanel[aps.size()]);
443 }, selviews, new ItemListener()
447 public void itemStateChanged(ItemEvent e)
449 if (origview.size() > 0)
451 final AlignmentPanel ap = origview.get(0);
454 * Copy the ViewStyle of the selected panel to 'this one'.
455 * Don't change value of 'scaleProteinAsCdna' unless copying
458 ViewStyleI vs = selviews.get(0).getAlignViewport()
460 boolean fromSplitFrame = selviews.get(0)
461 .getAlignViewport().getCodingComplement() != null;
464 vs.setScaleProteinAsCdna(ap.getAlignViewport()
465 .getViewStyle().isScaleProteinAsCdna());
467 ap.getAlignViewport().setViewStyle(vs);
470 * Also rescale ViewStyle of SplitFrame complement if there is
471 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
472 * the whole ViewStyle (allow cDNA protein to have different
475 AlignViewportI complement = ap.getAlignViewport()
476 .getCodingComplement();
477 if (complement != null && vs.isScaleProteinAsCdna())
479 AlignFrame af = Desktop.getAlignFrameFor(complement);
480 ((SplitFrame) af.getSplitViewContainer())
482 af.setMenusForViewport();
486 ap.setSelected(true);
487 ap.alignFrame.setMenusForViewport();
492 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
493 .indexOf("devel") > -1
494 || Cache.getDefault("VERSION", "DEVELOPMENT")
495 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
497 formatMenu.add(vsel);
499 addFocusListener(new FocusAdapter()
502 public void focusGained(FocusEvent e)
504 Jalview.setCurrentAlignFrame(AlignFrame.this);
511 * Change the filename and format for the alignment, and enable the 'reload'
512 * button functionality.
519 public void setFileName(String file, FileFormatI format)
522 setFileFormat(format);
523 reload.setEnabled(true);
527 * JavaScript will have this, maybe others. More dependable than a file name
528 * and maintains a reference to the actual bytes loaded.
532 public void setFileObject(File file)
534 this.fileObject = file;
538 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
541 void addKeyListener()
543 addKeyListener(new KeyAdapter()
546 public void keyPressed(KeyEvent evt)
548 if (viewport.cursorMode
549 && ((evt.getKeyCode() >= KeyEvent.VK_0
550 && evt.getKeyCode() <= KeyEvent.VK_9)
551 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
552 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
553 && Character.isDigit(evt.getKeyChar()))
555 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
558 switch (evt.getKeyCode())
561 case 27: // escape key
562 deselectAllSequenceMenuItem_actionPerformed(null);
566 case KeyEvent.VK_DOWN:
567 if (evt.isAltDown() || !viewport.cursorMode)
569 moveSelectedSequences(false);
571 if (viewport.cursorMode)
573 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
578 if (evt.isAltDown() || !viewport.cursorMode)
580 moveSelectedSequences(true);
582 if (viewport.cursorMode)
584 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
589 case KeyEvent.VK_LEFT:
590 if (evt.isAltDown() || !viewport.cursorMode)
592 slideSequences(false,
593 alignPanel.getSeqPanel().getKeyboardNo1());
597 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
602 case KeyEvent.VK_RIGHT:
603 if (evt.isAltDown() || !viewport.cursorMode)
605 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
609 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
613 case KeyEvent.VK_SPACE:
614 if (viewport.cursorMode)
616 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
617 || evt.isShiftDown() || evt.isAltDown());
621 // case KeyEvent.VK_A:
622 // if (viewport.cursorMode)
624 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
625 // //System.out.println("A");
629 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
630 * System.out.println("closing bracket"); } break;
632 case KeyEvent.VK_DELETE:
633 case KeyEvent.VK_BACK_SPACE:
634 if (!viewport.cursorMode)
636 cut_actionPerformed();
640 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
641 || evt.isShiftDown() || evt.isAltDown());
647 if (viewport.cursorMode)
649 alignPanel.getSeqPanel().setCursorRow();
653 if (viewport.cursorMode && !evt.isControlDown())
655 alignPanel.getSeqPanel().setCursorColumn();
659 if (viewport.cursorMode)
661 alignPanel.getSeqPanel().setCursorPosition();
665 case KeyEvent.VK_ENTER:
666 case KeyEvent.VK_COMMA:
667 if (viewport.cursorMode)
669 alignPanel.getSeqPanel().setCursorRowAndColumn();
674 if (viewport.cursorMode)
676 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
680 if (viewport.cursorMode)
682 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
687 viewport.cursorMode = !viewport.cursorMode;
688 setStatus(MessageManager
689 .formatMessage("label.keyboard_editing_mode", new String[]
690 { (viewport.cursorMode ? "on" : "off") }));
691 if (viewport.cursorMode)
693 ViewportRanges ranges = viewport.getRanges();
694 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
696 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
699 alignPanel.getSeqPanel().seqCanvas.repaint();
705 Help.showHelpWindow();
706 } catch (Exception ex)
708 ex.printStackTrace();
713 boolean toggleSeqs = !evt.isControlDown();
714 boolean toggleCols = !evt.isShiftDown();
715 toggleHiddenRegions(toggleSeqs, toggleCols);
720 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
721 boolean modifyExisting = true; // always modify, don't clear
722 // evt.isShiftDown();
723 boolean invertHighlighted = evt.isAltDown();
724 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
728 case KeyEvent.VK_PAGE_UP:
729 viewport.getRanges().pageUp();
731 case KeyEvent.VK_PAGE_DOWN:
732 viewport.getRanges().pageDown();
738 public void keyReleased(KeyEvent evt)
740 switch (evt.getKeyCode())
742 case KeyEvent.VK_LEFT:
743 if (evt.isAltDown() || !viewport.cursorMode)
745 viewport.firePropertyChange("alignment", null,
746 viewport.getAlignment().getSequences());
750 case KeyEvent.VK_RIGHT:
751 if (evt.isAltDown() || !viewport.cursorMode)
753 viewport.firePropertyChange("alignment", null,
754 viewport.getAlignment().getSequences());
762 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
764 ap.alignFrame = this;
765 avc = new jalview.controller.AlignViewController(this, viewport,
770 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
772 int aSize = alignPanels.size();
774 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
776 if (aSize == 1 && ap.av.getViewName() == null)
778 this.getContentPane().add(ap, BorderLayout.CENTER);
784 setInitialTabVisible();
787 expandViews.setEnabled(true);
788 gatherViews.setEnabled(true);
789 tabbedPane.addTab(ap.av.getViewName(), ap);
791 ap.setVisible(false);
796 if (ap.av.isPadGaps())
798 ap.av.getAlignment().padGaps();
800 ap.av.updateConservation(ap);
801 ap.av.updateConsensus(ap);
802 ap.av.updateStrucConsensus(ap);
806 public void setInitialTabVisible()
808 expandViews.setEnabled(true);
809 gatherViews.setEnabled(true);
810 tabbedPane.setVisible(true);
811 AlignmentPanel first = alignPanels.get(0);
812 tabbedPane.addTab(first.av.getViewName(), first);
813 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
816 public AlignViewport getViewport()
821 /* Set up intrinsic listeners for dynamically generated GUI bits. */
822 private void addServiceListeners()
824 final java.beans.PropertyChangeListener thisListener;
825 Desktop.instance.addJalviewPropertyChangeListener("services",
826 thisListener = new java.beans.PropertyChangeListener()
829 public void propertyChange(PropertyChangeEvent evt)
831 // // System.out.println("Discoverer property change.");
832 // if (evt.getPropertyName().equals("services"))
834 SwingUtilities.invokeLater(new Runnable()
841 "Rebuild WS Menu for service change");
842 BuildWebServiceMenu();
849 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
852 public void internalFrameClosed(
853 javax.swing.event.InternalFrameEvent evt)
855 // System.out.println("deregistering discoverer listener");
856 Desktop.instance.removeJalviewPropertyChangeListener("services",
858 closeMenuItem_actionPerformed(true);
861 // Finally, build the menu once to get current service state
862 new Thread(new Runnable()
867 BuildWebServiceMenu();
873 * Configure menu items that vary according to whether the alignment is
874 * nucleotide or protein
876 public void setGUINucleotide()
878 AlignmentI al = getViewport().getAlignment();
879 boolean nucleotide = al.isNucleotide();
881 loadVcf.setVisible(nucleotide);
882 showTranslation.setVisible(nucleotide);
883 showReverse.setVisible(nucleotide);
884 showReverseComplement.setVisible(nucleotide);
885 conservationMenuItem.setEnabled(!nucleotide);
887 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
888 showGroupConservation.setEnabled(!nucleotide);
890 showComplementMenuItem
891 .setText(nucleotide ? MessageManager.getString("label.protein")
892 : MessageManager.getString("label.nucleotide"));
896 * set up menus for the current viewport. This may be called after any
897 * operation that affects the data in the current view (selection changed,
898 * etc) to update the menus to reflect the new state.
901 public void setMenusForViewport()
903 setMenusFromViewport(viewport);
907 * Need to call this method when tabs are selected for multiple views, or when
908 * loading from Jalview2XML.java
913 public void setMenusFromViewport(AlignViewport av)
915 padGapsMenuitem.setSelected(av.isPadGaps());
916 colourTextMenuItem.setSelected(av.isShowColourText());
917 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
918 modifyPID.setEnabled(abovePIDThreshold.isSelected());
919 conservationMenuItem.setSelected(av.getConservationSelected());
920 modifyConservation.setEnabled(conservationMenuItem.isSelected());
921 seqLimits.setSelected(av.getShowJVSuffix());
922 idRightAlign.setSelected(av.isRightAlignIds());
923 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
924 renderGapsMenuItem.setSelected(av.isRenderGaps());
925 wrapMenuItem.setSelected(av.getWrapAlignment());
926 scaleAbove.setVisible(av.getWrapAlignment());
927 scaleLeft.setVisible(av.getWrapAlignment());
928 scaleRight.setVisible(av.getWrapAlignment());
929 annotationPanelMenuItem.setState(av.isShowAnnotation());
931 * Show/hide annotations only enabled if annotation panel is shown
933 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
934 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
935 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
936 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 viewBoxesMenuItem.setSelected(av.getShowBoxes());
938 viewTextMenuItem.setSelected(av.getShowText());
939 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
940 showGroupConsensus.setSelected(av.isShowGroupConsensus());
941 showGroupConservation.setSelected(av.isShowGroupConservation());
942 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
943 showSequenceLogo.setSelected(av.isShowSequenceLogo());
944 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
946 ColourMenuHelper.setColourSelected(colourMenu,
947 av.getGlobalColourScheme());
949 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
950 hiddenMarkers.setState(av.getShowHiddenMarkers());
951 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
952 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
953 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
954 autoCalculate.setSelected(av.autoCalculateConsensus);
955 sortByTree.setSelected(av.sortByTree);
956 listenToViewSelections.setSelected(av.followSelection);
958 showProducts.setEnabled(canShowProducts());
959 setGroovyEnabled(Desktop.getGroovyConsole() != null);
965 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
969 public void setGroovyEnabled(boolean b)
971 runGroovy.setEnabled(b);
974 private IProgressIndicator progressBar;
979 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
982 public void setProgressBar(String message, long id)
984 if (!Platform.isHeadless())
985 progressBar.setProgressBar(message, id);
989 public void registerHandler(final long id,
990 final IProgressIndicatorHandler handler)
992 progressBar.registerHandler(id, handler);
997 * @return true if any progress bars are still active
1000 public boolean operationInProgress()
1002 return progressBar.operationInProgress();
1006 * Sets the text of the status bar. Note that setting a null or empty value
1007 * will cause the status bar to be hidden, with possibly undesirable flicker
1008 * of the screen layout.
1011 public void setStatus(String text)
1013 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1017 * Added so Castor Mapping file can obtain Jalview Version
1019 public String getVersion()
1021 return Cache.getProperty("VERSION");
1024 public FeatureRenderer getFeatureRenderer()
1026 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1030 public void fetchSequence_actionPerformed()
1032 new SequenceFetcher(this);
1036 public void addFromFile_actionPerformed(ActionEvent e)
1038 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1042 public void reload_actionPerformed(ActionEvent e)
1044 if (fileName != null)
1046 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1047 // originating file's format
1048 // TODO: work out how to recover feature settings for correct view(s) when
1049 // file is reloaded.
1050 if (FileFormat.Jalview.equals(currentFileFormat))
1052 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1053 for (int i = 0; i < frames.length; i++)
1055 if (frames[i] instanceof AlignFrame && frames[i] != this
1056 && ((AlignFrame) frames[i]).fileName != null
1057 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1061 frames[i].setSelected(true);
1062 Desktop.instance.closeAssociatedWindows();
1063 } catch (java.beans.PropertyVetoException ex)
1069 Desktop.instance.closeAssociatedWindows();
1071 FileLoader loader = new FileLoader();
1072 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1073 ? DataSourceType.URL
1074 : DataSourceType.FILE;
1075 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1079 Rectangle bounds = this.getBounds();
1081 FileLoader loader = new FileLoader();
1083 AlignFrame newframe = null;
1085 if (fileObject == null)
1088 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1089 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1090 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1095 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1096 DataSourceType.FILE, currentFileFormat);
1099 newframe.setBounds(bounds);
1100 if (featureSettings != null && featureSettings.isShowing())
1102 final Rectangle fspos = featureSettings.frame.getBounds();
1103 // TODO: need a 'show feature settings' function that takes bounds -
1104 // need to refactor Desktop.addFrame
1105 newframe.featureSettings_actionPerformed(null);
1106 final FeatureSettings nfs = newframe.featureSettings;
1107 SwingUtilities.invokeLater(new Runnable()
1112 nfs.frame.setBounds(fspos);
1115 this.featureSettings.close();
1116 this.featureSettings = null;
1118 this.closeMenuItem_actionPerformed(true);
1124 public void addFromText_actionPerformed(ActionEvent e)
1127 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1131 public void addFromURL_actionPerformed(ActionEvent e)
1133 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1137 public void save_actionPerformed(ActionEvent e)
1139 if (fileName == null || (currentFileFormat == null)
1140 || HttpUtils.startsWithHttpOrHttps(fileName))
1142 saveAs_actionPerformed();
1146 saveAlignment(fileName, currentFileFormat);
1151 * Saves the alignment to a file with a name chosen by the user, if necessary
1152 * warning if a file would be overwritten
1155 public void saveAs_actionPerformed()
1157 String format = currentFileFormat == null ? null
1158 : currentFileFormat.getName();
1159 JalviewFileChooser chooser = JalviewFileChooser
1160 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1162 chooser.setFileView(new JalviewFileView());
1163 chooser.setDialogTitle(
1164 MessageManager.getString("label.save_alignment_to_file"));
1165 chooser.setToolTipText(MessageManager.getString("action.save"));
1167 int value = chooser.showSaveDialog(this);
1169 if (value != JalviewFileChooser.APPROVE_OPTION)
1173 currentFileFormat = chooser.getSelectedFormat();
1174 // todo is this (2005) test now obsolete - value is never null?
1175 while (currentFileFormat == null)
1177 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1179 .getString("label.select_file_format_before_saving"),
1180 MessageManager.getString("label.file_format_not_specified"),
1181 JvOptionPane.WARNING_MESSAGE);
1182 currentFileFormat = chooser.getSelectedFormat();
1183 value = chooser.showSaveDialog(this);
1184 if (value != JalviewFileChooser.APPROVE_OPTION)
1190 fileName = chooser.getSelectedFile().getPath();
1192 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1193 Cache.setProperty("LAST_DIRECTORY", fileName);
1194 saveAlignment(fileName, currentFileFormat);
1197 boolean lastSaveSuccessful = false;
1199 FileFormatI lastFormatSaved;
1201 String lastFilenameSaved;
1204 * Raise a dialog or status message for the last call to saveAlignment.
1206 * @return true if last call to saveAlignment(file, format) was successful.
1208 public boolean isSaveAlignmentSuccessful()
1211 if (!lastSaveSuccessful)
1213 if (!Platform.isHeadless())
1215 JvOptionPane.showInternalMessageDialog(this, MessageManager
1216 .formatMessage("label.couldnt_save_file", new Object[]
1217 { lastFilenameSaved }),
1218 MessageManager.getString("label.error_saving_file"),
1219 JvOptionPane.WARNING_MESSAGE);
1223 Console.error(MessageManager
1224 .formatMessage("label.couldnt_save_file", new Object[]
1225 { lastFilenameSaved }));
1231 setStatus(MessageManager.formatMessage(
1232 "label.successfully_saved_to_file_in_format", new Object[]
1233 { lastFilenameSaved, lastFormatSaved }));
1236 return lastSaveSuccessful;
1240 * Saves the alignment to the specified file path, in the specified format,
1241 * which may be an alignment format, or Jalview project format. If the
1242 * alignment has hidden regions, or the format is one capable of including
1243 * non-sequence data (features, annotations, groups), then the user may be
1244 * prompted to specify what to include in the output.
1249 public void saveAlignment(String file, FileFormatI format)
1251 lastSaveSuccessful = true;
1252 lastFilenameSaved = file;
1253 lastFormatSaved = format;
1255 if (FileFormat.Jalview.equals(format))
1257 String shortName = title;
1258 if (shortName.indexOf(File.separatorChar) > -1)
1260 shortName = shortName
1261 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1263 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1266 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1267 if (lastSaveSuccessful)
1269 this.getViewport().setSavedUpToDate(true);
1272 statusBar.setText(MessageManager.formatMessage(
1273 "label.successfully_saved_to_file_in_format", new Object[]
1279 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1280 Callable<Void> cancelAction = () -> {
1281 lastSaveSuccessful = false;
1284 Callable<Void> outputAction = () -> {
1285 // todo defer this to inside formatSequences (or later)
1286 AlignmentExportData exportData = viewport.getAlignExportData(options);
1287 String output = new FormatAdapter(alignPanel, options)
1288 .formatSequences(format, exportData.getAlignment(),
1289 exportData.getOmitHidden(),
1290 exportData.getStartEndPostions(),
1291 viewport.getAlignment().getHiddenColumns());
1294 lastSaveSuccessful = false;
1298 // create backupfiles object and get new temp filename destination
1299 boolean doBackup = BackupFiles.getEnabled();
1300 BackupFiles backupfiles = null;
1303 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1304 backupfiles = new BackupFiles(file);
1308 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1310 Console.trace("ALIGNFRAME setting PrintWriter");
1311 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1313 if (backupfiles != null)
1315 Console.trace("ALIGNFRAME about to write to temp file "
1316 + backupfiles.getTempFilePath());
1320 Console.trace("ALIGNFRAME about to close file");
1322 Console.trace("ALIGNFRAME closed file");
1323 AlignFrame.this.setTitle(file);
1324 statusBar.setText(MessageManager.formatMessage(
1325 "label.successfully_saved_to_file_in_format", new Object[]
1326 { fileName, format.getName() }));
1327 lastSaveSuccessful = true;
1328 } catch (IOException e)
1330 lastSaveSuccessful = false;
1332 "ALIGNFRAME Something happened writing the temp file");
1333 Console.error(e.getMessage());
1334 Console.debug(Cache.getStackTraceString(e));
1335 } catch (Exception ex)
1337 lastSaveSuccessful = false;
1339 "ALIGNFRAME Something unexpected happened writing the temp file");
1340 Console.error(ex.getMessage());
1341 Console.debug(Cache.getStackTraceString(ex));
1346 backupfiles.setWriteSuccess(lastSaveSuccessful);
1347 Console.debug("ALIGNFRAME writing temp file was "
1348 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1349 // do the backup file roll and rename the temp file to actual file
1350 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1351 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1352 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1353 + (lastSaveSuccessful ? "" : "un") + "successfully");
1356 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1357 if (lastSaveSuccessful)
1359 AlignFrame.this.getViewport().setSavedUpToDate(true);
1366 * show dialog with export options if applicable; else just do it
1368 if (AlignExportOptions.isNeeded(viewport, format))
1370 AlignExportOptions choices = new AlignExportOptions(
1371 alignPanel.getAlignViewport(), format, options);
1372 choices.setResponseAction(0, outputAction);
1373 choices.setResponseAction(1, cancelAction);
1374 choices.showDialog();
1380 outputAction.call();
1381 } catch (Exception e)
1383 // TODO Auto-generated catch block
1384 e.printStackTrace();
1390 * Outputs the alignment to textbox in the requested format, if necessary
1391 * first prompting the user for whether to include hidden regions or
1394 * @param fileFormatName
1397 protected void outputText_actionPerformed(String fileFormatName)
1399 FileFormatI fileFormat = FileFormats.getInstance()
1400 .forName(fileFormatName);
1401 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1402 Callable<Void> outputAction = () -> {
1403 // todo defer this to inside formatSequences (or later)
1404 AlignmentExportData exportData = viewport.getAlignExportData(options);
1405 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1406 cap.setForInput(null);
1409 FileFormatI format = fileFormat;
1410 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1411 format, exportData.getAlignment(),
1412 exportData.getOmitHidden(),
1413 exportData.getStartEndPostions(),
1414 viewport.getAlignment().getHiddenColumns()));
1415 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1416 "label.alignment_output_command", new Object[]
1417 { fileFormat.getName() }), 600, 500);
1418 } catch (OutOfMemoryError oom)
1420 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
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();
1441 outputAction.call();
1442 } catch (Exception e)
1444 e.printStackTrace();
1456 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1458 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1459 htmlSVG.exportHTML(null);
1463 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1465 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1466 bjs.exportHTML(null);
1469 public void createImageMap(File file, String image)
1471 alignPanel.makePNGImageMap(file, image);
1475 * Creates a PNG image of the alignment and writes it to the given file. If
1476 * the file is null, the user is prompted to choose a file.
1481 public void createPNG(File f)
1486 public void createPNG(File f, String renderer)
1488 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer);
1492 * Creates an EPS image of the alignment and writes it to the given file. If
1493 * the file is null, the user is prompted to choose a file.
1498 public void createEPS(File f)
1503 public void createEPS(File f, String renderer)
1505 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1509 * Creates an SVG image of the alignment and writes it to the given file. If
1510 * the file is null, the user is prompted to choose a file.
1515 public void createSVG(File f)
1520 public void createSVG(File f, String renderer)
1522 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1526 public void pageSetup_actionPerformed(ActionEvent e)
1528 PrinterJob printJob = PrinterJob.getPrinterJob();
1529 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1539 public void printMenuItem_actionPerformed(ActionEvent e)
1541 // Putting in a thread avoids Swing painting problems
1542 PrintThread thread = new PrintThread(alignPanel);
1547 public void exportFeatures_actionPerformed(ActionEvent e)
1549 new AnnotationExporter(alignPanel).exportFeatures();
1553 public void exportAnnotations_actionPerformed(ActionEvent e)
1555 new AnnotationExporter(alignPanel).exportAnnotations();
1559 public void associatedData_actionPerformed(ActionEvent e)
1561 final JalviewFileChooser chooser = new JalviewFileChooser(
1562 Cache.getProperty("LAST_DIRECTORY"));
1563 chooser.setFileView(new JalviewFileView());
1564 String tooltip = MessageManager
1565 .getString("label.load_jalview_annotations");
1566 chooser.setDialogTitle(tooltip);
1567 chooser.setToolTipText(tooltip);
1568 chooser.setResponseHandler(0, () -> {
1569 String choice = chooser.getSelectedFile().getPath();
1570 Cache.setProperty("LAST_DIRECTORY", choice);
1571 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1575 chooser.showOpenDialog(this);
1579 * Close the current view or all views in the alignment frame. If the frame
1580 * only contains one view then the alignment will be removed from memory.
1582 * @param closeAllTabs
1585 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1587 if (alignPanels != null && alignPanels.size() < 2)
1589 closeAllTabs = true;
1594 if (alignPanels != null)
1598 if (this.isClosed())
1600 // really close all the windows - otherwise wait till
1601 // setClosed(true) is called
1602 for (int i = 0; i < alignPanels.size(); i++)
1604 AlignmentPanel ap = alignPanels.get(i);
1611 closeView(alignPanel);
1616 if (featureSettings != null && featureSettings.isOpen())
1618 featureSettings.close();
1619 featureSettings = null;
1622 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1623 * be called recursively, with the frame now in 'closed' state
1625 this.setClosed(true);
1627 } catch (Exception ex)
1629 ex.printStackTrace();
1634 * Close the specified panel and close up tabs appropriately.
1636 * @param panelToClose
1638 public void closeView(AlignmentPanel panelToClose)
1640 int index = tabbedPane.getSelectedIndex();
1641 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1642 alignPanels.remove(panelToClose);
1643 panelToClose.closePanel();
1644 panelToClose = null;
1646 tabbedPane.removeTabAt(closedindex);
1647 tabbedPane.validate();
1649 if (index > closedindex || index == tabbedPane.getTabCount())
1651 // modify currently selected tab index if necessary.
1655 this.tabSelectionChanged(index);
1661 void updateEditMenuBar()
1664 if (viewport.getHistoryList().size() > 0)
1666 undoMenuItem.setEnabled(true);
1667 CommandI command = viewport.getHistoryList().peek();
1668 undoMenuItem.setText(MessageManager
1669 .formatMessage("label.undo_command", new Object[]
1670 { command.getDescription() }));
1674 undoMenuItem.setEnabled(false);
1675 undoMenuItem.setText(MessageManager.getString("action.undo"));
1678 if (viewport.getRedoList().size() > 0)
1680 redoMenuItem.setEnabled(true);
1682 CommandI command = viewport.getRedoList().peek();
1683 redoMenuItem.setText(MessageManager
1684 .formatMessage("label.redo_command", new Object[]
1685 { command.getDescription() }));
1689 redoMenuItem.setEnabled(false);
1690 redoMenuItem.setText(MessageManager.getString("action.redo"));
1695 public void addHistoryItem(CommandI command)
1697 if (command.getSize() > 0)
1699 viewport.addToHistoryList(command);
1700 viewport.clearRedoList();
1701 updateEditMenuBar();
1702 viewport.updateHiddenColumns();
1703 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1704 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1705 // viewport.getColumnSelection()
1706 // .getHiddenColumns().size() > 0);
1712 * @return alignment objects for all views
1714 AlignmentI[] getViewAlignments()
1716 if (alignPanels != null)
1718 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1720 for (AlignmentPanel ap : alignPanels)
1722 als[i++] = ap.av.getAlignment();
1726 if (viewport != null)
1728 return new AlignmentI[] { viewport.getAlignment() };
1740 protected void undoMenuItem_actionPerformed(ActionEvent e)
1742 if (viewport.getHistoryList().isEmpty())
1746 CommandI command = viewport.getHistoryList().pop();
1747 viewport.addToRedoList(command);
1748 command.undoCommand(getViewAlignments());
1750 AlignmentViewport originalSource = getOriginatingSource(command);
1751 updateEditMenuBar();
1753 if (originalSource != null)
1755 if (originalSource != viewport)
1758 "Implementation worry: mismatch of viewport origin for undo");
1760 originalSource.updateHiddenColumns();
1761 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1763 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1764 // viewport.getColumnSelection()
1765 // .getHiddenColumns().size() > 0);
1766 originalSource.firePropertyChange("alignment", null,
1767 originalSource.getAlignment().getSequences());
1778 protected void redoMenuItem_actionPerformed(ActionEvent e)
1780 if (viewport.getRedoList().size() < 1)
1785 CommandI command = viewport.getRedoList().pop();
1786 viewport.addToHistoryList(command);
1787 command.doCommand(getViewAlignments());
1789 AlignmentViewport originalSource = getOriginatingSource(command);
1790 updateEditMenuBar();
1792 if (originalSource != null)
1795 if (originalSource != viewport)
1798 "Implementation worry: mismatch of viewport origin for redo");
1800 originalSource.updateHiddenColumns();
1801 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1803 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1804 // viewport.getColumnSelection()
1805 // .getHiddenColumns().size() > 0);
1806 originalSource.firePropertyChange("alignment", null,
1807 originalSource.getAlignment().getSequences());
1811 AlignmentViewport getOriginatingSource(CommandI command)
1813 AlignmentViewport originalSource = null;
1814 // For sequence removal and addition, we need to fire
1815 // the property change event FROM the viewport where the
1816 // original alignment was altered
1817 AlignmentI al = null;
1818 if (command instanceof EditCommand)
1820 EditCommand editCommand = (EditCommand) command;
1821 al = editCommand.getAlignment();
1822 List<Component> comps = PaintRefresher.components
1823 .get(viewport.getSequenceSetId());
1825 for (Component comp : comps)
1827 if (comp instanceof AlignmentPanel)
1829 if (al == ((AlignmentPanel) comp).av.getAlignment())
1831 originalSource = ((AlignmentPanel) comp).av;
1838 if (originalSource == null)
1840 // The original view is closed, we must validate
1841 // the current view against the closed view first
1844 PaintRefresher.validateSequences(al, viewport.getAlignment());
1847 originalSource = viewport;
1850 return originalSource;
1854 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1855 * or the sequence under cursor in keyboard mode
1860 public void moveSelectedSequences(boolean up)
1862 SequenceGroup sg = viewport.getSelectionGroup();
1866 if (viewport.cursorMode)
1868 sg = new SequenceGroup();
1869 sg.addSequence(viewport.getAlignment().getSequenceAt(
1870 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1878 if (sg.getSize() < 1)
1883 // TODO: JAL-3733 - add an event to the undo buffer for this !
1885 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1886 viewport.getHiddenRepSequences(), up);
1887 alignPanel.paintAlignment(true, false);
1890 synchronized void slideSequences(boolean right, int size)
1892 List<SequenceI> sg = new ArrayList<>();
1893 if (viewport.cursorMode)
1895 sg.add(viewport.getAlignment()
1896 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1898 else if (viewport.getSelectionGroup() != null
1899 && viewport.getSelectionGroup().getSize() != viewport
1900 .getAlignment().getHeight())
1902 sg = viewport.getSelectionGroup()
1903 .getSequences(viewport.getHiddenRepSequences());
1911 List<SequenceI> invertGroup = new ArrayList<>();
1913 for (SequenceI seq : viewport.getAlignment().getSequences())
1915 if (!sg.contains(seq))
1917 invertGroup.add(seq);
1921 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1923 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1924 for (int i = 0; i < invertGroup.size(); i++)
1926 seqs2[i] = invertGroup.get(i);
1929 SlideSequencesCommand ssc;
1932 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1933 viewport.getGapCharacter());
1937 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1938 viewport.getGapCharacter());
1941 int groupAdjustment = 0;
1942 if (ssc.getGapsInsertedBegin() && right)
1944 if (viewport.cursorMode)
1946 alignPanel.getSeqPanel().moveCursor(size, 0);
1950 groupAdjustment = size;
1953 else if (!ssc.getGapsInsertedBegin() && !right)
1955 if (viewport.cursorMode)
1957 alignPanel.getSeqPanel().moveCursor(-size, 0);
1961 groupAdjustment = -size;
1965 if (groupAdjustment != 0)
1967 viewport.getSelectionGroup().setStartRes(
1968 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1969 viewport.getSelectionGroup().setEndRes(
1970 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1974 * just extend the last slide command if compatible; but not if in
1975 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1977 boolean appendHistoryItem = false;
1978 Deque<CommandI> historyList = viewport.getHistoryList();
1979 boolean inSplitFrame = getSplitViewContainer() != null;
1980 if (!inSplitFrame && historyList != null && historyList.size() > 0
1981 && historyList.peek() instanceof SlideSequencesCommand)
1983 appendHistoryItem = ssc.appendSlideCommand(
1984 (SlideSequencesCommand) historyList.peek());
1987 if (!appendHistoryItem)
1989 addHistoryItem(ssc);
2002 protected void copy_actionPerformed()
2004 if (viewport.getSelectionGroup() == null)
2008 // TODO: preserve the ordering of displayed alignment annotation in any
2009 // internal paste (particularly sequence associated annotation)
2010 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2011 String[] omitHidden = null;
2013 if (viewport.hasHiddenColumns())
2015 omitHidden = viewport.getViewAsString(true);
2018 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2019 seqs, omitHidden, null);
2021 StringSelection ss = new StringSelection(output);
2025 jalview.gui.Desktop.internalCopy = true;
2026 // Its really worth setting the clipboard contents
2027 // to empty before setting the large StringSelection!!
2028 Toolkit.getDefaultToolkit().getSystemClipboard()
2029 .setContents(new StringSelection(""), null);
2031 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2033 } catch (OutOfMemoryError er)
2035 new OOMWarning("copying region", er);
2039 HiddenColumns hiddenColumns = null;
2040 if (viewport.hasHiddenColumns())
2042 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2043 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2045 // create new HiddenColumns object with copy of hidden regions
2046 // between startRes and endRes, offset by startRes
2047 hiddenColumns = new HiddenColumns(
2048 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2049 hiddenCutoff, hiddenOffset);
2052 Desktop.jalviewClipboard = new Object[] { seqs,
2053 viewport.getAlignment().getDataset(), hiddenColumns };
2054 setStatus(MessageManager.formatMessage(
2055 "label.copied_sequences_to_clipboard", new Object[]
2056 { Integer.valueOf(seqs.length).toString() }));
2066 protected void pasteNew_actionPerformed(ActionEvent e)
2078 protected void pasteThis_actionPerformed(ActionEvent e)
2084 * Paste contents of Jalview clipboard
2086 * @param newAlignment
2087 * true to paste to a new alignment, otherwise add to this.
2089 void paste(boolean newAlignment)
2091 boolean externalPaste = true;
2094 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2095 Transferable contents = c.getContents(this);
2097 if (contents == null)
2106 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2107 if (str.length() < 1)
2112 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2114 } catch (OutOfMemoryError er)
2116 new OOMWarning("Out of memory pasting sequences!!", er);
2120 SequenceI[] sequences;
2121 boolean annotationAdded = false;
2122 AlignmentI alignment = null;
2124 if (Desktop.jalviewClipboard != null)
2126 // The clipboard was filled from within Jalview, we must use the
2128 // And dataset from the copied alignment
2129 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2130 // be doubly sure that we create *new* sequence objects.
2131 sequences = new SequenceI[newseq.length];
2132 for (int i = 0; i < newseq.length; i++)
2134 sequences[i] = new Sequence(newseq[i]);
2136 alignment = new Alignment(sequences);
2137 externalPaste = false;
2141 // parse the clipboard as an alignment.
2142 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2144 sequences = alignment.getSequencesArray();
2148 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2154 if (Desktop.jalviewClipboard != null)
2156 // dataset is inherited
2157 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2161 // new dataset is constructed
2162 alignment.setDataset(null);
2164 alwidth = alignment.getWidth() + 1;
2168 AlignmentI pastedal = alignment; // preserve pasted alignment object
2169 // Add pasted sequences and dataset into existing alignment.
2170 alignment = viewport.getAlignment();
2171 alwidth = alignment.getWidth() + 1;
2172 // decide if we need to import sequences from an existing dataset
2173 boolean importDs = Desktop.jalviewClipboard != null
2174 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2175 // importDs==true instructs us to copy over new dataset sequences from
2176 // an existing alignment
2177 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2179 // minimum dataset set
2181 for (int i = 0; i < sequences.length; i++)
2185 newDs.addElement(null);
2187 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2189 if (importDs && ds != null)
2191 if (!newDs.contains(ds))
2193 newDs.setElementAt(ds, i);
2194 ds = new Sequence(ds);
2195 // update with new dataset sequence
2196 sequences[i].setDatasetSequence(ds);
2200 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2205 // copy and derive new dataset sequence
2206 sequences[i] = sequences[i].deriveSequence();
2207 alignment.getDataset()
2208 .addSequence(sequences[i].getDatasetSequence());
2209 // TODO: avoid creation of duplicate dataset sequences with a
2210 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2212 alignment.addSequence(sequences[i]); // merges dataset
2216 newDs.clear(); // tidy up
2218 if (alignment.getAlignmentAnnotation() != null)
2220 for (AlignmentAnnotation alan : alignment
2221 .getAlignmentAnnotation())
2223 if (alan.graphGroup > fgroup)
2225 fgroup = alan.graphGroup;
2229 if (pastedal.getAlignmentAnnotation() != null)
2231 // Add any annotation attached to alignment.
2232 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2233 for (int i = 0; i < alann.length; i++)
2235 annotationAdded = true;
2236 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2238 AlignmentAnnotation newann = new AlignmentAnnotation(
2240 if (newann.graphGroup > -1)
2242 if (newGraphGroups.size() <= newann.graphGroup
2243 || newGraphGroups.get(newann.graphGroup) == null)
2245 for (int q = newGraphGroups
2246 .size(); q <= newann.graphGroup; q++)
2248 newGraphGroups.add(q, null);
2250 newGraphGroups.set(newann.graphGroup,
2251 Integer.valueOf(++fgroup));
2253 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2257 newann.padAnnotation(alwidth);
2258 alignment.addAnnotation(newann);
2268 addHistoryItem(new EditCommand(
2269 MessageManager.getString("label.add_sequences"),
2270 Action.PASTE, sequences, 0, alignment.getWidth(),
2273 // Add any annotations attached to sequences
2274 for (int i = 0; i < sequences.length; i++)
2276 if (sequences[i].getAnnotation() != null)
2278 AlignmentAnnotation newann;
2279 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2281 annotationAdded = true;
2282 newann = sequences[i].getAnnotation()[a];
2283 newann.adjustForAlignment();
2284 newann.padAnnotation(alwidth);
2285 if (newann.graphGroup > -1)
2287 if (newann.graphGroup > -1)
2289 if (newGraphGroups.size() <= newann.graphGroup
2290 || newGraphGroups.get(newann.graphGroup) == null)
2292 for (int q = newGraphGroups
2293 .size(); q <= newann.graphGroup; q++)
2295 newGraphGroups.add(q, null);
2297 newGraphGroups.set(newann.graphGroup,
2298 Integer.valueOf(++fgroup));
2300 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2304 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
2308 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2316 // propagate alignment changed.
2317 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2318 if (annotationAdded)
2320 // Duplicate sequence annotation in all views.
2321 AlignmentI[] alview = this.getViewAlignments();
2322 for (int i = 0; i < sequences.length; i++)
2324 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2329 for (int avnum = 0; avnum < alview.length; avnum++)
2331 if (alview[avnum] != alignment)
2333 // duplicate in a view other than the one with input focus
2334 int avwidth = alview[avnum].getWidth() + 1;
2335 // this relies on sann being preserved after we
2336 // modify the sequence's annotation array for each duplication
2337 for (int a = 0; a < sann.length; a++)
2339 AlignmentAnnotation newann = new AlignmentAnnotation(
2341 sequences[i].addAlignmentAnnotation(newann);
2342 newann.padAnnotation(avwidth);
2343 alview[avnum].addAnnotation(newann); // annotation was
2344 // duplicated earlier
2345 // TODO JAL-1145 graphGroups are not updated for sequence
2346 // annotation added to several views. This may cause
2348 alview[avnum].setAnnotationIndex(newann, a);
2353 buildSortByAnnotationScoresMenu();
2355 viewport.firePropertyChange("alignment", null,
2356 alignment.getSequences());
2357 if (alignPanels != null)
2359 for (AlignmentPanel ap : alignPanels)
2361 ap.validateAnnotationDimensions(false);
2366 alignPanel.validateAnnotationDimensions(false);
2372 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2374 String newtitle = new String("Copied sequences");
2376 if (Desktop.jalviewClipboard != null
2377 && Desktop.jalviewClipboard[2] != null)
2379 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2380 af.viewport.setHiddenColumns(hc);
2383 // >>>This is a fix for the moment, until a better solution is
2385 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2386 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2387 .getFeatureRenderer());
2389 // TODO: maintain provenance of an alignment, rather than just make the
2390 // title a concatenation of operations.
2393 if (title.startsWith("Copied sequences"))
2399 newtitle = newtitle.concat("- from " + title);
2404 newtitle = new String("Pasted sequences");
2407 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2412 } catch (Exception ex)
2414 ex.printStackTrace();
2415 System.out.println("Exception whilst pasting: " + ex);
2416 // could be anything being pasted in here
2422 protected void expand_newalign(ActionEvent e)
2426 AlignmentI alignment = AlignmentUtils
2427 .expandContext(getViewport().getAlignment(), -1);
2428 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2430 String newtitle = new String("Flanking alignment");
2432 if (Desktop.jalviewClipboard != null
2433 && Desktop.jalviewClipboard[2] != null)
2435 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2436 af.viewport.setHiddenColumns(hc);
2439 // >>>This is a fix for the moment, until a better solution is
2441 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2442 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2443 .getFeatureRenderer());
2445 // TODO: maintain provenance of an alignment, rather than just make the
2446 // title a concatenation of operations.
2448 if (title.startsWith("Copied sequences"))
2454 newtitle = newtitle.concat("- from " + title);
2458 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2460 } catch (Exception ex)
2462 ex.printStackTrace();
2463 System.out.println("Exception whilst pasting: " + ex);
2464 // could be anything being pasted in here
2465 } catch (OutOfMemoryError oom)
2467 new OOMWarning("Viewing flanking region of alignment", oom);
2472 * Action Cut (delete and copy) the selected region
2475 protected void cut_actionPerformed()
2477 copy_actionPerformed();
2478 delete_actionPerformed();
2482 * Performs menu option to Delete the currently selected region
2485 protected void delete_actionPerformed()
2488 SequenceGroup sg = viewport.getSelectionGroup();
2494 Callable okAction = () -> {
2495 SequenceI[] cut = sg.getSequences()
2496 .toArray(new SequenceI[sg.getSize()]);
2498 addHistoryItem(new EditCommand(
2499 MessageManager.getString("label.cut_sequences"), Action.CUT,
2500 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2501 viewport.getAlignment()));
2503 viewport.setSelectionGroup(null);
2504 viewport.sendSelection();
2505 viewport.getAlignment().deleteGroup(sg);
2507 viewport.firePropertyChange("alignment", null,
2508 viewport.getAlignment().getSequences());
2509 if (viewport.getAlignment().getHeight() < 1)
2513 AlignFrame.this.setClosed(true);
2514 } catch (Exception ex)
2522 * If the cut affects all sequences, prompt for confirmation
2524 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2526 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2527 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2528 if (wholeHeight && wholeWidth)
2530 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2531 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2532 Object[] options = new Object[] {
2533 MessageManager.getString("action.ok"),
2534 MessageManager.getString("action.cancel") };
2535 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2536 MessageManager.getString("label.delete_all"),
2537 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2538 options, options[0]);
2545 } catch (Exception e)
2547 e.printStackTrace();
2559 protected void deleteGroups_actionPerformed(ActionEvent e)
2561 if (avc.deleteGroups())
2563 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2564 alignPanel.updateAnnotation();
2565 alignPanel.paintAlignment(true, true);
2576 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2578 SequenceGroup sg = new SequenceGroup(
2579 viewport.getAlignment().getSequences());
2581 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2582 viewport.setSelectionGroup(sg);
2583 viewport.isSelectionGroupChanged(true);
2584 viewport.sendSelection();
2585 // JAL-2034 - should delegate to
2586 // alignPanel to decide if overview needs
2588 alignPanel.paintAlignment(false, false);
2589 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2599 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2601 if (viewport.cursorMode)
2603 alignPanel.getSeqPanel().keyboardNo1 = null;
2604 alignPanel.getSeqPanel().keyboardNo2 = null;
2606 viewport.setSelectionGroup(null);
2607 viewport.getColumnSelection().clear();
2608 viewport.setSearchResults(null);
2609 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2610 // JAL-2034 - should delegate to
2611 // alignPanel to decide if overview needs
2613 alignPanel.paintAlignment(false, false);
2614 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2615 viewport.sendSelection();
2625 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2627 SequenceGroup sg = viewport.getSelectionGroup();
2631 selectAllSequenceMenuItem_actionPerformed(null);
2636 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2638 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2640 // JAL-2034 - should delegate to
2641 // alignPanel to decide if overview needs
2644 alignPanel.paintAlignment(true, false);
2645 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2646 viewport.sendSelection();
2650 public void invertColSel_actionPerformed(ActionEvent e)
2652 viewport.invertColumnSelection();
2653 alignPanel.paintAlignment(true, false);
2654 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2655 viewport.sendSelection();
2665 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2667 trimAlignment(true);
2677 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2679 trimAlignment(false);
2682 void trimAlignment(boolean trimLeft)
2684 ColumnSelection colSel = viewport.getColumnSelection();
2687 if (!colSel.isEmpty())
2691 column = colSel.getMin();
2695 column = colSel.getMax();
2699 if (viewport.getSelectionGroup() != null)
2701 seqs = viewport.getSelectionGroup()
2702 .getSequencesAsArray(viewport.getHiddenRepSequences());
2706 seqs = viewport.getAlignment().getSequencesArray();
2709 TrimRegionCommand trimRegion;
2712 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2713 column, viewport.getAlignment());
2714 viewport.getRanges().setStartRes(0);
2718 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2719 column, viewport.getAlignment());
2722 setStatus(MessageManager.formatMessage("label.removed_columns",
2724 { Integer.valueOf(trimRegion.getSize()).toString() }));
2726 addHistoryItem(trimRegion);
2728 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2730 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2731 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2733 viewport.getAlignment().deleteGroup(sg);
2737 viewport.firePropertyChange("alignment", null,
2738 viewport.getAlignment().getSequences());
2749 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2751 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2754 if (viewport.getSelectionGroup() != null)
2756 seqs = viewport.getSelectionGroup()
2757 .getSequencesAsArray(viewport.getHiddenRepSequences());
2758 start = viewport.getSelectionGroup().getStartRes();
2759 end = viewport.getSelectionGroup().getEndRes();
2763 seqs = viewport.getAlignment().getSequencesArray();
2766 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2767 "Remove Gapped Columns", seqs, start, end,
2768 viewport.getAlignment());
2770 addHistoryItem(removeGapCols);
2772 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2774 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2776 // This is to maintain viewport position on first residue
2777 // of first sequence
2778 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2779 ViewportRanges ranges = viewport.getRanges();
2780 int startRes = seq.findPosition(ranges.getStartRes());
2781 // ShiftList shifts;
2782 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2783 // edit.alColumnChanges=shifts.getInverse();
2784 // if (viewport.hasHiddenColumns)
2785 // viewport.getColumnSelection().compensateForEdits(shifts);
2786 ranges.setStartRes(seq.findIndex(startRes) - 1);
2787 viewport.firePropertyChange("alignment", null,
2788 viewport.getAlignment().getSequences());
2799 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2801 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2804 if (viewport.getSelectionGroup() != null)
2806 seqs = viewport.getSelectionGroup()
2807 .getSequencesAsArray(viewport.getHiddenRepSequences());
2808 start = viewport.getSelectionGroup().getStartRes();
2809 end = viewport.getSelectionGroup().getEndRes();
2813 seqs = viewport.getAlignment().getSequencesArray();
2816 // This is to maintain viewport position on first residue
2817 // of first sequence
2818 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2819 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2821 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2822 viewport.getAlignment()));
2824 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2826 viewport.firePropertyChange("alignment", null,
2827 viewport.getAlignment().getSequences());
2838 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2840 viewport.setPadGaps(padGapsMenuitem.isSelected());
2841 viewport.firePropertyChange("alignment", null,
2842 viewport.getAlignment().getSequences());
2846 * Opens a Finder dialog
2851 public void findMenuItem_actionPerformed(ActionEvent e)
2853 new Finder(alignPanel, false, null);
2857 * Create a new view of the current alignment.
2860 public void newView_actionPerformed(ActionEvent e)
2862 newView(null, true);
2866 * Creates and shows a new view of the current alignment.
2869 * title of newly created view; if null, one will be generated
2870 * @param copyAnnotation
2871 * if true then duplicate all annnotation, groups and settings
2872 * @return new alignment panel, already displayed.
2874 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2877 * Create a new AlignmentPanel (with its own, new Viewport)
2879 AlignmentPanel newap = new jalview.project.Jalview2XML()
2880 .copyAlignPanel(alignPanel);
2881 if (!copyAnnotation)
2884 * remove all groups and annotation except for the automatic stuff
2886 newap.av.getAlignment().deleteAllGroups();
2887 newap.av.getAlignment().deleteAllAnnotations(false);
2890 newap.av.setGatherViewsHere(false);
2892 if (viewport.getViewName() == null)
2894 viewport.setViewName(
2895 MessageManager.getString("label.view_name_original"));
2899 * Views share the same edits undo and redo stacks
2901 newap.av.setHistoryList(viewport.getHistoryList());
2902 newap.av.setRedoList(viewport.getRedoList());
2905 * copy any visualisation settings that are not saved in the project
2907 newap.av.setColourAppliesToAllGroups(
2908 viewport.getColourAppliesToAllGroups());
2911 * Views share the same mappings; need to deregister any new mappings
2912 * created by copyAlignPanel, and register the new reference to the shared
2915 newap.av.replaceMappings(viewport.getAlignment());
2918 * start up cDNA consensus (if applicable) now mappings are in place
2920 if (newap.av.initComplementConsensus())
2922 newap.refresh(true); // adjust layout of annotations
2925 newap.av.setViewName(getNewViewName(viewTitle));
2927 addAlignmentPanel(newap, true);
2928 newap.alignmentChanged();
2930 if (alignPanels.size() == 2)
2932 viewport.setGatherViewsHere(true);
2934 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2940 * Make a new name for the view, ensuring it is unique within the current
2941 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2942 * these now use viewId. Unique view names are still desirable for usability.)
2947 protected String getNewViewName(String viewTitle)
2949 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2950 boolean addFirstIndex = false;
2951 if (viewTitle == null || viewTitle.trim().length() == 0)
2953 viewTitle = MessageManager.getString("action.view");
2954 addFirstIndex = true;
2958 index = 1;// we count from 1 if given a specific name
2960 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2962 List<Component> comps = PaintRefresher.components
2963 .get(viewport.getSequenceSetId());
2965 List<String> existingNames = getExistingViewNames(comps);
2967 while (existingNames.contains(newViewName))
2969 newViewName = viewTitle + " " + (++index);
2975 * Returns a list of distinct view names found in the given list of
2976 * components. View names are held on the viewport of an AlignmentPanel.
2981 protected List<String> getExistingViewNames(List<Component> comps)
2983 List<String> existingNames = new ArrayList<>();
2984 for (Component comp : comps)
2986 if (comp instanceof AlignmentPanel)
2988 AlignmentPanel ap = (AlignmentPanel) comp;
2989 if (!existingNames.contains(ap.av.getViewName()))
2991 existingNames.add(ap.av.getViewName());
2995 return existingNames;
2999 * Explode tabbed views into separate windows.
3002 public void expandViews_actionPerformed(ActionEvent e)
3004 Desktop.explodeViews(this);
3008 * Gather views in separate windows back into a tabbed presentation.
3011 public void gatherViews_actionPerformed(ActionEvent e)
3013 Desktop.instance.gatherViews(this);
3023 public void font_actionPerformed(ActionEvent e)
3025 new FontChooser(alignPanel);
3035 protected void seqLimit_actionPerformed(ActionEvent e)
3037 viewport.setShowJVSuffix(seqLimits.isSelected());
3039 alignPanel.getIdPanel().getIdCanvas()
3040 .setPreferredSize(alignPanel.calculateIdWidth());
3041 alignPanel.paintAlignment(true, false);
3045 public void idRightAlign_actionPerformed(ActionEvent e)
3047 viewport.setRightAlignIds(idRightAlign.isSelected());
3048 alignPanel.paintAlignment(false, false);
3052 public void centreColumnLabels_actionPerformed(ActionEvent e)
3054 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3055 alignPanel.paintAlignment(false, false);
3061 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3064 protected void followHighlight_actionPerformed()
3067 * Set the 'follow' flag on the Viewport (and scroll to position if now
3070 final boolean state = this.followHighlightMenuItem.getState();
3071 viewport.setFollowHighlight(state);
3074 alignPanel.scrollToPosition(viewport.getSearchResults());
3085 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3087 viewport.setColourText(colourTextMenuItem.isSelected());
3088 alignPanel.paintAlignment(false, false);
3098 public void wrapMenuItem_actionPerformed(ActionEvent e)
3100 scaleAbove.setVisible(wrapMenuItem.isSelected());
3101 scaleLeft.setVisible(wrapMenuItem.isSelected());
3102 scaleRight.setVisible(wrapMenuItem.isSelected());
3103 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3104 alignPanel.updateLayout();
3108 public void showAllSeqs_actionPerformed(ActionEvent e)
3110 viewport.showAllHiddenSeqs();
3114 public void showAllColumns_actionPerformed(ActionEvent e)
3116 viewport.showAllHiddenColumns();
3117 alignPanel.paintAlignment(true, true);
3118 viewport.sendSelection();
3122 public void hideSelSequences_actionPerformed(ActionEvent e)
3124 viewport.hideAllSelectedSeqs();
3128 * called by key handler and the hide all/show all menu items
3133 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3136 boolean hide = false;
3137 SequenceGroup sg = viewport.getSelectionGroup();
3138 if (!toggleSeqs && !toggleCols)
3140 // Hide everything by the current selection - this is a hack - we do the
3141 // invert and then hide
3142 // first check that there will be visible columns after the invert.
3143 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3144 && sg.getStartRes() <= sg.getEndRes()))
3146 // now invert the sequence set, if required - empty selection implies
3147 // that no hiding is required.
3150 invertSequenceMenuItem_actionPerformed(null);
3151 sg = viewport.getSelectionGroup();
3155 viewport.expandColSelection(sg, true);
3156 // finally invert the column selection and get the new sequence
3158 invertColSel_actionPerformed(null);
3165 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3167 hideSelSequences_actionPerformed(null);
3170 else if (!(toggleCols && viewport.hasSelectedColumns()))
3172 showAllSeqs_actionPerformed(null);
3178 if (viewport.hasSelectedColumns())
3180 hideSelColumns_actionPerformed(null);
3183 viewport.setSelectionGroup(sg);
3188 showAllColumns_actionPerformed(null);
3197 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3198 * event.ActionEvent)
3201 public void hideAllButSelection_actionPerformed(ActionEvent e)
3203 toggleHiddenRegions(false, false);
3204 viewport.sendSelection();
3211 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3215 public void hideAllSelection_actionPerformed(ActionEvent e)
3217 SequenceGroup sg = viewport.getSelectionGroup();
3218 viewport.expandColSelection(sg, false);
3219 viewport.hideAllSelectedSeqs();
3220 viewport.hideSelectedColumns();
3221 alignPanel.updateLayout();
3222 alignPanel.paintAlignment(true, true);
3223 viewport.sendSelection();
3230 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3234 public void showAllhidden_actionPerformed(ActionEvent e)
3236 viewport.showAllHiddenColumns();
3237 viewport.showAllHiddenSeqs();
3238 alignPanel.paintAlignment(true, true);
3239 viewport.sendSelection();
3243 public void hideSelColumns_actionPerformed(ActionEvent e)
3245 viewport.hideSelectedColumns();
3246 alignPanel.updateLayout();
3247 alignPanel.paintAlignment(true, true);
3248 viewport.sendSelection();
3252 public void hiddenMarkers_actionPerformed(ActionEvent e)
3254 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3265 protected void scaleAbove_actionPerformed(ActionEvent e)
3267 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3268 alignPanel.updateLayout();
3269 alignPanel.paintAlignment(true, false);
3279 protected void scaleLeft_actionPerformed(ActionEvent e)
3281 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3282 alignPanel.updateLayout();
3283 alignPanel.paintAlignment(true, false);
3293 protected void scaleRight_actionPerformed(ActionEvent e)
3295 viewport.setScaleRightWrapped(scaleRight.isSelected());
3296 alignPanel.updateLayout();
3297 alignPanel.paintAlignment(true, false);
3307 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3309 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3310 alignPanel.paintAlignment(false, false);
3320 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3322 viewport.setShowText(viewTextMenuItem.isSelected());
3323 alignPanel.paintAlignment(false, false);
3333 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3335 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3336 alignPanel.paintAlignment(false, false);
3339 public FeatureSettings featureSettings;
3342 public FeatureSettingsControllerI getFeatureSettingsUI()
3344 return featureSettings;
3348 public void featureSettings_actionPerformed(ActionEvent e)
3350 showFeatureSettingsUI();
3354 public FeatureSettingsControllerI showFeatureSettingsUI()
3356 if (featureSettings != null)
3358 featureSettings.closeOldSettings();
3359 featureSettings = null;
3361 if (!showSeqFeatures.isSelected())
3363 // make sure features are actually displayed
3364 showSeqFeatures.setSelected(true);
3365 showSeqFeatures_actionPerformed(null);
3367 featureSettings = new FeatureSettings(this);
3368 return featureSettings;
3372 * Set or clear 'Show Sequence Features'
3378 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3380 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3381 alignPanel.paintAlignment(true, true);
3385 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3386 * the annotations panel as a whole.
3388 * The options to show/hide all annotations should be enabled when the panel
3389 * is shown, and disabled when the panel is hidden.
3394 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3396 final boolean setVisible = annotationPanelMenuItem.isSelected();
3397 viewport.setShowAnnotation(setVisible);
3398 this.showAllSeqAnnotations.setEnabled(setVisible);
3399 this.hideAllSeqAnnotations.setEnabled(setVisible);
3400 this.showAllAlAnnotations.setEnabled(setVisible);
3401 this.hideAllAlAnnotations.setEnabled(setVisible);
3402 alignPanel.updateLayout();
3406 public void alignmentProperties()
3409 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3412 String content = MessageManager.formatMessage("label.html_content",
3414 { contents.toString() });
3417 if (Platform.isJS())
3419 JLabel textLabel = new JLabel();
3420 textLabel.setText(content);
3421 textLabel.setBackground(Color.WHITE);
3423 pane = new JPanel(new BorderLayout());
3424 ((JPanel) pane).setOpaque(true);
3425 pane.setBackground(Color.WHITE);
3426 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3435 JEditorPane editPane = new JEditorPane("text/html", "");
3436 editPane.setEditable(false);
3437 editPane.setText(content);
3441 JInternalFrame frame = new JInternalFrame();
3443 frame.getContentPane().add(new JScrollPane(pane));
3445 Desktop.addInternalFrame(frame, MessageManager
3446 .formatMessage("label.alignment_properties", new Object[]
3447 { getTitle() }), 500, 400);
3451 * Opens an Overview panel for the alignment, unless one is open already
3456 public void overviewMenuItem_actionPerformed(ActionEvent e)
3458 boolean showHiddenRegions = Cache
3459 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3460 openOverviewPanel(showHiddenRegions);
3463 public OverviewPanel openOverviewPanel(boolean showHidden)
3465 if (alignPanel.overviewPanel != null)
3467 return alignPanel.overviewPanel;
3469 JInternalFrame frame = new JInternalFrame();
3470 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3472 frame.setContentPane(overview);
3473 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3474 frame.getHeight(), true, true);
3475 frame.setFrameIcon(null);
3477 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3478 final AlignmentPanel thePanel = this.alignPanel;
3479 frame.addInternalFrameListener(
3480 new javax.swing.event.InternalFrameAdapter()
3483 public void internalFrameClosed(
3484 javax.swing.event.InternalFrameEvent evt)
3487 thePanel.setOverviewPanel(null);
3490 if (getKeyListeners().length > 0)
3492 frame.addKeyListener(getKeyListeners()[0]);
3495 alignPanel.setOverviewPanel(overview);
3496 alignPanel.setOverviewTitle(this);
3502 public void textColour_actionPerformed()
3504 new TextColourChooser().chooseColour(alignPanel, null);
3508 * public void covariationColour_actionPerformed() {
3510 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3514 public void annotationColour_actionPerformed()
3516 new AnnotationColourChooser(viewport, alignPanel);
3520 public void annotationColumn_actionPerformed(ActionEvent e)
3522 new AnnotationColumnChooser(viewport, alignPanel);
3526 * Action on the user checking or unchecking the option to apply the selected
3527 * colour scheme to all groups. If unchecked, groups may have their own
3528 * independent colour schemes.
3533 public void applyToAllGroups_actionPerformed(boolean selected)
3535 viewport.setColourAppliesToAllGroups(selected);
3539 * Action on user selecting a colour from the colour menu
3542 * the name (not the menu item label!) of the colour scheme
3545 public void changeColour_actionPerformed(String name)
3548 * 'User Defined' opens a panel to configure or load a
3549 * user-defined colour scheme
3551 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3553 new UserDefinedColours(alignPanel);
3558 * otherwise set the chosen colour scheme (or null for 'None')
3560 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3561 viewport, viewport.getAlignment(),
3562 viewport.getHiddenRepSequences());
3567 * Actions on setting or changing the alignment colour scheme
3572 public void changeColour(ColourSchemeI cs)
3574 // TODO: pull up to controller method
3575 ColourMenuHelper.setColourSelected(colourMenu, cs);
3577 viewport.setGlobalColourScheme(cs);
3579 alignPanel.paintAlignment(true, true);
3583 * Show the PID threshold slider panel
3586 protected void modifyPID_actionPerformed()
3588 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3589 alignPanel.getViewName());
3590 SliderPanel.showPIDSlider();
3594 * Show the Conservation slider panel
3597 protected void modifyConservation_actionPerformed()
3599 SliderPanel.setConservationSlider(alignPanel,
3600 viewport.getResidueShading(), alignPanel.getViewName());
3601 SliderPanel.showConservationSlider();
3605 * Action on selecting or deselecting (Colour) By Conservation
3608 public void conservationMenuItem_actionPerformed(boolean selected)
3610 modifyConservation.setEnabled(selected);
3611 viewport.setConservationSelected(selected);
3612 viewport.getResidueShading().setConservationApplied(selected);
3614 changeColour(viewport.getGlobalColourScheme());
3617 modifyConservation_actionPerformed();
3621 SliderPanel.hideConservationSlider();
3626 * Action on selecting or deselecting (Colour) Above PID Threshold
3629 public void abovePIDThreshold_actionPerformed(boolean selected)
3631 modifyPID.setEnabled(selected);
3632 viewport.setAbovePIDThreshold(selected);
3635 viewport.getResidueShading().setThreshold(0,
3636 viewport.isIgnoreGapsConsensus());
3639 changeColour(viewport.getGlobalColourScheme());
3642 modifyPID_actionPerformed();
3646 SliderPanel.hidePIDSlider();
3657 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3659 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3660 AlignmentSorter.sortByPID(viewport.getAlignment(),
3661 viewport.getAlignment().getSequenceAt(0));
3662 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3663 viewport.getAlignment()));
3664 alignPanel.paintAlignment(true, false);
3674 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3676 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3677 AlignmentSorter.sortByID(viewport.getAlignment());
3679 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3680 alignPanel.paintAlignment(true, false);
3690 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3692 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3693 AlignmentSorter.sortByLength(viewport.getAlignment());
3694 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3695 viewport.getAlignment()));
3696 alignPanel.paintAlignment(true, false);
3706 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3708 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3709 AlignmentSorter.sortByGroup(viewport.getAlignment());
3710 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3711 viewport.getAlignment()));
3713 alignPanel.paintAlignment(true, false);
3723 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3725 new RedundancyPanel(alignPanel, this);
3735 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3737 if ((viewport.getSelectionGroup() == null)
3738 || (viewport.getSelectionGroup().getSize() < 2))
3740 JvOptionPane.showInternalMessageDialog(this,
3741 MessageManager.getString(
3742 "label.you_must_select_least_two_sequences"),
3743 MessageManager.getString("label.invalid_selection"),
3744 JvOptionPane.WARNING_MESSAGE);
3748 JInternalFrame frame = new JInternalFrame();
3749 frame.setContentPane(new PairwiseAlignPanel(viewport));
3750 Desktop.addInternalFrame(frame,
3751 MessageManager.getString("action.pairwise_alignment"), 600,
3757 public void autoCalculate_actionPerformed(ActionEvent e)
3759 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3760 if (viewport.autoCalculateConsensus)
3762 viewport.firePropertyChange("alignment", null,
3763 viewport.getAlignment().getSequences());
3768 public void sortByTreeOption_actionPerformed(ActionEvent e)
3770 viewport.sortByTree = sortByTree.isSelected();
3774 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3776 viewport.followSelection = listenToViewSelections.isSelected();
3780 * Constructs a tree panel and adds it to the desktop
3783 * tree type (NJ or AV)
3785 * name of score model used to compute the tree
3787 * parameters for the distance or similarity calculation
3789 void newTreePanel(String type, String modelName,
3790 SimilarityParamsI options)
3792 String frameTitle = "";
3795 boolean onSelection = false;
3796 if (viewport.getSelectionGroup() != null
3797 && viewport.getSelectionGroup().getSize() > 0)
3799 SequenceGroup sg = viewport.getSelectionGroup();
3801 /* Decide if the selection is a column region */
3802 for (SequenceI _s : sg.getSequences())
3804 if (_s.getLength() < sg.getEndRes())
3806 JvOptionPane.showMessageDialog(Desktop.desktop,
3807 MessageManager.getString(
3808 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3809 MessageManager.getString(
3810 "label.sequences_selection_not_aligned"),
3811 JvOptionPane.WARNING_MESSAGE);
3820 if (viewport.getAlignment().getHeight() < 2)
3826 tp = new TreePanel(alignPanel, type, modelName, options);
3827 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3829 frameTitle += " from ";
3831 if (viewport.getViewName() != null)
3833 frameTitle += viewport.getViewName() + " of ";
3836 frameTitle += this.title;
3838 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3849 public void addSortByOrderMenuItem(String title,
3850 final AlignmentOrder order)
3852 final JMenuItem item = new JMenuItem(MessageManager
3853 .formatMessage("action.by_title_param", new Object[]
3856 item.addActionListener(new java.awt.event.ActionListener()
3859 public void actionPerformed(ActionEvent e)
3861 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3863 // TODO: JBPNote - have to map order entries to curent SequenceI
3865 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3867 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3868 viewport.getAlignment()));
3870 alignPanel.paintAlignment(true, false);
3876 * Add a new sort by annotation score menu item
3879 * the menu to add the option to
3881 * the label used to retrieve scores for each sequence on the
3884 public void addSortByAnnotScoreMenuItem(JMenu sort,
3885 final String scoreLabel)
3887 final JMenuItem item = new JMenuItem(scoreLabel);
3889 item.addActionListener(new java.awt.event.ActionListener()
3892 public void actionPerformed(ActionEvent e)
3894 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3895 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3896 viewport.getAlignment());// ,viewport.getSelectionGroup());
3897 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3898 viewport.getAlignment()));
3899 alignPanel.paintAlignment(true, false);
3905 * last hash for alignment's annotation array - used to minimise cost of
3908 protected int _annotationScoreVectorHash;
3911 * search the alignment and rebuild the sort by annotation score submenu the
3912 * last alignment annotation vector hash is stored to minimize cost of
3913 * rebuilding in subsequence calls.
3917 public void buildSortByAnnotationScoresMenu()
3919 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3924 if (viewport.getAlignment().getAlignmentAnnotation()
3925 .hashCode() != _annotationScoreVectorHash)
3927 sortByAnnotScore.removeAll();
3928 // almost certainly a quicker way to do this - but we keep it simple
3929 Hashtable<String, String> scoreSorts = new Hashtable<>();
3930 AlignmentAnnotation aann[];
3931 for (SequenceI sqa : viewport.getAlignment().getSequences())
3933 aann = sqa.getAnnotation();
3934 for (int i = 0; aann != null && i < aann.length; i++)
3936 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3938 scoreSorts.put(aann[i].label, aann[i].label);
3942 Enumeration<String> labels = scoreSorts.keys();
3943 while (labels.hasMoreElements())
3945 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3947 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3950 _annotationScoreVectorHash = viewport.getAlignment()
3951 .getAlignmentAnnotation().hashCode();
3956 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3957 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3958 * call. Listeners are added to remove the menu item when the treePanel is
3959 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3963 public void buildTreeSortMenu()
3965 sortByTreeMenu.removeAll();
3967 List<Component> comps = PaintRefresher.components
3968 .get(viewport.getSequenceSetId());
3969 List<TreePanel> treePanels = new ArrayList<>();
3970 for (Component comp : comps)
3972 if (comp instanceof TreePanel)
3974 treePanels.add((TreePanel) comp);
3978 if (treePanels.size() < 1)
3980 sortByTreeMenu.setVisible(false);
3984 sortByTreeMenu.setVisible(true);
3986 for (final TreePanel tp : treePanels)
3988 final JMenuItem item = new JMenuItem(tp.getTitle());
3989 item.addActionListener(new java.awt.event.ActionListener()
3992 public void actionPerformed(ActionEvent e)
3994 tp.sortByTree_actionPerformed();
3995 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4000 sortByTreeMenu.add(item);
4004 public boolean sortBy(AlignmentOrder alorder, String undoname)
4006 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4007 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4008 if (undoname != null)
4010 addHistoryItem(new OrderCommand(undoname, oldOrder,
4011 viewport.getAlignment()));
4013 alignPanel.paintAlignment(true, false);
4018 * Work out whether the whole set of sequences or just the selected set will
4019 * be submitted for multiple alignment.
4022 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4024 // Now, check we have enough sequences
4025 AlignmentView msa = null;
4027 if ((viewport.getSelectionGroup() != null)
4028 && (viewport.getSelectionGroup().getSize() > 1))
4030 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4031 // some common interface!
4033 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4034 * SequenceI[sz = seqs.getSize(false)];
4036 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4037 * seqs.getSequenceAt(i); }
4039 msa = viewport.getAlignmentView(true);
4041 else if (viewport.getSelectionGroup() != null
4042 && viewport.getSelectionGroup().getSize() == 1)
4044 int option = JvOptionPane.showConfirmDialog(this,
4045 MessageManager.getString("warn.oneseq_msainput_selection"),
4046 MessageManager.getString("label.invalid_selection"),
4047 JvOptionPane.OK_CANCEL_OPTION);
4048 if (option == JvOptionPane.OK_OPTION)
4050 msa = viewport.getAlignmentView(false);
4055 msa = viewport.getAlignmentView(false);
4061 * Decides what is submitted to a secondary structure prediction service: the
4062 * first sequence in the alignment, or in the current selection, or, if the
4063 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4064 * region or the whole alignment. (where the first sequence in the set is the
4065 * one that the prediction will be for).
4067 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4069 AlignmentView seqs = null;
4071 if ((viewport.getSelectionGroup() != null)
4072 && (viewport.getSelectionGroup().getSize() > 0))
4074 seqs = viewport.getAlignmentView(true);
4078 seqs = viewport.getAlignmentView(false);
4080 // limit sequences - JBPNote in future - could spawn multiple prediction
4082 // TODO: viewport.getAlignment().isAligned is a global state - the local
4083 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4084 if (!viewport.getAlignment().isAligned(false))
4086 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4087 // TODO: if seqs.getSequences().length>1 then should really have warned
4101 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4103 // Pick the tree file
4104 JalviewFileChooser chooser = new JalviewFileChooser(
4105 Cache.getProperty("LAST_DIRECTORY"));
4106 chooser.setFileView(new JalviewFileView());
4107 chooser.setDialogTitle(
4108 MessageManager.getString("label.select_newick_like_tree_file"));
4109 chooser.setToolTipText(
4110 MessageManager.getString("label.load_tree_file"));
4112 chooser.setResponseHandler(0, () -> {
4113 String filePath = chooser.getSelectedFile().getPath();
4114 Cache.setProperty("LAST_DIRECTORY", filePath);
4115 NewickFile fin = null;
4118 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4119 DataSourceType.FILE));
4120 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4121 } catch (Exception ex)
4123 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4124 MessageManager.getString("label.problem_reading_tree_file"),
4125 JvOptionPane.WARNING_MESSAGE);
4126 ex.printStackTrace();
4128 if (fin != null && fin.hasWarningMessage())
4130 JvOptionPane.showMessageDialog(Desktop.desktop,
4131 fin.getWarningMessage(),
4133 .getString("label.possible_problem_with_tree_file"),
4134 JvOptionPane.WARNING_MESSAGE);
4138 chooser.showOpenDialog(this);
4141 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4143 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4146 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4147 int h, int x, int y)
4149 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4153 * Add a treeviewer for the tree extracted from a Newick file object to the
4154 * current alignment view
4161 * Associated alignment input data (or null)
4170 * @return TreePanel handle
4172 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4173 AlignmentView input, int w, int h, int x, int y)
4175 TreePanel tp = null;
4181 if (nf.getTree() != null)
4183 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4189 tp.setLocation(x, y);
4192 Desktop.addInternalFrame(tp, treeTitle, w, h);
4194 } catch (Exception ex)
4196 ex.printStackTrace();
4202 public void showContactMapTree(AlignmentAnnotation aa,
4203 PAEContactMatrix cm)
4206 int w = 400, h = 500;
4210 NewickFile fin = new NewickFile(
4211 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4212 String title = "PAE Matrix Tree for "
4213 + cm.getReferenceSeq().getDisplayId(false);
4215 showColumnWiseTree(fin, aa, title, w, h, x, y);
4216 } catch (Throwable xx)
4218 Console.error("Unexpected exception showing tree for contact matrix",
4223 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4224 String treeTitle, int w, int h, int x, int y)
4229 if (nf.getTree() == null)
4233 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4239 tp.setLocation(x, y);
4242 Desktop.addInternalFrame(tp, title, w, h);
4244 } catch (Throwable xx)
4246 Console.error("Unexpected exception showing tree for contact matrix",
4252 private boolean buildingMenu = false;
4255 * Generates menu items and listener event actions for web service clients
4258 public void BuildWebServiceMenu()
4260 while (buildingMenu)
4264 System.err.println("Waiting for building menu to finish.");
4266 } catch (Exception e)
4270 final AlignFrame me = this;
4271 buildingMenu = true;
4272 new Thread(new Runnable()
4277 final List<JMenuItem> legacyItems = new ArrayList<>();
4280 // System.err.println("Building ws menu again "
4281 // + Thread.currentThread());
4282 // TODO: add support for context dependent disabling of services based
4284 // alignment and current selection
4285 // TODO: add additional serviceHandle parameter to specify abstract
4287 // class independently of AbstractName
4288 // TODO: add in rediscovery GUI function to restart discoverer
4289 // TODO: group services by location as well as function and/or
4291 // object broker mechanism.
4292 final Vector<JMenu> wsmenu = new Vector<>();
4293 final IProgressIndicator af = me;
4296 * do not i18n these strings - they are hard-coded in class
4297 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4298 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4300 final JMenu msawsmenu = new JMenu("Alignment");
4301 final JMenu secstrmenu = new JMenu(
4302 "Secondary Structure Prediction");
4303 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4304 final JMenu analymenu = new JMenu("Analysis");
4305 final JMenu dismenu = new JMenu("Protein Disorder");
4306 // JAL-940 - only show secondary structure prediction services from
4307 // the legacy server
4308 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4310 Discoverer.services != null && (Discoverer.services.size() > 0))
4312 // TODO: refactor to allow list of AbstractName/Handler bindings to
4314 // stored or retrieved from elsewhere
4315 // No MSAWS used any more:
4316 // Vector msaws = null; // (Vector)
4317 // Discoverer.services.get("MsaWS");
4318 Vector<ServiceHandle> secstrpr = Discoverer.services
4320 if (secstrpr != null)
4322 // Add any secondary structure prediction services
4323 for (int i = 0, j = secstrpr.size(); i < j; i++)
4325 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4326 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4327 .getServiceClient(sh);
4328 int p = secstrmenu.getItemCount();
4329 impl.attachWSMenuEntry(secstrmenu, me);
4330 int q = secstrmenu.getItemCount();
4331 for (int litm = p; litm < q; litm++)
4333 legacyItems.add(secstrmenu.getItem(litm));
4339 // Add all submenus in the order they should appear on the web
4341 wsmenu.add(msawsmenu);
4342 wsmenu.add(secstrmenu);
4343 wsmenu.add(dismenu);
4344 wsmenu.add(analymenu);
4345 // No search services yet
4346 // wsmenu.add(seqsrchmenu);
4348 javax.swing.SwingUtilities.invokeLater(new Runnable()
4355 webService.removeAll();
4356 // first, add discovered services onto the webservices menu
4357 if (wsmenu.size() > 0)
4359 for (int i = 0, j = wsmenu.size(); i < j; i++)
4361 webService.add(wsmenu.get(i));
4366 webService.add(me.webServiceNoServices);
4368 // TODO: move into separate menu builder class.
4370 // logic for 2.11.1.4 is
4371 // always look to see if there is a discover. if there isn't
4372 // we can't show any Jws2 services
4373 // if there are services available, show them - regardless of
4374 // the 'show JWS2 preference'
4375 // if the discoverer is running then say so
4376 // otherwise offer to trigger discovery if 'show JWS2' is not
4378 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4379 if (jws2servs != null)
4381 if (jws2servs.hasServices())
4383 jws2servs.attachWSMenuEntry(webService, me);
4384 for (Jws2Instance sv : jws2servs.getServices())
4386 if (sv.description.toLowerCase(Locale.ROOT)
4389 for (JMenuItem jmi : legacyItems)
4391 jmi.setVisible(false);
4397 if (jws2servs.isRunning())
4399 JMenuItem tm = new JMenuItem(
4400 "Still discovering JABA Services");
4401 tm.setEnabled(false);
4404 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4406 JMenuItem enableJws2 = new JMenuItem(
4407 "Discover Web Services");
4408 enableJws2.setToolTipText(
4409 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4410 enableJws2.setEnabled(true);
4411 enableJws2.addActionListener(new ActionListener()
4415 public void actionPerformed(ActionEvent e)
4417 // start service discoverer, but ignore preference
4418 Desktop.instance.startServiceDiscovery(false,
4422 webService.add(enableJws2);
4426 build_urlServiceMenu(me.webService);
4427 build_fetchdbmenu(webService);
4428 for (JMenu item : wsmenu)
4430 if (item.getItemCount() == 0)
4432 item.setEnabled(false);
4436 item.setEnabled(true);
4439 } catch (Exception e)
4442 "Exception during web service menu building process.",
4447 } catch (Exception e)
4450 buildingMenu = false;
4457 * construct any groupURL type service menu entries.
4461 protected void build_urlServiceMenu(JMenu webService)
4463 // TODO: remove this code when 2.7 is released
4464 // DEBUG - alignmentView
4466 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4467 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4469 * @Override public void actionPerformed(ActionEvent e) {
4470 * jalview.datamodel.AlignmentView
4471 * .testSelectionViews(af.viewport.getAlignment(),
4472 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4474 * }); webService.add(testAlView);
4476 // TODO: refactor to RestClient discoverer and merge menu entries for
4477 // rest-style services with other types of analysis/calculation service
4478 // SHmmr test client - still being implemented.
4479 // DEBUG - alignmentView
4481 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4484 client.attachWSMenuEntry(
4485 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4491 * Searches the alignment sequences for xRefs and builds the Show
4492 * Cross-References menu (formerly called Show Products), with database
4493 * sources for which cross-references are found (protein sources for a
4494 * nucleotide alignment and vice versa)
4496 * @return true if Show Cross-references menu should be enabled
4498 public boolean canShowProducts()
4500 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4501 AlignmentI dataset = viewport.getAlignment().getDataset();
4503 showProducts.removeAll();
4504 final boolean dna = viewport.getAlignment().isNucleotide();
4506 if (seqs == null || seqs.length == 0)
4508 // nothing to see here.
4512 boolean showp = false;
4515 List<String> ptypes = new CrossRef(seqs, dataset)
4516 .findXrefSourcesForSequences(dna);
4518 for (final String source : ptypes)
4521 final AlignFrame af = this;
4522 JMenuItem xtype = new JMenuItem(source);
4523 xtype.addActionListener(new ActionListener()
4526 public void actionPerformed(ActionEvent e)
4528 showProductsFor(af.viewport.getSequenceSelection(), dna,
4532 showProducts.add(xtype);
4534 showProducts.setVisible(showp);
4535 showProducts.setEnabled(showp);
4536 } catch (Exception e)
4539 "canShowProducts threw an exception - please report to help@jalview.org",
4547 * Finds and displays cross-references for the selected sequences (protein
4548 * products for nucleotide sequences, dna coding sequences for peptides).
4551 * the sequences to show cross-references for
4553 * true if from a nucleotide alignment (so showing proteins)
4555 * the database to show cross-references for
4557 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4558 final String source)
4560 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4565 * Construct and display a new frame containing the translation of this
4566 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4569 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4571 AlignmentI al = null;
4574 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4576 al = dna.translateCdna(codeTable);
4577 } catch (Exception ex)
4579 Console.error("Exception during translation. Please report this !",
4581 final String msg = MessageManager.getString(
4582 "label.error_when_translating_sequences_submit_bug_report");
4583 final String errorTitle = MessageManager
4584 .getString("label.implementation_error")
4585 + MessageManager.getString("label.translation_failed");
4586 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4587 JvOptionPane.ERROR_MESSAGE);
4590 if (al == null || al.getHeight() == 0)
4592 final String msg = MessageManager.getString(
4593 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4594 final String errorTitle = MessageManager
4595 .getString("label.translation_failed");
4596 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4597 JvOptionPane.WARNING_MESSAGE);
4601 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4602 af.setFileFormat(this.currentFileFormat);
4603 final String newTitle = MessageManager
4604 .formatMessage("label.translation_of_params", new Object[]
4605 { this.getTitle(), codeTable.getId() });
4606 af.setTitle(newTitle);
4607 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4609 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4610 viewport.openSplitFrame(af, new Alignment(seqs));
4614 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4621 * Set the file format
4625 public void setFileFormat(FileFormatI format)
4627 this.currentFileFormat = format;
4631 * Try to load a features file onto the alignment.
4634 * contents or path to retrieve file or a File object
4636 * access mode of file (see jalview.io.AlignFile)
4637 * @return true if features file was parsed correctly.
4639 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4642 return avc.parseFeaturesFile(file, sourceType,
4643 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4648 public void refreshFeatureUI(boolean enableIfNecessary)
4650 // note - currently this is only still here rather than in the controller
4651 // because of the featureSettings hard reference that is yet to be
4653 if (enableIfNecessary)
4655 viewport.setShowSequenceFeatures(true);
4656 showSeqFeatures.setSelected(true);
4662 public void dragEnter(DropTargetDragEvent evt)
4667 public void dragExit(DropTargetEvent evt)
4672 public void dragOver(DropTargetDragEvent evt)
4677 public void dropActionChanged(DropTargetDragEvent evt)
4682 public void drop(DropTargetDropEvent evt)
4684 // JAL-1552 - acceptDrop required before getTransferable call for
4685 // Java's Transferable for native dnd
4686 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4687 Transferable t = evt.getTransferable();
4689 final AlignFrame thisaf = this;
4690 final List<Object> files = new ArrayList<>();
4691 List<DataSourceType> protocols = new ArrayList<>();
4695 Desktop.transferFromDropTarget(files, protocols, evt, t);
4696 } catch (Exception e)
4698 e.printStackTrace();
4702 new Thread(new Runnable()
4709 // check to see if any of these files have names matching sequences
4712 SequenceIdMatcher idm = new SequenceIdMatcher(
4713 viewport.getAlignment().getSequencesArray());
4715 * Object[] { String,SequenceI}
4717 ArrayList<Object[]> filesmatched = new ArrayList<>();
4718 ArrayList<Object> filesnotmatched = new ArrayList<>();
4719 for (int i = 0; i < files.size(); i++)
4722 Object file = files.get(i);
4723 String fileName = file.toString();
4725 DataSourceType protocol = (file instanceof File
4726 ? DataSourceType.FILE
4727 : FormatAdapter.checkProtocol(fileName));
4728 if (protocol == DataSourceType.FILE)
4731 if (file instanceof File)
4734 Platform.cacheFileData(fl);
4738 fl = new File(fileName);
4740 pdbfn = fl.getName();
4742 else if (protocol == DataSourceType.URL)
4744 URL url = new URL(fileName);
4745 pdbfn = url.getFile();
4747 if (pdbfn.length() > 0)
4749 // attempt to find a match in the alignment
4750 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4751 int l = 0, c = pdbfn.indexOf(".");
4752 while (mtch == null && c != -1)
4757 } while ((c = pdbfn.indexOf(".", l)) > l);
4760 pdbfn = pdbfn.substring(0, l);
4762 mtch = idm.findAllIdMatches(pdbfn);
4769 type = new IdentifyFile().identify(file, protocol);
4770 } catch (Exception ex)
4774 if (type != null && type.isStructureFile())
4776 filesmatched.add(new Object[] { file, protocol, mtch });
4780 // File wasn't named like one of the sequences or wasn't a PDB
4782 filesnotmatched.add(file);
4786 if (filesmatched.size() > 0)
4788 boolean autoAssociate = Cache
4789 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4792 String msg = MessageManager.formatMessage(
4793 "label.automatically_associate_structure_files_with_sequences_same_name",
4795 { Integer.valueOf(filesmatched.size())
4797 String ttl = MessageManager.getString(
4798 "label.automatically_associate_structure_files_by_name");
4799 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4800 ttl, JvOptionPane.YES_NO_OPTION);
4801 autoAssociate = choice == JvOptionPane.YES_OPTION;
4805 for (Object[] fm : filesmatched)
4807 // try and associate
4808 // TODO: may want to set a standard ID naming formalism for
4809 // associating PDB files which have no IDs.
4810 for (SequenceI toassoc : (SequenceI[]) fm[2])
4812 PDBEntry pe = new AssociatePdbFileWithSeq()
4813 .associatePdbWithSeq(fm[0].toString(),
4814 (DataSourceType) fm[1], toassoc, false,
4818 System.err.println("Associated file : "
4819 + (fm[0].toString()) + " with "
4820 + toassoc.getDisplayId(true));
4824 // TODO: do we need to update overview ? only if features are
4826 alignPanel.paintAlignment(true, false);
4832 * add declined structures as sequences
4834 for (Object[] o : filesmatched)
4836 filesnotmatched.add(o[0]);
4840 if (filesnotmatched.size() > 0)
4842 if (assocfiles > 0 && (Cache.getDefault(
4843 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4844 || JvOptionPane.showConfirmDialog(thisaf,
4845 "<html>" + MessageManager.formatMessage(
4846 "label.ignore_unmatched_dropped_files_info",
4849 filesnotmatched.size())
4852 MessageManager.getString(
4853 "label.ignore_unmatched_dropped_files"),
4854 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4858 for (Object fn : filesnotmatched)
4860 loadJalviewDataFile(fn, null, null, null);
4864 } catch (Exception ex)
4866 ex.printStackTrace();
4874 * Attempt to load a "dropped" file or URL string, by testing in turn for
4876 * <li>an Annotation file</li>
4877 * <li>a JNet file</li>
4878 * <li>a features file</li>
4879 * <li>else try to interpret as an alignment file</li>
4883 * either a filename or a URL string.
4885 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4886 FileFormatI format, SequenceI assocSeq)
4888 // BH 2018 was String file
4891 if (sourceType == null)
4893 sourceType = FormatAdapter.checkProtocol(file);
4895 // if the file isn't identified, or not positively identified as some
4896 // other filetype (PFAM is default unidentified alignment file type) then
4897 // try to parse as annotation.
4898 boolean isAnnotation = (format == null
4899 || FileFormat.Pfam.equals(format))
4900 ? new AnnotationFile().annotateAlignmentView(viewport,
4906 // first see if its a T-COFFEE score file
4907 TCoffeeScoreFile tcf = null;
4910 tcf = new TCoffeeScoreFile(file, sourceType);
4913 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4917 new TCoffeeColourScheme(viewport.getAlignment()));
4918 isAnnotation = true;
4919 setStatus(MessageManager.getString(
4920 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4924 // some problem - if no warning its probable that the ID matching
4925 // process didn't work
4926 JvOptionPane.showMessageDialog(Desktop.desktop,
4927 tcf.getWarningMessage() == null
4928 ? MessageManager.getString(
4929 "label.check_file_matches_sequence_ids_alignment")
4930 : tcf.getWarningMessage(),
4931 MessageManager.getString(
4932 "label.problem_reading_tcoffee_score_file"),
4933 JvOptionPane.WARNING_MESSAGE);
4940 } catch (Exception x)
4943 "Exception when processing data source as T-COFFEE score file",
4949 // try to see if its a JNet 'concise' style annotation file *before*
4951 // try to parse it as a features file
4954 format = new IdentifyFile().identify(file, sourceType);
4956 if (FileFormat.ScoreMatrix == format)
4958 ScoreMatrixFile sm = new ScoreMatrixFile(
4959 new FileParse(file, sourceType));
4961 // todo: i18n this message
4962 setStatus(MessageManager.formatMessage(
4963 "label.successfully_loaded_matrix",
4964 sm.getMatrixName()));
4966 else if (FileFormat.Jnet.equals(format))
4968 JPredFile predictions = new JPredFile(file, sourceType);
4969 new JnetAnnotationMaker();
4970 JnetAnnotationMaker.add_annotation(predictions,
4971 viewport.getAlignment(), 0, false);
4972 viewport.getAlignment().setupJPredAlignment();
4973 isAnnotation = true;
4975 // else if (IdentifyFile.FeaturesFile.equals(format))
4976 else if (FileFormat.Features.equals(format))
4978 if (parseFeaturesFile(file, sourceType))
4980 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
4981 if (splitFrame != null)
4983 splitFrame.repaint();
4987 alignPanel.paintAlignment(true, true);
4993 new FileLoader().LoadFile(viewport, file, sourceType, format);
5000 alignPanel.adjustAnnotationHeight();
5001 viewport.updateSequenceIdColours();
5002 buildSortByAnnotationScoresMenu();
5003 alignPanel.paintAlignment(true, true);
5005 } catch (Exception ex)
5007 ex.printStackTrace();
5008 } catch (OutOfMemoryError oom)
5013 } catch (Exception x)
5018 + (sourceType != null
5019 ? (sourceType == DataSourceType.PASTE
5021 : "using " + sourceType + " from "
5025 ? "(parsing as '" + format + "' file)"
5027 oom, Desktop.desktop);
5032 * Method invoked by the ChangeListener on the tabbed pane, in other words
5033 * when a different tabbed pane is selected by the user or programmatically.
5036 public void tabSelectionChanged(int index)
5041 * update current Overview window title (if there is one)
5042 * to add view name "Original" if necessary
5044 alignPanel.setOverviewTitle(this);
5047 * switch panels and set Overview title (if there is one
5048 * because it was opened automatically)
5050 alignPanel = alignPanels.get(index);
5051 alignPanel.setOverviewTitle(this);
5053 viewport = alignPanel.av;
5054 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5055 setMenusFromViewport(viewport);
5056 if (featureSettings != null && featureSettings.isOpen()
5057 && featureSettings.fr.getViewport() != viewport)
5059 if (viewport.isShowSequenceFeatures())
5061 // refresh the featureSettings to reflect UI change
5062 showFeatureSettingsUI();
5066 // close feature settings for this view.
5067 featureSettings.close();
5074 * 'focus' any colour slider that is open to the selected viewport
5076 if (viewport.getConservationSelected())
5078 SliderPanel.setConservationSlider(alignPanel,
5079 viewport.getResidueShading(), alignPanel.getViewName());
5083 SliderPanel.hideConservationSlider();
5085 if (viewport.getAbovePIDThreshold())
5087 SliderPanel.setPIDSliderSource(alignPanel,
5088 viewport.getResidueShading(), alignPanel.getViewName());
5092 SliderPanel.hidePIDSlider();
5096 * If there is a frame linked to this one in a SplitPane, switch it to the
5097 * same view tab index. No infinite recursion of calls should happen, since
5098 * tabSelectionChanged() should not get invoked on setting the selected
5099 * index to an unchanged value. Guard against setting an invalid index
5100 * before the new view peer tab has been created.
5102 final AlignViewportI peer = viewport.getCodingComplement();
5105 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5106 .getAlignPanel().alignFrame;
5107 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5109 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5115 * On right mouse click on view tab, prompt for and set new view name.
5118 public void tabbedPane_mousePressed(MouseEvent e)
5120 if (e.isPopupTrigger())
5122 String msg = MessageManager.getString("label.enter_view_name");
5123 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5124 String reply = JvOptionPane.showInputDialog(msg, ttl);
5128 viewport.setViewName(reply);
5129 // TODO warn if reply is in getExistingViewNames()?
5130 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5135 public AlignViewport getCurrentView()
5141 * Open the dialog for regex description parsing.
5144 protected void extractScores_actionPerformed(ActionEvent e)
5146 ParseProperties pp = new jalview.analysis.ParseProperties(
5147 viewport.getAlignment());
5148 // TODO: verify regex and introduce GUI dialog for version 2.5
5149 // if (pp.getScoresFromDescription("col", "score column ",
5150 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5152 if (pp.getScoresFromDescription("description column",
5153 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5155 buildSortByAnnotationScoresMenu();
5163 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5167 protected void showDbRefs_actionPerformed(ActionEvent e)
5169 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5175 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5179 protected void showNpFeats_actionPerformed(ActionEvent e)
5181 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5185 * find the viewport amongst the tabs in this alignment frame and close that
5190 public boolean closeView(AlignViewportI av)
5194 this.closeMenuItem_actionPerformed(false);
5197 Component[] comp = tabbedPane.getComponents();
5198 for (int i = 0; comp != null && i < comp.length; i++)
5200 if (comp[i] instanceof AlignmentPanel)
5202 if (((AlignmentPanel) comp[i]).av == av)
5205 closeView((AlignmentPanel) comp[i]);
5213 protected void build_fetchdbmenu(JMenu webService)
5215 // Temporary hack - DBRef Fetcher always top level ws entry.
5216 // TODO We probably want to store a sequence database checklist in
5217 // preferences and have checkboxes.. rather than individual sources selected
5219 final JMenu rfetch = new JMenu(
5220 MessageManager.getString("action.fetch_db_references"));
5221 rfetch.setToolTipText(MessageManager.getString(
5222 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5223 webService.add(rfetch);
5225 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5226 MessageManager.getString("option.trim_retrieved_seqs"));
5227 trimrs.setToolTipText(
5228 MessageManager.getString("label.trim_retrieved_sequences"));
5230 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5231 trimrs.addActionListener(new ActionListener()
5234 public void actionPerformed(ActionEvent e)
5236 trimrs.setSelected(trimrs.isSelected());
5237 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5238 Boolean.valueOf(trimrs.isSelected()).toString());
5242 JMenuItem fetchr = new JMenuItem(
5243 MessageManager.getString("label.standard_databases"));
5244 fetchr.setToolTipText(
5245 MessageManager.getString("label.fetch_embl_uniprot"));
5246 fetchr.addActionListener(new ActionListener()
5250 public void actionPerformed(ActionEvent e)
5252 new Thread(new Runnable()
5257 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5258 .getAlignment().isNucleotide();
5259 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5260 alignPanel.av.getSequenceSelection(),
5261 alignPanel.alignFrame, null,
5262 alignPanel.alignFrame.featureSettings, isNucleotide);
5263 dbRefFetcher.addListener(new FetchFinishedListenerI()
5266 public void finished()
5269 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5270 .getFeatureSettingsModels())
5273 alignPanel.av.mergeFeaturesStyle(srcSettings);
5275 AlignFrame.this.setMenusForViewport();
5278 dbRefFetcher.fetchDBRefs(false);
5286 new Thread(new Runnable()
5291 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5292 .getSequenceFetcherSingleton();
5293 javax.swing.SwingUtilities.invokeLater(new Runnable()
5298 String[] dbclasses = sf.getNonAlignmentSources();
5299 List<DbSourceProxy> otherdb;
5300 JMenu dfetch = new JMenu();
5301 JMenu ifetch = new JMenu();
5302 JMenuItem fetchr = null;
5303 int comp = 0, icomp = 0, mcomp = 15;
5304 String mname = null;
5306 for (String dbclass : dbclasses)
5308 otherdb = sf.getSourceProxy(dbclass);
5309 // add a single entry for this class, or submenu allowing 'fetch
5311 if (otherdb == null || otherdb.size() < 1)
5317 mname = "From " + dbclass;
5319 if (otherdb.size() == 1)
5321 final DbSourceProxy[] dassource = otherdb
5322 .toArray(new DbSourceProxy[0]);
5323 DbSourceProxy src = otherdb.get(0);
5324 fetchr = new JMenuItem(src.getDbSource());
5325 fetchr.addActionListener(new ActionListener()
5329 public void actionPerformed(ActionEvent e)
5331 new Thread(new Runnable()
5337 boolean isNucleotide = alignPanel.alignFrame
5338 .getViewport().getAlignment()
5340 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5341 alignPanel.av.getSequenceSelection(),
5342 alignPanel.alignFrame, dassource,
5343 alignPanel.alignFrame.featureSettings,
5346 .addListener(new FetchFinishedListenerI()
5349 public void finished()
5351 FeatureSettingsModelI srcSettings = dassource[0]
5352 .getFeatureColourScheme();
5353 alignPanel.av.mergeFeaturesStyle(
5355 AlignFrame.this.setMenusForViewport();
5358 dbRefFetcher.fetchDBRefs(false);
5364 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5365 MessageManager.formatMessage(
5366 "label.fetch_retrieve_from", new Object[]
5367 { src.getDbName() })));
5373 final DbSourceProxy[] dassource = otherdb
5374 .toArray(new DbSourceProxy[0]);
5376 DbSourceProxy src = otherdb.get(0);
5377 fetchr = new JMenuItem(MessageManager
5378 .formatMessage("label.fetch_all_param", new Object[]
5379 { src.getDbSource() }));
5380 fetchr.addActionListener(new ActionListener()
5383 public void actionPerformed(ActionEvent e)
5385 new Thread(new Runnable()
5391 boolean isNucleotide = alignPanel.alignFrame
5392 .getViewport().getAlignment()
5394 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5395 alignPanel.av.getSequenceSelection(),
5396 alignPanel.alignFrame, dassource,
5397 alignPanel.alignFrame.featureSettings,
5400 .addListener(new FetchFinishedListenerI()
5403 public void finished()
5405 AlignFrame.this.setMenusForViewport();
5408 dbRefFetcher.fetchDBRefs(false);
5414 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5415 MessageManager.formatMessage(
5416 "label.fetch_retrieve_from_all_sources",
5418 { Integer.valueOf(otherdb.size())
5420 src.getDbSource(), src.getDbName() })));
5423 // and then build the rest of the individual menus
5424 ifetch = new JMenu(MessageManager.formatMessage(
5425 "label.source_from_db_source", new Object[]
5426 { src.getDbSource() }));
5428 String imname = null;
5430 for (DbSourceProxy sproxy : otherdb)
5432 String dbname = sproxy.getDbName();
5433 String sname = dbname.length() > 5
5434 ? dbname.substring(0, 5) + "..."
5436 String msname = dbname.length() > 10
5437 ? dbname.substring(0, 10) + "..."
5441 imname = MessageManager
5442 .formatMessage("label.from_msname", new Object[]
5445 fetchr = new JMenuItem(msname);
5446 final DbSourceProxy[] dassrc = { sproxy };
5447 fetchr.addActionListener(new ActionListener()
5451 public void actionPerformed(ActionEvent e)
5453 new Thread(new Runnable()
5459 boolean isNucleotide = alignPanel.alignFrame
5460 .getViewport().getAlignment()
5462 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5463 alignPanel.av.getSequenceSelection(),
5464 alignPanel.alignFrame, dassrc,
5465 alignPanel.alignFrame.featureSettings,
5468 .addListener(new FetchFinishedListenerI()
5471 public void finished()
5473 AlignFrame.this.setMenusForViewport();
5476 dbRefFetcher.fetchDBRefs(false);
5482 fetchr.setToolTipText(
5483 "<html>" + MessageManager.formatMessage(
5484 "label.fetch_retrieve_from", new Object[]
5488 if (++icomp >= mcomp || i == (otherdb.size()))
5490 ifetch.setText(MessageManager.formatMessage(
5491 "label.source_to_target", imname, sname));
5493 ifetch = new JMenu();
5501 if (comp >= mcomp || dbi >= (dbclasses.length))
5503 dfetch.setText(MessageManager.formatMessage(
5504 "label.source_to_target", mname, dbclass));
5506 dfetch = new JMenu();
5519 * Left justify the whole alignment.
5522 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5524 AlignmentI al = viewport.getAlignment();
5526 viewport.firePropertyChange("alignment", null, al);
5530 * Right justify the whole alignment.
5533 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5535 AlignmentI al = viewport.getAlignment();
5537 viewport.firePropertyChange("alignment", null, al);
5541 public void setShowSeqFeatures(boolean b)
5543 showSeqFeatures.setSelected(b);
5544 viewport.setShowSequenceFeatures(b);
5551 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5552 * awt.event.ActionEvent)
5555 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5557 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5558 alignPanel.paintAlignment(false, false);
5565 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5569 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5571 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5572 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5580 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5581 * .event.ActionEvent)
5584 protected void showGroupConservation_actionPerformed(ActionEvent e)
5586 viewport.setShowGroupConservation(showGroupConservation.getState());
5587 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5594 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5595 * .event.ActionEvent)
5598 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5600 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5601 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5608 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5609 * .event.ActionEvent)
5612 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5614 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5615 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5619 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5621 showSequenceLogo.setState(true);
5622 viewport.setShowSequenceLogo(true);
5623 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5624 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5628 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5630 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5637 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5638 * .event.ActionEvent)
5641 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5643 if (avc.makeGroupsFromSelection())
5645 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5646 alignPanel.updateAnnotation();
5647 alignPanel.paintAlignment(true,
5648 viewport.needToUpdateStructureViews());
5652 public void clearAlignmentSeqRep()
5654 // TODO refactor alignmentseqrep to controller
5655 if (viewport.getAlignment().hasSeqrep())
5657 viewport.getAlignment().setSeqrep(null);
5658 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5659 alignPanel.updateAnnotation();
5660 alignPanel.paintAlignment(true, true);
5665 protected void createGroup_actionPerformed(ActionEvent e)
5667 if (avc.createGroup())
5669 if (applyAutoAnnotationSettings.isSelected())
5671 alignPanel.updateAnnotation(true, false);
5673 alignPanel.alignmentChanged();
5678 protected void unGroup_actionPerformed(ActionEvent e)
5682 alignPanel.alignmentChanged();
5687 * make the given alignmentPanel the currently selected tab
5689 * @param alignmentPanel
5691 public void setDisplayedView(AlignmentPanel alignmentPanel)
5693 if (!viewport.getSequenceSetId()
5694 .equals(alignmentPanel.av.getSequenceSetId()))
5696 throw new Error(MessageManager.getString(
5697 "error.implementation_error_cannot_show_view_alignment_frame"));
5699 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5700 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5702 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5707 * Action on selection of menu options to Show or Hide annotations.
5710 * @param forSequences
5711 * update sequence-related annotations
5712 * @param forAlignment
5713 * update non-sequence-related annotations
5716 public void setAnnotationsVisibility(boolean visible,
5717 boolean forSequences, boolean forAlignment)
5719 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5720 .getAlignmentAnnotation();
5725 for (AlignmentAnnotation aa : anns)
5728 * don't display non-positional annotations on an alignment
5730 if (aa.annotations == null)
5734 boolean apply = (aa.sequenceRef == null && forAlignment)
5735 || (aa.sequenceRef != null && forSequences);
5738 aa.visible = visible;
5741 alignPanel.validateAnnotationDimensions(true);
5742 alignPanel.alignmentChanged();
5746 * Store selected annotation sort order for the view and repaint.
5749 protected void sortAnnotations_actionPerformed()
5751 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5753 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5754 alignPanel.paintAlignment(false, false);
5759 * @return alignment panels in this alignment frame
5761 public List<? extends AlignmentViewPanel> getAlignPanels()
5763 // alignPanels is never null
5764 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5769 * Open a new alignment window, with the cDNA associated with this (protein)
5770 * alignment, aligned as is the protein.
5772 protected void viewAsCdna_actionPerformed()
5774 // TODO no longer a menu action - refactor as required
5775 final AlignmentI alignment = getViewport().getAlignment();
5776 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5777 if (mappings == null)
5781 List<SequenceI> cdnaSeqs = new ArrayList<>();
5782 for (SequenceI aaSeq : alignment.getSequences())
5784 for (AlignedCodonFrame acf : mappings)
5786 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5790 * There is a cDNA mapping for this protein sequence - add to new
5791 * alignment. It will share the same dataset sequence as other mapped
5792 * cDNA (no new mappings need to be created).
5794 final Sequence newSeq = new Sequence(dnaSeq);
5795 newSeq.setDatasetSequence(dnaSeq);
5796 cdnaSeqs.add(newSeq);
5800 if (cdnaSeqs.size() == 0)
5802 // show a warning dialog no mapped cDNA
5805 AlignmentI cdna = new Alignment(
5806 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5807 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5808 AlignFrame.DEFAULT_HEIGHT);
5809 cdna.alignAs(alignment);
5810 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5812 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5813 AlignFrame.DEFAULT_HEIGHT);
5817 * Set visibility of dna/protein complement view (available when shown in a
5823 protected void showComplement_actionPerformed(boolean show)
5825 SplitContainerI sf = getSplitViewContainer();
5828 sf.setComplementVisible(this, show);
5833 * Generate the reverse (optionally complemented) of the selected sequences,
5834 * and add them to the alignment
5837 protected void showReverse_actionPerformed(boolean complement)
5839 AlignmentI al = null;
5842 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5843 al = dna.reverseCdna(complement);
5844 viewport.addAlignment(al, "");
5845 addHistoryItem(new EditCommand(
5846 MessageManager.getString("label.add_sequences"), Action.PASTE,
5847 al.getSequencesArray(), 0, al.getWidth(),
5848 viewport.getAlignment()));
5849 } catch (Exception ex)
5851 System.err.println(ex.getMessage());
5857 * Try to run a script in the Groovy console, having first ensured that this
5858 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5859 * be targeted at this alignment.
5862 protected void runGroovy_actionPerformed()
5864 Jalview.setCurrentAlignFrame(this);
5865 groovy.ui.Console console = Desktop.getGroovyConsole();
5866 if (console != null)
5870 console.runScript();
5871 } catch (Exception ex)
5873 System.err.println((ex.toString()));
5874 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5875 MessageManager.getString("label.couldnt_run_groovy_script"),
5876 MessageManager.getString("label.groovy_support_failed"),
5877 JvOptionPane.ERROR_MESSAGE);
5882 System.err.println("Can't run Groovy script as console not found");
5887 * Hides columns containing (or not containing) a specified feature, provided
5888 * that would not leave all columns hidden
5890 * @param featureType
5891 * @param columnsContaining
5894 public boolean hideFeatureColumns(String featureType,
5895 boolean columnsContaining)
5897 boolean notForHiding = avc.markColumnsContainingFeatures(
5898 columnsContaining, false, false, featureType);
5901 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5902 false, featureType))
5904 getViewport().hideSelectedColumns();
5912 protected void selectHighlightedColumns_actionPerformed(
5913 ActionEvent actionEvent)
5915 // include key modifier check in case user selects from menu
5916 avc.markHighlightedColumns(
5917 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5918 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5919 | ActionEvent.CTRL_MASK)) != 0);
5923 protected void copyHighlightedColumns_actionPerformed(
5924 ActionEvent actionEvent)
5926 avc.copyHighlightedRegionsToClipboard();
5930 * Rebuilds the Colour menu, including any user-defined colours which have
5931 * been loaded either on startup or during the session
5933 public void buildColourMenu()
5935 colourMenu.removeAll();
5937 colourMenu.add(applyToAllGroups);
5938 colourMenu.add(textColour);
5939 colourMenu.addSeparator();
5941 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5942 viewport.getAlignment(), false);
5944 colourMenu.add(annotationColour);
5945 bg.add(annotationColour);
5946 colourMenu.addSeparator();
5947 colourMenu.add(conservationMenuItem);
5948 colourMenu.add(modifyConservation);
5949 colourMenu.add(abovePIDThreshold);
5950 colourMenu.add(modifyPID);
5952 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5953 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5957 * Open a dialog (if not already open) that allows the user to select and
5958 * calculate PCA or Tree analysis
5960 protected void openTreePcaDialog()
5962 if (alignPanel.getCalculationDialog() == null)
5964 new CalculationChooser(AlignFrame.this);
5969 protected void loadVcf_actionPerformed()
5971 JalviewFileChooser chooser = new JalviewFileChooser(
5972 Cache.getProperty("LAST_DIRECTORY"));
5973 chooser.setFileView(new JalviewFileView());
5974 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
5975 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
5976 final AlignFrame us = this;
5977 chooser.setResponseHandler(0, () -> {
5978 String choice = chooser.getSelectedFile().getPath();
5979 Cache.setProperty("LAST_DIRECTORY", choice);
5980 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
5981 new VCFLoader(choice).loadVCF(seqs, us);
5984 chooser.showOpenDialog(null);
5988 private Rectangle lastFeatureSettingsBounds = null;
5991 public void setFeatureSettingsGeometry(Rectangle bounds)
5993 lastFeatureSettingsBounds = bounds;
5997 public Rectangle getFeatureSettingsGeometry()
5999 return lastFeatureSettingsBounds;
6004 class PrintThread extends Thread
6008 public PrintThread(AlignmentPanel ap)
6013 static PageFormat pf;
6018 PrinterJob printJob = PrinterJob.getPrinterJob();
6022 printJob.setPrintable(ap, pf);
6026 printJob.setPrintable(ap);
6029 if (printJob.printDialog())
6034 } catch (Exception PrintException)
6036 PrintException.printStackTrace();