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)
1483 alignPanel.makeAlignmentImage(TYPE.PNG, f);
1487 * Creates an EPS image of the alignment and writes it to the given file. If
1488 * the file is null, the user is prompted to choose a file.
1493 public void createEPS(File f)
1495 alignPanel.makeAlignmentImage(TYPE.EPS, f);
1499 * Creates an SVG image of the alignment and writes it to the given file. If
1500 * the file is null, the user is prompted to choose a file.
1505 public void createSVG(File f)
1507 alignPanel.makeAlignmentImage(TYPE.SVG, f);
1511 public void pageSetup_actionPerformed(ActionEvent e)
1513 PrinterJob printJob = PrinterJob.getPrinterJob();
1514 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1524 public void printMenuItem_actionPerformed(ActionEvent e)
1526 // Putting in a thread avoids Swing painting problems
1527 PrintThread thread = new PrintThread(alignPanel);
1532 public void exportFeatures_actionPerformed(ActionEvent e)
1534 new AnnotationExporter(alignPanel).exportFeatures();
1538 public void exportAnnotations_actionPerformed(ActionEvent e)
1540 new AnnotationExporter(alignPanel).exportAnnotations();
1544 public void associatedData_actionPerformed(ActionEvent e)
1546 final JalviewFileChooser chooser = new JalviewFileChooser(
1547 Cache.getProperty("LAST_DIRECTORY"));
1548 chooser.setFileView(new JalviewFileView());
1549 String tooltip = MessageManager
1550 .getString("label.load_jalview_annotations");
1551 chooser.setDialogTitle(tooltip);
1552 chooser.setToolTipText(tooltip);
1553 chooser.setResponseHandler(0, () -> {
1554 String choice = chooser.getSelectedFile().getPath();
1555 Cache.setProperty("LAST_DIRECTORY", choice);
1556 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1560 chooser.showOpenDialog(this);
1564 * Close the current view or all views in the alignment frame. If the frame
1565 * only contains one view then the alignment will be removed from memory.
1567 * @param closeAllTabs
1570 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1572 if (alignPanels != null && alignPanels.size() < 2)
1574 closeAllTabs = true;
1579 if (alignPanels != null)
1583 if (this.isClosed())
1585 // really close all the windows - otherwise wait till
1586 // setClosed(true) is called
1587 for (int i = 0; i < alignPanels.size(); i++)
1589 AlignmentPanel ap = alignPanels.get(i);
1596 closeView(alignPanel);
1601 if (featureSettings != null && featureSettings.isOpen())
1603 featureSettings.close();
1604 featureSettings = null;
1607 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1608 * be called recursively, with the frame now in 'closed' state
1610 this.setClosed(true);
1612 } catch (Exception ex)
1614 ex.printStackTrace();
1619 * Close the specified panel and close up tabs appropriately.
1621 * @param panelToClose
1623 public void closeView(AlignmentPanel panelToClose)
1625 int index = tabbedPane.getSelectedIndex();
1626 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1627 alignPanels.remove(panelToClose);
1628 panelToClose.closePanel();
1629 panelToClose = null;
1631 tabbedPane.removeTabAt(closedindex);
1632 tabbedPane.validate();
1634 if (index > closedindex || index == tabbedPane.getTabCount())
1636 // modify currently selected tab index if necessary.
1640 this.tabSelectionChanged(index);
1646 void updateEditMenuBar()
1649 if (viewport.getHistoryList().size() > 0)
1651 undoMenuItem.setEnabled(true);
1652 CommandI command = viewport.getHistoryList().peek();
1653 undoMenuItem.setText(MessageManager
1654 .formatMessage("label.undo_command", new Object[]
1655 { command.getDescription() }));
1659 undoMenuItem.setEnabled(false);
1660 undoMenuItem.setText(MessageManager.getString("action.undo"));
1663 if (viewport.getRedoList().size() > 0)
1665 redoMenuItem.setEnabled(true);
1667 CommandI command = viewport.getRedoList().peek();
1668 redoMenuItem.setText(MessageManager
1669 .formatMessage("label.redo_command", new Object[]
1670 { command.getDescription() }));
1674 redoMenuItem.setEnabled(false);
1675 redoMenuItem.setText(MessageManager.getString("action.redo"));
1680 public void addHistoryItem(CommandI command)
1682 if (command.getSize() > 0)
1684 viewport.addToHistoryList(command);
1685 viewport.clearRedoList();
1686 updateEditMenuBar();
1687 viewport.updateHiddenColumns();
1688 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1689 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1690 // viewport.getColumnSelection()
1691 // .getHiddenColumns().size() > 0);
1697 * @return alignment objects for all views
1699 AlignmentI[] getViewAlignments()
1701 if (alignPanels != null)
1703 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1705 for (AlignmentPanel ap : alignPanels)
1707 als[i++] = ap.av.getAlignment();
1711 if (viewport != null)
1713 return new AlignmentI[] { viewport.getAlignment() };
1725 protected void undoMenuItem_actionPerformed(ActionEvent e)
1727 if (viewport.getHistoryList().isEmpty())
1731 CommandI command = viewport.getHistoryList().pop();
1732 viewport.addToRedoList(command);
1733 command.undoCommand(getViewAlignments());
1735 AlignmentViewport originalSource = getOriginatingSource(command);
1736 updateEditMenuBar();
1738 if (originalSource != null)
1740 if (originalSource != viewport)
1743 "Implementation worry: mismatch of viewport origin for undo");
1745 originalSource.updateHiddenColumns();
1746 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1748 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1749 // viewport.getColumnSelection()
1750 // .getHiddenColumns().size() > 0);
1751 originalSource.firePropertyChange("alignment", null,
1752 originalSource.getAlignment().getSequences());
1763 protected void redoMenuItem_actionPerformed(ActionEvent e)
1765 if (viewport.getRedoList().size() < 1)
1770 CommandI command = viewport.getRedoList().pop();
1771 viewport.addToHistoryList(command);
1772 command.doCommand(getViewAlignments());
1774 AlignmentViewport originalSource = getOriginatingSource(command);
1775 updateEditMenuBar();
1777 if (originalSource != null)
1780 if (originalSource != viewport)
1783 "Implementation worry: mismatch of viewport origin for redo");
1785 originalSource.updateHiddenColumns();
1786 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1788 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1789 // viewport.getColumnSelection()
1790 // .getHiddenColumns().size() > 0);
1791 originalSource.firePropertyChange("alignment", null,
1792 originalSource.getAlignment().getSequences());
1796 AlignmentViewport getOriginatingSource(CommandI command)
1798 AlignmentViewport originalSource = null;
1799 // For sequence removal and addition, we need to fire
1800 // the property change event FROM the viewport where the
1801 // original alignment was altered
1802 AlignmentI al = null;
1803 if (command instanceof EditCommand)
1805 EditCommand editCommand = (EditCommand) command;
1806 al = editCommand.getAlignment();
1807 List<Component> comps = PaintRefresher.components
1808 .get(viewport.getSequenceSetId());
1810 for (Component comp : comps)
1812 if (comp instanceof AlignmentPanel)
1814 if (al == ((AlignmentPanel) comp).av.getAlignment())
1816 originalSource = ((AlignmentPanel) comp).av;
1823 if (originalSource == null)
1825 // The original view is closed, we must validate
1826 // the current view against the closed view first
1829 PaintRefresher.validateSequences(al, viewport.getAlignment());
1832 originalSource = viewport;
1835 return originalSource;
1839 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1840 * or the sequence under cursor in keyboard mode
1845 public void moveSelectedSequences(boolean up)
1847 SequenceGroup sg = viewport.getSelectionGroup();
1851 if (viewport.cursorMode)
1853 sg = new SequenceGroup();
1854 sg.addSequence(viewport.getAlignment().getSequenceAt(
1855 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1863 if (sg.getSize() < 1)
1868 // TODO: JAL-3733 - add an event to the undo buffer for this !
1870 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1871 viewport.getHiddenRepSequences(), up);
1872 alignPanel.paintAlignment(true, false);
1875 synchronized void slideSequences(boolean right, int size)
1877 List<SequenceI> sg = new ArrayList<>();
1878 if (viewport.cursorMode)
1880 sg.add(viewport.getAlignment()
1881 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1883 else if (viewport.getSelectionGroup() != null
1884 && viewport.getSelectionGroup().getSize() != viewport
1885 .getAlignment().getHeight())
1887 sg = viewport.getSelectionGroup()
1888 .getSequences(viewport.getHiddenRepSequences());
1896 List<SequenceI> invertGroup = new ArrayList<>();
1898 for (SequenceI seq : viewport.getAlignment().getSequences())
1900 if (!sg.contains(seq))
1902 invertGroup.add(seq);
1906 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1908 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1909 for (int i = 0; i < invertGroup.size(); i++)
1911 seqs2[i] = invertGroup.get(i);
1914 SlideSequencesCommand ssc;
1917 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1918 viewport.getGapCharacter());
1922 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1923 viewport.getGapCharacter());
1926 int groupAdjustment = 0;
1927 if (ssc.getGapsInsertedBegin() && right)
1929 if (viewport.cursorMode)
1931 alignPanel.getSeqPanel().moveCursor(size, 0);
1935 groupAdjustment = size;
1938 else if (!ssc.getGapsInsertedBegin() && !right)
1940 if (viewport.cursorMode)
1942 alignPanel.getSeqPanel().moveCursor(-size, 0);
1946 groupAdjustment = -size;
1950 if (groupAdjustment != 0)
1952 viewport.getSelectionGroup().setStartRes(
1953 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1954 viewport.getSelectionGroup().setEndRes(
1955 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1959 * just extend the last slide command if compatible; but not if in
1960 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1962 boolean appendHistoryItem = false;
1963 Deque<CommandI> historyList = viewport.getHistoryList();
1964 boolean inSplitFrame = getSplitViewContainer() != null;
1965 if (!inSplitFrame && historyList != null && historyList.size() > 0
1966 && historyList.peek() instanceof SlideSequencesCommand)
1968 appendHistoryItem = ssc.appendSlideCommand(
1969 (SlideSequencesCommand) historyList.peek());
1972 if (!appendHistoryItem)
1974 addHistoryItem(ssc);
1987 protected void copy_actionPerformed()
1989 if (viewport.getSelectionGroup() == null)
1993 // TODO: preserve the ordering of displayed alignment annotation in any
1994 // internal paste (particularly sequence associated annotation)
1995 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
1996 String[] omitHidden = null;
1998 if (viewport.hasHiddenColumns())
2000 omitHidden = viewport.getViewAsString(true);
2003 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2004 seqs, omitHidden, null);
2006 StringSelection ss = new StringSelection(output);
2010 jalview.gui.Desktop.internalCopy = true;
2011 // Its really worth setting the clipboard contents
2012 // to empty before setting the large StringSelection!!
2013 Toolkit.getDefaultToolkit().getSystemClipboard()
2014 .setContents(new StringSelection(""), null);
2016 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2018 } catch (OutOfMemoryError er)
2020 new OOMWarning("copying region", er);
2024 HiddenColumns hiddenColumns = null;
2025 if (viewport.hasHiddenColumns())
2027 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2028 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2030 // create new HiddenColumns object with copy of hidden regions
2031 // between startRes and endRes, offset by startRes
2032 hiddenColumns = new HiddenColumns(
2033 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2034 hiddenCutoff, hiddenOffset);
2037 Desktop.jalviewClipboard = new Object[] { seqs,
2038 viewport.getAlignment().getDataset(), hiddenColumns };
2039 setStatus(MessageManager.formatMessage(
2040 "label.copied_sequences_to_clipboard", new Object[]
2041 { Integer.valueOf(seqs.length).toString() }));
2051 protected void pasteNew_actionPerformed(ActionEvent e)
2063 protected void pasteThis_actionPerformed(ActionEvent e)
2069 * Paste contents of Jalview clipboard
2071 * @param newAlignment
2072 * true to paste to a new alignment, otherwise add to this.
2074 void paste(boolean newAlignment)
2076 boolean externalPaste = true;
2079 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2080 Transferable contents = c.getContents(this);
2082 if (contents == null)
2091 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2092 if (str.length() < 1)
2097 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2099 } catch (OutOfMemoryError er)
2101 new OOMWarning("Out of memory pasting sequences!!", er);
2105 SequenceI[] sequences;
2106 boolean annotationAdded = false;
2107 AlignmentI alignment = null;
2109 if (Desktop.jalviewClipboard != null)
2111 // The clipboard was filled from within Jalview, we must use the
2113 // And dataset from the copied alignment
2114 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2115 // be doubly sure that we create *new* sequence objects.
2116 sequences = new SequenceI[newseq.length];
2117 for (int i = 0; i < newseq.length; i++)
2119 sequences[i] = new Sequence(newseq[i]);
2121 alignment = new Alignment(sequences);
2122 externalPaste = false;
2126 // parse the clipboard as an alignment.
2127 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2129 sequences = alignment.getSequencesArray();
2133 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2139 if (Desktop.jalviewClipboard != null)
2141 // dataset is inherited
2142 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2146 // new dataset is constructed
2147 alignment.setDataset(null);
2149 alwidth = alignment.getWidth() + 1;
2153 AlignmentI pastedal = alignment; // preserve pasted alignment object
2154 // Add pasted sequences and dataset into existing alignment.
2155 alignment = viewport.getAlignment();
2156 alwidth = alignment.getWidth() + 1;
2157 // decide if we need to import sequences from an existing dataset
2158 boolean importDs = Desktop.jalviewClipboard != null
2159 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2160 // importDs==true instructs us to copy over new dataset sequences from
2161 // an existing alignment
2162 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2164 // minimum dataset set
2166 for (int i = 0; i < sequences.length; i++)
2170 newDs.addElement(null);
2172 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2174 if (importDs && ds != null)
2176 if (!newDs.contains(ds))
2178 newDs.setElementAt(ds, i);
2179 ds = new Sequence(ds);
2180 // update with new dataset sequence
2181 sequences[i].setDatasetSequence(ds);
2185 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2190 // copy and derive new dataset sequence
2191 sequences[i] = sequences[i].deriveSequence();
2192 alignment.getDataset()
2193 .addSequence(sequences[i].getDatasetSequence());
2194 // TODO: avoid creation of duplicate dataset sequences with a
2195 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2197 alignment.addSequence(sequences[i]); // merges dataset
2201 newDs.clear(); // tidy up
2203 if (alignment.getAlignmentAnnotation() != null)
2205 for (AlignmentAnnotation alan : alignment
2206 .getAlignmentAnnotation())
2208 if (alan.graphGroup > fgroup)
2210 fgroup = alan.graphGroup;
2214 if (pastedal.getAlignmentAnnotation() != null)
2216 // Add any annotation attached to alignment.
2217 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2218 for (int i = 0; i < alann.length; i++)
2220 annotationAdded = true;
2221 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2223 AlignmentAnnotation newann = new AlignmentAnnotation(
2225 if (newann.graphGroup > -1)
2227 if (newGraphGroups.size() <= newann.graphGroup
2228 || newGraphGroups.get(newann.graphGroup) == null)
2230 for (int q = newGraphGroups
2231 .size(); q <= newann.graphGroup; q++)
2233 newGraphGroups.add(q, null);
2235 newGraphGroups.set(newann.graphGroup,
2236 Integer.valueOf(++fgroup));
2238 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2242 newann.padAnnotation(alwidth);
2243 alignment.addAnnotation(newann);
2253 addHistoryItem(new EditCommand(
2254 MessageManager.getString("label.add_sequences"),
2255 Action.PASTE, sequences, 0, alignment.getWidth(),
2258 // Add any annotations attached to sequences
2259 for (int i = 0; i < sequences.length; i++)
2261 if (sequences[i].getAnnotation() != null)
2263 AlignmentAnnotation newann;
2264 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2266 annotationAdded = true;
2267 newann = sequences[i].getAnnotation()[a];
2268 newann.adjustForAlignment();
2269 newann.padAnnotation(alwidth);
2270 if (newann.graphGroup > -1)
2272 if (newann.graphGroup > -1)
2274 if (newGraphGroups.size() <= newann.graphGroup
2275 || newGraphGroups.get(newann.graphGroup) == null)
2277 for (int q = newGraphGroups
2278 .size(); q <= newann.graphGroup; q++)
2280 newGraphGroups.add(q, null);
2282 newGraphGroups.set(newann.graphGroup,
2283 Integer.valueOf(++fgroup));
2285 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2289 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
2293 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2301 // propagate alignment changed.
2302 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2303 if (annotationAdded)
2305 // Duplicate sequence annotation in all views.
2306 AlignmentI[] alview = this.getViewAlignments();
2307 for (int i = 0; i < sequences.length; i++)
2309 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2314 for (int avnum = 0; avnum < alview.length; avnum++)
2316 if (alview[avnum] != alignment)
2318 // duplicate in a view other than the one with input focus
2319 int avwidth = alview[avnum].getWidth() + 1;
2320 // this relies on sann being preserved after we
2321 // modify the sequence's annotation array for each duplication
2322 for (int a = 0; a < sann.length; a++)
2324 AlignmentAnnotation newann = new AlignmentAnnotation(
2326 sequences[i].addAlignmentAnnotation(newann);
2327 newann.padAnnotation(avwidth);
2328 alview[avnum].addAnnotation(newann); // annotation was
2329 // duplicated earlier
2330 // TODO JAL-1145 graphGroups are not updated for sequence
2331 // annotation added to several views. This may cause
2333 alview[avnum].setAnnotationIndex(newann, a);
2338 buildSortByAnnotationScoresMenu();
2340 viewport.firePropertyChange("alignment", null,
2341 alignment.getSequences());
2342 if (alignPanels != null)
2344 for (AlignmentPanel ap : alignPanels)
2346 ap.validateAnnotationDimensions(false);
2351 alignPanel.validateAnnotationDimensions(false);
2357 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2359 String newtitle = new String("Copied sequences");
2361 if (Desktop.jalviewClipboard != null
2362 && Desktop.jalviewClipboard[2] != null)
2364 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2365 af.viewport.setHiddenColumns(hc);
2368 // >>>This is a fix for the moment, until a better solution is
2370 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2371 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2372 .getFeatureRenderer());
2374 // TODO: maintain provenance of an alignment, rather than just make the
2375 // title a concatenation of operations.
2378 if (title.startsWith("Copied sequences"))
2384 newtitle = newtitle.concat("- from " + title);
2389 newtitle = new String("Pasted sequences");
2392 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2397 } catch (Exception ex)
2399 ex.printStackTrace();
2400 System.out.println("Exception whilst pasting: " + ex);
2401 // could be anything being pasted in here
2407 protected void expand_newalign(ActionEvent e)
2411 AlignmentI alignment = AlignmentUtils
2412 .expandContext(getViewport().getAlignment(), -1);
2413 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2415 String newtitle = new String("Flanking alignment");
2417 if (Desktop.jalviewClipboard != null
2418 && Desktop.jalviewClipboard[2] != null)
2420 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2421 af.viewport.setHiddenColumns(hc);
2424 // >>>This is a fix for the moment, until a better solution is
2426 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2427 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2428 .getFeatureRenderer());
2430 // TODO: maintain provenance of an alignment, rather than just make the
2431 // title a concatenation of operations.
2433 if (title.startsWith("Copied sequences"))
2439 newtitle = newtitle.concat("- from " + title);
2443 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2445 } catch (Exception ex)
2447 ex.printStackTrace();
2448 System.out.println("Exception whilst pasting: " + ex);
2449 // could be anything being pasted in here
2450 } catch (OutOfMemoryError oom)
2452 new OOMWarning("Viewing flanking region of alignment", oom);
2457 * Action Cut (delete and copy) the selected region
2460 protected void cut_actionPerformed()
2462 copy_actionPerformed();
2463 delete_actionPerformed();
2467 * Performs menu option to Delete the currently selected region
2470 protected void delete_actionPerformed()
2473 SequenceGroup sg = viewport.getSelectionGroup();
2479 Callable okAction = () -> {
2480 SequenceI[] cut = sg.getSequences()
2481 .toArray(new SequenceI[sg.getSize()]);
2483 addHistoryItem(new EditCommand(
2484 MessageManager.getString("label.cut_sequences"), Action.CUT,
2485 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2486 viewport.getAlignment()));
2488 viewport.setSelectionGroup(null);
2489 viewport.sendSelection();
2490 viewport.getAlignment().deleteGroup(sg);
2492 viewport.firePropertyChange("alignment", null,
2493 viewport.getAlignment().getSequences());
2494 if (viewport.getAlignment().getHeight() < 1)
2498 AlignFrame.this.setClosed(true);
2499 } catch (Exception ex)
2507 * If the cut affects all sequences, prompt for confirmation
2509 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2511 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2512 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2513 if (wholeHeight && wholeWidth)
2515 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2516 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2517 Object[] options = new Object[] {
2518 MessageManager.getString("action.ok"),
2519 MessageManager.getString("action.cancel") };
2520 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2521 MessageManager.getString("label.delete_all"),
2522 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2523 options, options[0]);
2530 } catch (Exception e)
2532 e.printStackTrace();
2544 protected void deleteGroups_actionPerformed(ActionEvent e)
2546 if (avc.deleteGroups())
2548 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2549 alignPanel.updateAnnotation();
2550 alignPanel.paintAlignment(true, true);
2561 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2563 SequenceGroup sg = new SequenceGroup(
2564 viewport.getAlignment().getSequences());
2566 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2567 viewport.setSelectionGroup(sg);
2568 viewport.isSelectionGroupChanged(true);
2569 viewport.sendSelection();
2570 // JAL-2034 - should delegate to
2571 // alignPanel to decide if overview needs
2573 alignPanel.paintAlignment(false, false);
2574 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2584 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2586 if (viewport.cursorMode)
2588 alignPanel.getSeqPanel().keyboardNo1 = null;
2589 alignPanel.getSeqPanel().keyboardNo2 = null;
2591 viewport.setSelectionGroup(null);
2592 viewport.getColumnSelection().clear();
2593 viewport.setSearchResults(null);
2594 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2595 // JAL-2034 - should delegate to
2596 // alignPanel to decide if overview needs
2598 alignPanel.paintAlignment(false, false);
2599 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2600 viewport.sendSelection();
2610 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2612 SequenceGroup sg = viewport.getSelectionGroup();
2616 selectAllSequenceMenuItem_actionPerformed(null);
2621 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2623 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2625 // JAL-2034 - should delegate to
2626 // alignPanel to decide if overview needs
2629 alignPanel.paintAlignment(true, false);
2630 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2631 viewport.sendSelection();
2635 public void invertColSel_actionPerformed(ActionEvent e)
2637 viewport.invertColumnSelection();
2638 alignPanel.paintAlignment(true, false);
2639 viewport.sendSelection();
2649 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2651 trimAlignment(true);
2661 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2663 trimAlignment(false);
2666 void trimAlignment(boolean trimLeft)
2668 ColumnSelection colSel = viewport.getColumnSelection();
2671 if (!colSel.isEmpty())
2675 column = colSel.getMin();
2679 column = colSel.getMax();
2683 if (viewport.getSelectionGroup() != null)
2685 seqs = viewport.getSelectionGroup()
2686 .getSequencesAsArray(viewport.getHiddenRepSequences());
2690 seqs = viewport.getAlignment().getSequencesArray();
2693 TrimRegionCommand trimRegion;
2696 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2697 column, viewport.getAlignment());
2698 viewport.getRanges().setStartRes(0);
2702 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2703 column, viewport.getAlignment());
2706 setStatus(MessageManager.formatMessage("label.removed_columns",
2708 { Integer.valueOf(trimRegion.getSize()).toString() }));
2710 addHistoryItem(trimRegion);
2712 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2714 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2715 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2717 viewport.getAlignment().deleteGroup(sg);
2721 viewport.firePropertyChange("alignment", null,
2722 viewport.getAlignment().getSequences());
2733 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2735 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2738 if (viewport.getSelectionGroup() != null)
2740 seqs = viewport.getSelectionGroup()
2741 .getSequencesAsArray(viewport.getHiddenRepSequences());
2742 start = viewport.getSelectionGroup().getStartRes();
2743 end = viewport.getSelectionGroup().getEndRes();
2747 seqs = viewport.getAlignment().getSequencesArray();
2750 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2751 "Remove Gapped Columns", seqs, start, end,
2752 viewport.getAlignment());
2754 addHistoryItem(removeGapCols);
2756 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2758 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2760 // This is to maintain viewport position on first residue
2761 // of first sequence
2762 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2763 ViewportRanges ranges = viewport.getRanges();
2764 int startRes = seq.findPosition(ranges.getStartRes());
2765 // ShiftList shifts;
2766 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2767 // edit.alColumnChanges=shifts.getInverse();
2768 // if (viewport.hasHiddenColumns)
2769 // viewport.getColumnSelection().compensateForEdits(shifts);
2770 ranges.setStartRes(seq.findIndex(startRes) - 1);
2771 viewport.firePropertyChange("alignment", null,
2772 viewport.getAlignment().getSequences());
2783 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2785 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2788 if (viewport.getSelectionGroup() != null)
2790 seqs = viewport.getSelectionGroup()
2791 .getSequencesAsArray(viewport.getHiddenRepSequences());
2792 start = viewport.getSelectionGroup().getStartRes();
2793 end = viewport.getSelectionGroup().getEndRes();
2797 seqs = viewport.getAlignment().getSequencesArray();
2800 // This is to maintain viewport position on first residue
2801 // of first sequence
2802 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2803 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2805 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2806 viewport.getAlignment()));
2808 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2810 viewport.firePropertyChange("alignment", null,
2811 viewport.getAlignment().getSequences());
2822 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2824 viewport.setPadGaps(padGapsMenuitem.isSelected());
2825 viewport.firePropertyChange("alignment", null,
2826 viewport.getAlignment().getSequences());
2830 * Opens a Finder dialog
2835 public void findMenuItem_actionPerformed(ActionEvent e)
2837 new Finder(alignPanel, false, null);
2841 * Create a new view of the current alignment.
2844 public void newView_actionPerformed(ActionEvent e)
2846 newView(null, true);
2850 * Creates and shows a new view of the current alignment.
2853 * title of newly created view; if null, one will be generated
2854 * @param copyAnnotation
2855 * if true then duplicate all annnotation, groups and settings
2856 * @return new alignment panel, already displayed.
2858 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2861 * Create a new AlignmentPanel (with its own, new Viewport)
2863 AlignmentPanel newap = new jalview.project.Jalview2XML()
2864 .copyAlignPanel(alignPanel);
2865 if (!copyAnnotation)
2868 * remove all groups and annotation except for the automatic stuff
2870 newap.av.getAlignment().deleteAllGroups();
2871 newap.av.getAlignment().deleteAllAnnotations(false);
2874 newap.av.setGatherViewsHere(false);
2876 if (viewport.getViewName() == null)
2878 viewport.setViewName(
2879 MessageManager.getString("label.view_name_original"));
2883 * Views share the same edits undo and redo stacks
2885 newap.av.setHistoryList(viewport.getHistoryList());
2886 newap.av.setRedoList(viewport.getRedoList());
2889 * copy any visualisation settings that are not saved in the project
2891 newap.av.setColourAppliesToAllGroups(
2892 viewport.getColourAppliesToAllGroups());
2895 * Views share the same mappings; need to deregister any new mappings
2896 * created by copyAlignPanel, and register the new reference to the shared
2899 newap.av.replaceMappings(viewport.getAlignment());
2902 * start up cDNA consensus (if applicable) now mappings are in place
2904 if (newap.av.initComplementConsensus())
2906 newap.refresh(true); // adjust layout of annotations
2909 newap.av.setViewName(getNewViewName(viewTitle));
2911 addAlignmentPanel(newap, true);
2912 newap.alignmentChanged();
2914 if (alignPanels.size() == 2)
2916 viewport.setGatherViewsHere(true);
2918 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2924 * Make a new name for the view, ensuring it is unique within the current
2925 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2926 * these now use viewId. Unique view names are still desirable for usability.)
2931 protected String getNewViewName(String viewTitle)
2933 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2934 boolean addFirstIndex = false;
2935 if (viewTitle == null || viewTitle.trim().length() == 0)
2937 viewTitle = MessageManager.getString("action.view");
2938 addFirstIndex = true;
2942 index = 1;// we count from 1 if given a specific name
2944 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2946 List<Component> comps = PaintRefresher.components
2947 .get(viewport.getSequenceSetId());
2949 List<String> existingNames = getExistingViewNames(comps);
2951 while (existingNames.contains(newViewName))
2953 newViewName = viewTitle + " " + (++index);
2959 * Returns a list of distinct view names found in the given list of
2960 * components. View names are held on the viewport of an AlignmentPanel.
2965 protected List<String> getExistingViewNames(List<Component> comps)
2967 List<String> existingNames = new ArrayList<>();
2968 for (Component comp : comps)
2970 if (comp instanceof AlignmentPanel)
2972 AlignmentPanel ap = (AlignmentPanel) comp;
2973 if (!existingNames.contains(ap.av.getViewName()))
2975 existingNames.add(ap.av.getViewName());
2979 return existingNames;
2983 * Explode tabbed views into separate windows.
2986 public void expandViews_actionPerformed(ActionEvent e)
2988 Desktop.explodeViews(this);
2992 * Gather views in separate windows back into a tabbed presentation.
2995 public void gatherViews_actionPerformed(ActionEvent e)
2997 Desktop.instance.gatherViews(this);
3007 public void font_actionPerformed(ActionEvent e)
3009 new FontChooser(alignPanel);
3019 protected void seqLimit_actionPerformed(ActionEvent e)
3021 viewport.setShowJVSuffix(seqLimits.isSelected());
3023 alignPanel.getIdPanel().getIdCanvas()
3024 .setPreferredSize(alignPanel.calculateIdWidth());
3025 alignPanel.paintAlignment(true, false);
3029 public void idRightAlign_actionPerformed(ActionEvent e)
3031 viewport.setRightAlignIds(idRightAlign.isSelected());
3032 alignPanel.paintAlignment(false, false);
3036 public void centreColumnLabels_actionPerformed(ActionEvent e)
3038 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3039 alignPanel.paintAlignment(false, false);
3045 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3048 protected void followHighlight_actionPerformed()
3051 * Set the 'follow' flag on the Viewport (and scroll to position if now
3054 final boolean state = this.followHighlightMenuItem.getState();
3055 viewport.setFollowHighlight(state);
3058 alignPanel.scrollToPosition(viewport.getSearchResults());
3069 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3071 viewport.setColourText(colourTextMenuItem.isSelected());
3072 alignPanel.paintAlignment(false, false);
3082 public void wrapMenuItem_actionPerformed(ActionEvent e)
3084 scaleAbove.setVisible(wrapMenuItem.isSelected());
3085 scaleLeft.setVisible(wrapMenuItem.isSelected());
3086 scaleRight.setVisible(wrapMenuItem.isSelected());
3087 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3088 alignPanel.updateLayout();
3092 public void showAllSeqs_actionPerformed(ActionEvent e)
3094 viewport.showAllHiddenSeqs();
3098 public void showAllColumns_actionPerformed(ActionEvent e)
3100 viewport.showAllHiddenColumns();
3101 alignPanel.paintAlignment(true, true);
3102 viewport.sendSelection();
3106 public void hideSelSequences_actionPerformed(ActionEvent e)
3108 viewport.hideAllSelectedSeqs();
3112 * called by key handler and the hide all/show all menu items
3117 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3120 boolean hide = false;
3121 SequenceGroup sg = viewport.getSelectionGroup();
3122 if (!toggleSeqs && !toggleCols)
3124 // Hide everything by the current selection - this is a hack - we do the
3125 // invert and then hide
3126 // first check that there will be visible columns after the invert.
3127 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3128 && sg.getStartRes() <= sg.getEndRes()))
3130 // now invert the sequence set, if required - empty selection implies
3131 // that no hiding is required.
3134 invertSequenceMenuItem_actionPerformed(null);
3135 sg = viewport.getSelectionGroup();
3139 viewport.expandColSelection(sg, true);
3140 // finally invert the column selection and get the new sequence
3142 invertColSel_actionPerformed(null);
3149 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3151 hideSelSequences_actionPerformed(null);
3154 else if (!(toggleCols && viewport.hasSelectedColumns()))
3156 showAllSeqs_actionPerformed(null);
3162 if (viewport.hasSelectedColumns())
3164 hideSelColumns_actionPerformed(null);
3167 viewport.setSelectionGroup(sg);
3172 showAllColumns_actionPerformed(null);
3181 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3182 * event.ActionEvent)
3185 public void hideAllButSelection_actionPerformed(ActionEvent e)
3187 toggleHiddenRegions(false, false);
3188 viewport.sendSelection();
3195 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3199 public void hideAllSelection_actionPerformed(ActionEvent e)
3201 SequenceGroup sg = viewport.getSelectionGroup();
3202 viewport.expandColSelection(sg, false);
3203 viewport.hideAllSelectedSeqs();
3204 viewport.hideSelectedColumns();
3205 alignPanel.updateLayout();
3206 alignPanel.paintAlignment(true, true);
3207 viewport.sendSelection();
3214 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3218 public void showAllhidden_actionPerformed(ActionEvent e)
3220 viewport.showAllHiddenColumns();
3221 viewport.showAllHiddenSeqs();
3222 alignPanel.paintAlignment(true, true);
3223 viewport.sendSelection();
3227 public void hideSelColumns_actionPerformed(ActionEvent e)
3229 viewport.hideSelectedColumns();
3230 alignPanel.updateLayout();
3231 alignPanel.paintAlignment(true, true);
3232 viewport.sendSelection();
3236 public void hiddenMarkers_actionPerformed(ActionEvent e)
3238 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3249 protected void scaleAbove_actionPerformed(ActionEvent e)
3251 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3252 alignPanel.updateLayout();
3253 alignPanel.paintAlignment(true, false);
3263 protected void scaleLeft_actionPerformed(ActionEvent e)
3265 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3266 alignPanel.updateLayout();
3267 alignPanel.paintAlignment(true, false);
3277 protected void scaleRight_actionPerformed(ActionEvent e)
3279 viewport.setScaleRightWrapped(scaleRight.isSelected());
3280 alignPanel.updateLayout();
3281 alignPanel.paintAlignment(true, false);
3291 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3293 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3294 alignPanel.paintAlignment(false, false);
3304 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3306 viewport.setShowText(viewTextMenuItem.isSelected());
3307 alignPanel.paintAlignment(false, false);
3317 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3319 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3320 alignPanel.paintAlignment(false, false);
3323 public FeatureSettings featureSettings;
3326 public FeatureSettingsControllerI getFeatureSettingsUI()
3328 return featureSettings;
3332 public void featureSettings_actionPerformed(ActionEvent e)
3334 showFeatureSettingsUI();
3338 public FeatureSettingsControllerI showFeatureSettingsUI()
3340 if (featureSettings != null)
3342 featureSettings.closeOldSettings();
3343 featureSettings = null;
3345 if (!showSeqFeatures.isSelected())
3347 // make sure features are actually displayed
3348 showSeqFeatures.setSelected(true);
3349 showSeqFeatures_actionPerformed(null);
3351 featureSettings = new FeatureSettings(this);
3352 return featureSettings;
3356 * Set or clear 'Show Sequence Features'
3362 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3364 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3365 alignPanel.paintAlignment(true, true);
3369 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3370 * the annotations panel as a whole.
3372 * The options to show/hide all annotations should be enabled when the panel
3373 * is shown, and disabled when the panel is hidden.
3378 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3380 final boolean setVisible = annotationPanelMenuItem.isSelected();
3381 viewport.setShowAnnotation(setVisible);
3382 this.showAllSeqAnnotations.setEnabled(setVisible);
3383 this.hideAllSeqAnnotations.setEnabled(setVisible);
3384 this.showAllAlAnnotations.setEnabled(setVisible);
3385 this.hideAllAlAnnotations.setEnabled(setVisible);
3386 alignPanel.updateLayout();
3390 public void alignmentProperties()
3393 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3396 String content = MessageManager.formatMessage("label.html_content",
3398 { contents.toString() });
3401 if (Platform.isJS())
3403 JLabel textLabel = new JLabel();
3404 textLabel.setText(content);
3405 textLabel.setBackground(Color.WHITE);
3407 pane = new JPanel(new BorderLayout());
3408 ((JPanel) pane).setOpaque(true);
3409 pane.setBackground(Color.WHITE);
3410 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3419 JEditorPane editPane = new JEditorPane("text/html", "");
3420 editPane.setEditable(false);
3421 editPane.setText(content);
3425 JInternalFrame frame = new JInternalFrame();
3427 frame.getContentPane().add(new JScrollPane(pane));
3429 Desktop.addInternalFrame(frame, MessageManager
3430 .formatMessage("label.alignment_properties", new Object[]
3431 { getTitle() }), 500, 400);
3435 * Opens an Overview panel for the alignment, unless one is open already
3440 public void overviewMenuItem_actionPerformed(ActionEvent e)
3442 boolean showHiddenRegions = Cache.getDefault(Preferences.SHOW_OV_HIDDEN_AT_START,
3444 openOverviewPanel(showHiddenRegions);
3447 public OverviewPanel openOverviewPanel(boolean showHidden)
3449 if (alignPanel.overviewPanel != null)
3451 return alignPanel.overviewPanel;
3453 JInternalFrame frame = new JInternalFrame();
3454 final OverviewPanel overview = new OverviewPanel(alignPanel, frame, showHidden);
3455 frame.setContentPane(overview);
3456 Desktop.addInternalFrame(frame, "", true, frame.getWidth(), frame.getHeight(),
3458 frame.setFrameIcon(null);
3460 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3461 final AlignmentPanel thePanel = this.alignPanel;
3462 frame.addInternalFrameListener(
3463 new javax.swing.event.InternalFrameAdapter()
3466 public void internalFrameClosed(
3467 javax.swing.event.InternalFrameEvent evt)
3470 thePanel.setOverviewPanel(null);
3473 if (getKeyListeners().length > 0)
3475 frame.addKeyListener(getKeyListeners()[0]);
3478 alignPanel.setOverviewPanel(overview);
3479 alignPanel.setOverviewTitle(this);
3485 public void textColour_actionPerformed()
3487 new TextColourChooser().chooseColour(alignPanel, null);
3491 * public void covariationColour_actionPerformed() {
3493 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3497 public void annotationColour_actionPerformed()
3499 new AnnotationColourChooser(viewport, alignPanel);
3503 public void annotationColumn_actionPerformed(ActionEvent e)
3505 new AnnotationColumnChooser(viewport, alignPanel);
3509 * Action on the user checking or unchecking the option to apply the selected
3510 * colour scheme to all groups. If unchecked, groups may have their own
3511 * independent colour schemes.
3516 public void applyToAllGroups_actionPerformed(boolean selected)
3518 viewport.setColourAppliesToAllGroups(selected);
3522 * Action on user selecting a colour from the colour menu
3525 * the name (not the menu item label!) of the colour scheme
3528 public void changeColour_actionPerformed(String name)
3531 * 'User Defined' opens a panel to configure or load a
3532 * user-defined colour scheme
3534 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3536 new UserDefinedColours(alignPanel);
3541 * otherwise set the chosen colour scheme (or null for 'None')
3543 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3544 viewport, viewport.getAlignment(),
3545 viewport.getHiddenRepSequences());
3550 * Actions on setting or changing the alignment colour scheme
3555 public void changeColour(ColourSchemeI cs)
3557 // TODO: pull up to controller method
3558 ColourMenuHelper.setColourSelected(colourMenu, cs);
3560 viewport.setGlobalColourScheme(cs);
3562 alignPanel.paintAlignment(true, true);
3566 * Show the PID threshold slider panel
3569 protected void modifyPID_actionPerformed()
3571 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3572 alignPanel.getViewName());
3573 SliderPanel.showPIDSlider();
3577 * Show the Conservation slider panel
3580 protected void modifyConservation_actionPerformed()
3582 SliderPanel.setConservationSlider(alignPanel,
3583 viewport.getResidueShading(), alignPanel.getViewName());
3584 SliderPanel.showConservationSlider();
3588 * Action on selecting or deselecting (Colour) By Conservation
3591 public void conservationMenuItem_actionPerformed(boolean selected)
3593 modifyConservation.setEnabled(selected);
3594 viewport.setConservationSelected(selected);
3595 viewport.getResidueShading().setConservationApplied(selected);
3597 changeColour(viewport.getGlobalColourScheme());
3600 modifyConservation_actionPerformed();
3604 SliderPanel.hideConservationSlider();
3609 * Action on selecting or deselecting (Colour) Above PID Threshold
3612 public void abovePIDThreshold_actionPerformed(boolean selected)
3614 modifyPID.setEnabled(selected);
3615 viewport.setAbovePIDThreshold(selected);
3618 viewport.getResidueShading().setThreshold(0,
3619 viewport.isIgnoreGapsConsensus());
3622 changeColour(viewport.getGlobalColourScheme());
3625 modifyPID_actionPerformed();
3629 SliderPanel.hidePIDSlider();
3640 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3642 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3643 AlignmentSorter.sortByPID(viewport.getAlignment(),
3644 viewport.getAlignment().getSequenceAt(0));
3645 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3646 viewport.getAlignment()));
3647 alignPanel.paintAlignment(true, false);
3657 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3659 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3660 AlignmentSorter.sortByID(viewport.getAlignment());
3662 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3663 alignPanel.paintAlignment(true, false);
3673 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3675 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3676 AlignmentSorter.sortByLength(viewport.getAlignment());
3677 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3678 viewport.getAlignment()));
3679 alignPanel.paintAlignment(true, false);
3689 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3691 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3692 AlignmentSorter.sortByGroup(viewport.getAlignment());
3693 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3694 viewport.getAlignment()));
3696 alignPanel.paintAlignment(true, false);
3706 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3708 new RedundancyPanel(alignPanel, this);
3718 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3720 if ((viewport.getSelectionGroup() == null)
3721 || (viewport.getSelectionGroup().getSize() < 2))
3723 JvOptionPane.showInternalMessageDialog(this,
3724 MessageManager.getString(
3725 "label.you_must_select_least_two_sequences"),
3726 MessageManager.getString("label.invalid_selection"),
3727 JvOptionPane.WARNING_MESSAGE);
3731 JInternalFrame frame = new JInternalFrame();
3732 frame.setContentPane(new PairwiseAlignPanel(viewport));
3733 Desktop.addInternalFrame(frame,
3734 MessageManager.getString("action.pairwise_alignment"), 600,
3740 public void autoCalculate_actionPerformed(ActionEvent e)
3742 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3743 if (viewport.autoCalculateConsensus)
3745 viewport.firePropertyChange("alignment", null,
3746 viewport.getAlignment().getSequences());
3751 public void sortByTreeOption_actionPerformed(ActionEvent e)
3753 viewport.sortByTree = sortByTree.isSelected();
3757 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3759 viewport.followSelection = listenToViewSelections.isSelected();
3763 * Constructs a tree panel and adds it to the desktop
3766 * tree type (NJ or AV)
3768 * name of score model used to compute the tree
3770 * parameters for the distance or similarity calculation
3772 void newTreePanel(String type, String modelName,
3773 SimilarityParamsI options)
3775 String frameTitle = "";
3778 boolean onSelection = false;
3779 if (viewport.getSelectionGroup() != null
3780 && viewport.getSelectionGroup().getSize() > 0)
3782 SequenceGroup sg = viewport.getSelectionGroup();
3784 /* Decide if the selection is a column region */
3785 for (SequenceI _s : sg.getSequences())
3787 if (_s.getLength() < sg.getEndRes())
3789 JvOptionPane.showMessageDialog(Desktop.desktop,
3790 MessageManager.getString(
3791 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3792 MessageManager.getString(
3793 "label.sequences_selection_not_aligned"),
3794 JvOptionPane.WARNING_MESSAGE);
3803 if (viewport.getAlignment().getHeight() < 2)
3809 tp = new TreePanel(alignPanel, type, modelName, options);
3810 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3812 frameTitle += " from ";
3814 if (viewport.getViewName() != null)
3816 frameTitle += viewport.getViewName() + " of ";
3819 frameTitle += this.title;
3821 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3832 public void addSortByOrderMenuItem(String title,
3833 final AlignmentOrder order)
3835 final JMenuItem item = new JMenuItem(MessageManager
3836 .formatMessage("action.by_title_param", new Object[]
3839 item.addActionListener(new java.awt.event.ActionListener()
3842 public void actionPerformed(ActionEvent e)
3844 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3846 // TODO: JBPNote - have to map order entries to curent SequenceI
3848 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3850 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3851 viewport.getAlignment()));
3853 alignPanel.paintAlignment(true, false);
3859 * Add a new sort by annotation score menu item
3862 * the menu to add the option to
3864 * the label used to retrieve scores for each sequence on the
3867 public void addSortByAnnotScoreMenuItem(JMenu sort,
3868 final String scoreLabel)
3870 final JMenuItem item = new JMenuItem(scoreLabel);
3872 item.addActionListener(new java.awt.event.ActionListener()
3875 public void actionPerformed(ActionEvent e)
3877 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3878 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3879 viewport.getAlignment());// ,viewport.getSelectionGroup());
3880 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3881 viewport.getAlignment()));
3882 alignPanel.paintAlignment(true, false);
3888 * last hash for alignment's annotation array - used to minimise cost of
3891 protected int _annotationScoreVectorHash;
3894 * search the alignment and rebuild the sort by annotation score submenu the
3895 * last alignment annotation vector hash is stored to minimize cost of
3896 * rebuilding in subsequence calls.
3900 public void buildSortByAnnotationScoresMenu()
3902 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3907 if (viewport.getAlignment().getAlignmentAnnotation()
3908 .hashCode() != _annotationScoreVectorHash)
3910 sortByAnnotScore.removeAll();
3911 // almost certainly a quicker way to do this - but we keep it simple
3912 Hashtable<String, String> scoreSorts = new Hashtable<>();
3913 AlignmentAnnotation aann[];
3914 for (SequenceI sqa : viewport.getAlignment().getSequences())
3916 aann = sqa.getAnnotation();
3917 for (int i = 0; aann != null && i < aann.length; i++)
3919 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3921 scoreSorts.put(aann[i].label, aann[i].label);
3925 Enumeration<String> labels = scoreSorts.keys();
3926 while (labels.hasMoreElements())
3928 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3930 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3933 _annotationScoreVectorHash = viewport.getAlignment()
3934 .getAlignmentAnnotation().hashCode();
3939 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3940 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3941 * call. Listeners are added to remove the menu item when the treePanel is
3942 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3946 public void buildTreeSortMenu()
3948 sortByTreeMenu.removeAll();
3950 List<Component> comps = PaintRefresher.components
3951 .get(viewport.getSequenceSetId());
3952 List<TreePanel> treePanels = new ArrayList<>();
3953 for (Component comp : comps)
3955 if (comp instanceof TreePanel)
3957 treePanels.add((TreePanel) comp);
3961 if (treePanels.size() < 1)
3963 sortByTreeMenu.setVisible(false);
3967 sortByTreeMenu.setVisible(true);
3969 for (final TreePanel tp : treePanels)
3971 final JMenuItem item = new JMenuItem(tp.getTitle());
3972 item.addActionListener(new java.awt.event.ActionListener()
3975 public void actionPerformed(ActionEvent e)
3977 tp.sortByTree_actionPerformed();
3978 addHistoryItem(tp.sortAlignmentIn(alignPanel));
3983 sortByTreeMenu.add(item);
3987 public boolean sortBy(AlignmentOrder alorder, String undoname)
3989 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3990 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
3991 if (undoname != null)
3993 addHistoryItem(new OrderCommand(undoname, oldOrder,
3994 viewport.getAlignment()));
3996 alignPanel.paintAlignment(true, false);
4001 * Work out whether the whole set of sequences or just the selected set will
4002 * be submitted for multiple alignment.
4005 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4007 // Now, check we have enough sequences
4008 AlignmentView msa = null;
4010 if ((viewport.getSelectionGroup() != null)
4011 && (viewport.getSelectionGroup().getSize() > 1))
4013 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4014 // some common interface!
4016 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4017 * SequenceI[sz = seqs.getSize(false)];
4019 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4020 * seqs.getSequenceAt(i); }
4022 msa = viewport.getAlignmentView(true);
4024 else if (viewport.getSelectionGroup() != null
4025 && viewport.getSelectionGroup().getSize() == 1)
4027 int option = JvOptionPane.showConfirmDialog(this,
4028 MessageManager.getString("warn.oneseq_msainput_selection"),
4029 MessageManager.getString("label.invalid_selection"),
4030 JvOptionPane.OK_CANCEL_OPTION);
4031 if (option == JvOptionPane.OK_OPTION)
4033 msa = viewport.getAlignmentView(false);
4038 msa = viewport.getAlignmentView(false);
4044 * Decides what is submitted to a secondary structure prediction service: the
4045 * first sequence in the alignment, or in the current selection, or, if the
4046 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4047 * region or the whole alignment. (where the first sequence in the set is the
4048 * one that the prediction will be for).
4050 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4052 AlignmentView seqs = null;
4054 if ((viewport.getSelectionGroup() != null)
4055 && (viewport.getSelectionGroup().getSize() > 0))
4057 seqs = viewport.getAlignmentView(true);
4061 seqs = viewport.getAlignmentView(false);
4063 // limit sequences - JBPNote in future - could spawn multiple prediction
4065 // TODO: viewport.getAlignment().isAligned is a global state - the local
4066 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4067 if (!viewport.getAlignment().isAligned(false))
4069 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4070 // TODO: if seqs.getSequences().length>1 then should really have warned
4084 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4086 // Pick the tree file
4087 JalviewFileChooser chooser = new JalviewFileChooser(
4088 Cache.getProperty("LAST_DIRECTORY"));
4089 chooser.setFileView(new JalviewFileView());
4090 chooser.setDialogTitle(
4091 MessageManager.getString("label.select_newick_like_tree_file"));
4092 chooser.setToolTipText(
4093 MessageManager.getString("label.load_tree_file"));
4095 chooser.setResponseHandler(0, () -> {
4096 String filePath = chooser.getSelectedFile().getPath();
4097 Cache.setProperty("LAST_DIRECTORY", filePath);
4098 NewickFile fin = null;
4101 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4102 DataSourceType.FILE));
4103 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4104 } catch (Exception ex)
4106 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4107 MessageManager.getString("label.problem_reading_tree_file"),
4108 JvOptionPane.WARNING_MESSAGE);
4109 ex.printStackTrace();
4111 if (fin != null && fin.hasWarningMessage())
4113 JvOptionPane.showMessageDialog(Desktop.desktop,
4114 fin.getWarningMessage(),
4116 .getString("label.possible_problem_with_tree_file"),
4117 JvOptionPane.WARNING_MESSAGE);
4121 chooser.showOpenDialog(this);
4124 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4126 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4129 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4130 int h, int x, int y)
4132 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4137 * Add a treeviewer for the tree extracted from a Newick file object to the
4138 * current alignment view
4145 * Associated alignment input data (or null)
4154 * @return TreePanel handle
4156 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4157 AlignmentView input, int w, int h, int x, int y)
4159 TreePanel tp = null;
4165 if (nf.getTree() != null)
4167 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4173 tp.setLocation(x, y);
4176 Desktop.addInternalFrame(tp, treeTitle, w, h);
4178 } catch (Exception ex)
4180 ex.printStackTrace();
4187 public void showContactMapTree(AlignmentAnnotation aa,
4188 PAEContactMatrix cm)
4191 int w = 400, h = 500;
4195 NewickFile fin = new NewickFile(
4196 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4197 String title = "PAE Matrix Tree for "
4198 + cm.getReferenceSeq().getDisplayId(false);
4200 showColumnWiseTree(fin, aa, title, w,h, x,y);
4201 } catch (Throwable xx)
4203 Console.error("Unexpected exception showing tree for contact matrix",
4207 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa, String treeTitle,
4208 int w, int h, int x, int y)
4213 if (nf.getTree() == null)
4217 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4223 tp.setLocation(x, y);
4226 Desktop.addInternalFrame(tp, title, w, h);
4228 } catch (Throwable xx)
4230 Console.error("Unexpected exception showing tree for contact matrix",
4236 private boolean buildingMenu = false;
4239 * Generates menu items and listener event actions for web service clients
4242 public void BuildWebServiceMenu()
4244 while (buildingMenu)
4248 System.err.println("Waiting for building menu to finish.");
4250 } catch (Exception e)
4254 final AlignFrame me = this;
4255 buildingMenu = true;
4256 new Thread(new Runnable()
4261 final List<JMenuItem> legacyItems = new ArrayList<>();
4264 // System.err.println("Building ws menu again "
4265 // + Thread.currentThread());
4266 // TODO: add support for context dependent disabling of services based
4268 // alignment and current selection
4269 // TODO: add additional serviceHandle parameter to specify abstract
4271 // class independently of AbstractName
4272 // TODO: add in rediscovery GUI function to restart discoverer
4273 // TODO: group services by location as well as function and/or
4275 // object broker mechanism.
4276 final Vector<JMenu> wsmenu = new Vector<>();
4277 final IProgressIndicator af = me;
4280 * do not i18n these strings - they are hard-coded in class
4281 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4282 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4284 final JMenu msawsmenu = new JMenu("Alignment");
4285 final JMenu secstrmenu = new JMenu(
4286 "Secondary Structure Prediction");
4287 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4288 final JMenu analymenu = new JMenu("Analysis");
4289 final JMenu dismenu = new JMenu("Protein Disorder");
4290 // JAL-940 - only show secondary structure prediction services from
4291 // the legacy server
4292 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4294 Discoverer.services != null && (Discoverer.services.size() > 0))
4296 // TODO: refactor to allow list of AbstractName/Handler bindings to
4298 // stored or retrieved from elsewhere
4299 // No MSAWS used any more:
4300 // Vector msaws = null; // (Vector)
4301 // Discoverer.services.get("MsaWS");
4302 Vector<ServiceHandle> secstrpr = Discoverer.services
4304 if (secstrpr != null)
4306 // Add any secondary structure prediction services
4307 for (int i = 0, j = secstrpr.size(); i < j; i++)
4309 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4310 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4311 .getServiceClient(sh);
4312 int p = secstrmenu.getItemCount();
4313 impl.attachWSMenuEntry(secstrmenu, me);
4314 int q = secstrmenu.getItemCount();
4315 for (int litm = p; litm < q; litm++)
4317 legacyItems.add(secstrmenu.getItem(litm));
4323 // Add all submenus in the order they should appear on the web
4325 wsmenu.add(msawsmenu);
4326 wsmenu.add(secstrmenu);
4327 wsmenu.add(dismenu);
4328 wsmenu.add(analymenu);
4329 // No search services yet
4330 // wsmenu.add(seqsrchmenu);
4332 javax.swing.SwingUtilities.invokeLater(new Runnable()
4339 webService.removeAll();
4340 // first, add discovered services onto the webservices menu
4341 if (wsmenu.size() > 0)
4343 for (int i = 0, j = wsmenu.size(); i < j; i++)
4345 webService.add(wsmenu.get(i));
4350 webService.add(me.webServiceNoServices);
4352 // TODO: move into separate menu builder class.
4354 // logic for 2.11.1.4 is
4355 // always look to see if there is a discover. if there isn't
4356 // we can't show any Jws2 services
4357 // if there are services available, show them - regardless of
4358 // the 'show JWS2 preference'
4359 // if the discoverer is running then say so
4360 // otherwise offer to trigger discovery if 'show JWS2' is not
4362 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4363 if (jws2servs != null)
4365 if (jws2servs.hasServices())
4367 jws2servs.attachWSMenuEntry(webService, me);
4368 for (Jws2Instance sv : jws2servs.getServices())
4370 if (sv.description.toLowerCase(Locale.ROOT)
4373 for (JMenuItem jmi : legacyItems)
4375 jmi.setVisible(false);
4381 if (jws2servs.isRunning())
4383 JMenuItem tm = new JMenuItem(
4384 "Still discovering JABA Services");
4385 tm.setEnabled(false);
4388 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4390 JMenuItem enableJws2 = new JMenuItem(
4391 "Discover Web Services");
4392 enableJws2.setToolTipText(
4393 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4394 enableJws2.setEnabled(true);
4395 enableJws2.addActionListener(new ActionListener()
4399 public void actionPerformed(ActionEvent e)
4401 // start service discoverer, but ignore preference
4402 Desktop.instance.startServiceDiscovery(false,
4406 webService.add(enableJws2);
4410 build_urlServiceMenu(me.webService);
4411 build_fetchdbmenu(webService);
4412 for (JMenu item : wsmenu)
4414 if (item.getItemCount() == 0)
4416 item.setEnabled(false);
4420 item.setEnabled(true);
4423 } catch (Exception e)
4426 "Exception during web service menu building process.",
4431 } catch (Exception e)
4434 buildingMenu = false;
4441 * construct any groupURL type service menu entries.
4445 protected void build_urlServiceMenu(JMenu webService)
4447 // TODO: remove this code when 2.7 is released
4448 // DEBUG - alignmentView
4450 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4451 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4453 * @Override public void actionPerformed(ActionEvent e) {
4454 * jalview.datamodel.AlignmentView
4455 * .testSelectionViews(af.viewport.getAlignment(),
4456 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4458 * }); webService.add(testAlView);
4460 // TODO: refactor to RestClient discoverer and merge menu entries for
4461 // rest-style services with other types of analysis/calculation service
4462 // SHmmr test client - still being implemented.
4463 // DEBUG - alignmentView
4465 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4468 client.attachWSMenuEntry(
4469 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4475 * Searches the alignment sequences for xRefs and builds the Show
4476 * Cross-References menu (formerly called Show Products), with database
4477 * sources for which cross-references are found (protein sources for a
4478 * nucleotide alignment and vice versa)
4480 * @return true if Show Cross-references menu should be enabled
4482 public boolean canShowProducts()
4484 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4485 AlignmentI dataset = viewport.getAlignment().getDataset();
4487 showProducts.removeAll();
4488 final boolean dna = viewport.getAlignment().isNucleotide();
4490 if (seqs == null || seqs.length == 0)
4492 // nothing to see here.
4496 boolean showp = false;
4499 List<String> ptypes = new CrossRef(seqs, dataset)
4500 .findXrefSourcesForSequences(dna);
4502 for (final String source : ptypes)
4505 final AlignFrame af = this;
4506 JMenuItem xtype = new JMenuItem(source);
4507 xtype.addActionListener(new ActionListener()
4510 public void actionPerformed(ActionEvent e)
4512 showProductsFor(af.viewport.getSequenceSelection(), dna,
4516 showProducts.add(xtype);
4518 showProducts.setVisible(showp);
4519 showProducts.setEnabled(showp);
4520 } catch (Exception e)
4523 "canShowProducts threw an exception - please report to help@jalview.org",
4531 * Finds and displays cross-references for the selected sequences (protein
4532 * products for nucleotide sequences, dna coding sequences for peptides).
4535 * the sequences to show cross-references for
4537 * true if from a nucleotide alignment (so showing proteins)
4539 * the database to show cross-references for
4541 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4542 final String source)
4544 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4549 * Construct and display a new frame containing the translation of this
4550 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4553 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4555 AlignmentI al = null;
4558 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4560 al = dna.translateCdna(codeTable);
4561 } catch (Exception ex)
4563 Console.error("Exception during translation. Please report this !",
4565 final String msg = MessageManager.getString(
4566 "label.error_when_translating_sequences_submit_bug_report");
4567 final String errorTitle = MessageManager
4568 .getString("label.implementation_error")
4569 + MessageManager.getString("label.translation_failed");
4570 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4571 JvOptionPane.ERROR_MESSAGE);
4574 if (al == null || al.getHeight() == 0)
4576 final String msg = MessageManager.getString(
4577 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4578 final String errorTitle = MessageManager
4579 .getString("label.translation_failed");
4580 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4581 JvOptionPane.WARNING_MESSAGE);
4585 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4586 af.setFileFormat(this.currentFileFormat);
4587 final String newTitle = MessageManager
4588 .formatMessage("label.translation_of_params", new Object[]
4589 { this.getTitle(), codeTable.getId() });
4590 af.setTitle(newTitle);
4591 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4593 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4594 viewport.openSplitFrame(af, new Alignment(seqs));
4598 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4605 * Set the file format
4609 public void setFileFormat(FileFormatI format)
4611 this.currentFileFormat = format;
4615 * Try to load a features file onto the alignment.
4618 * contents or path to retrieve file or a File object
4620 * access mode of file (see jalview.io.AlignFile)
4621 * @return true if features file was parsed correctly.
4623 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4626 return avc.parseFeaturesFile(file, sourceType,
4627 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4632 public void refreshFeatureUI(boolean enableIfNecessary)
4634 // note - currently this is only still here rather than in the controller
4635 // because of the featureSettings hard reference that is yet to be
4637 if (enableIfNecessary)
4639 viewport.setShowSequenceFeatures(true);
4640 showSeqFeatures.setSelected(true);
4646 public void dragEnter(DropTargetDragEvent evt)
4651 public void dragExit(DropTargetEvent evt)
4656 public void dragOver(DropTargetDragEvent evt)
4661 public void dropActionChanged(DropTargetDragEvent evt)
4666 public void drop(DropTargetDropEvent evt)
4668 // JAL-1552 - acceptDrop required before getTransferable call for
4669 // Java's Transferable for native dnd
4670 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4671 Transferable t = evt.getTransferable();
4673 final AlignFrame thisaf = this;
4674 final List<Object> files = new ArrayList<>();
4675 List<DataSourceType> protocols = new ArrayList<>();
4679 Desktop.transferFromDropTarget(files, protocols, evt, t);
4680 } catch (Exception e)
4682 e.printStackTrace();
4686 new Thread(new Runnable()
4693 // check to see if any of these files have names matching sequences
4696 SequenceIdMatcher idm = new SequenceIdMatcher(
4697 viewport.getAlignment().getSequencesArray());
4699 * Object[] { String,SequenceI}
4701 ArrayList<Object[]> filesmatched = new ArrayList<>();
4702 ArrayList<Object> filesnotmatched = new ArrayList<>();
4703 for (int i = 0; i < files.size(); i++)
4706 Object file = files.get(i);
4707 String fileName = file.toString();
4709 DataSourceType protocol = (file instanceof File
4710 ? DataSourceType.FILE
4711 : FormatAdapter.checkProtocol(fileName));
4712 if (protocol == DataSourceType.FILE)
4715 if (file instanceof File)
4718 Platform.cacheFileData(fl);
4722 fl = new File(fileName);
4724 pdbfn = fl.getName();
4726 else if (protocol == DataSourceType.URL)
4728 URL url = new URL(fileName);
4729 pdbfn = url.getFile();
4731 if (pdbfn.length() > 0)
4733 // attempt to find a match in the alignment
4734 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4735 int l = 0, c = pdbfn.indexOf(".");
4736 while (mtch == null && c != -1)
4741 } while ((c = pdbfn.indexOf(".", l)) > l);
4744 pdbfn = pdbfn.substring(0, l);
4746 mtch = idm.findAllIdMatches(pdbfn);
4753 type = new IdentifyFile().identify(file, protocol);
4754 } catch (Exception ex)
4758 if (type != null && type.isStructureFile())
4760 filesmatched.add(new Object[] { file, protocol, mtch });
4764 // File wasn't named like one of the sequences or wasn't a PDB
4766 filesnotmatched.add(file);
4770 if (filesmatched.size() > 0)
4772 boolean autoAssociate = Cache
4773 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4776 String msg = MessageManager.formatMessage(
4777 "label.automatically_associate_structure_files_with_sequences_same_name",
4779 { Integer.valueOf(filesmatched.size())
4781 String ttl = MessageManager.getString(
4782 "label.automatically_associate_structure_files_by_name");
4783 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4784 ttl, JvOptionPane.YES_NO_OPTION);
4785 autoAssociate = choice == JvOptionPane.YES_OPTION;
4789 for (Object[] fm : filesmatched)
4791 // try and associate
4792 // TODO: may want to set a standard ID naming formalism for
4793 // associating PDB files which have no IDs.
4794 for (SequenceI toassoc : (SequenceI[]) fm[2])
4796 PDBEntry pe = new AssociatePdbFileWithSeq()
4797 .associatePdbWithSeq(fm[0].toString(),
4798 (DataSourceType) fm[1], toassoc, false,
4802 System.err.println("Associated file : "
4803 + (fm[0].toString()) + " with "
4804 + toassoc.getDisplayId(true));
4808 // TODO: do we need to update overview ? only if features are
4810 alignPanel.paintAlignment(true, false);
4816 * add declined structures as sequences
4818 for (Object[] o : filesmatched)
4820 filesnotmatched.add(o[0]);
4824 if (filesnotmatched.size() > 0)
4826 if (assocfiles > 0 && (Cache.getDefault(
4827 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4828 || JvOptionPane.showConfirmDialog(thisaf,
4829 "<html>" + MessageManager.formatMessage(
4830 "label.ignore_unmatched_dropped_files_info",
4833 filesnotmatched.size())
4836 MessageManager.getString(
4837 "label.ignore_unmatched_dropped_files"),
4838 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4842 for (Object fn : filesnotmatched)
4844 loadJalviewDataFile(fn, null, null, null);
4848 } catch (Exception ex)
4850 ex.printStackTrace();
4858 * Attempt to load a "dropped" file or URL string, by testing in turn for
4860 * <li>an Annotation file</li>
4861 * <li>a JNet file</li>
4862 * <li>a features file</li>
4863 * <li>else try to interpret as an alignment file</li>
4867 * either a filename or a URL string.
4869 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4870 FileFormatI format, SequenceI assocSeq)
4872 // BH 2018 was String file
4875 if (sourceType == null)
4877 sourceType = FormatAdapter.checkProtocol(file);
4879 // if the file isn't identified, or not positively identified as some
4880 // other filetype (PFAM is default unidentified alignment file type) then
4881 // try to parse as annotation.
4882 boolean isAnnotation = (format == null
4883 || FileFormat.Pfam.equals(format))
4884 ? new AnnotationFile().annotateAlignmentView(viewport,
4890 // first see if its a T-COFFEE score file
4891 TCoffeeScoreFile tcf = null;
4894 tcf = new TCoffeeScoreFile(file, sourceType);
4897 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4901 new TCoffeeColourScheme(viewport.getAlignment()));
4902 isAnnotation = true;
4903 setStatus(MessageManager.getString(
4904 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4908 // some problem - if no warning its probable that the ID matching
4909 // process didn't work
4910 JvOptionPane.showMessageDialog(Desktop.desktop,
4911 tcf.getWarningMessage() == null
4912 ? MessageManager.getString(
4913 "label.check_file_matches_sequence_ids_alignment")
4914 : tcf.getWarningMessage(),
4915 MessageManager.getString(
4916 "label.problem_reading_tcoffee_score_file"),
4917 JvOptionPane.WARNING_MESSAGE);
4924 } catch (Exception x)
4927 "Exception when processing data source as T-COFFEE score file",
4933 // try to see if its a JNet 'concise' style annotation file *before*
4935 // try to parse it as a features file
4938 format = new IdentifyFile().identify(file, sourceType);
4940 if (FileFormat.ScoreMatrix == format)
4942 ScoreMatrixFile sm = new ScoreMatrixFile(
4943 new FileParse(file, sourceType));
4945 // todo: i18n this message
4946 setStatus(MessageManager.formatMessage(
4947 "label.successfully_loaded_matrix",
4948 sm.getMatrixName()));
4950 else if (FileFormat.Jnet.equals(format))
4952 JPredFile predictions = new JPredFile(file, sourceType);
4953 new JnetAnnotationMaker();
4954 JnetAnnotationMaker.add_annotation(predictions,
4955 viewport.getAlignment(), 0, false);
4956 viewport.getAlignment().setupJPredAlignment();
4957 isAnnotation = true;
4959 // else if (IdentifyFile.FeaturesFile.equals(format))
4960 else if (FileFormat.Features.equals(format))
4962 if (parseFeaturesFile(file, sourceType))
4964 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
4965 if (splitFrame != null)
4967 splitFrame.repaint();
4971 alignPanel.paintAlignment(true, true);
4977 new FileLoader().LoadFile(viewport, file, sourceType, format);
4984 alignPanel.adjustAnnotationHeight();
4985 viewport.updateSequenceIdColours();
4986 buildSortByAnnotationScoresMenu();
4987 alignPanel.paintAlignment(true, true);
4989 } catch (Exception ex)
4991 ex.printStackTrace();
4992 } catch (OutOfMemoryError oom)
4997 } catch (Exception x)
5002 + (sourceType != null
5003 ? (sourceType == DataSourceType.PASTE
5005 : "using " + sourceType + " from "
5009 ? "(parsing as '" + format + "' file)"
5011 oom, Desktop.desktop);
5016 * Method invoked by the ChangeListener on the tabbed pane, in other words
5017 * when a different tabbed pane is selected by the user or programmatically.
5020 public void tabSelectionChanged(int index)
5025 * update current Overview window title (if there is one)
5026 * to add view name "Original" if necessary
5028 alignPanel.setOverviewTitle(this);
5031 * switch panels and set Overview title (if there is one
5032 * because it was opened automatically)
5034 alignPanel = alignPanels.get(index);
5035 alignPanel.setOverviewTitle(this);
5037 viewport = alignPanel.av;
5038 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5039 setMenusFromViewport(viewport);
5040 if (featureSettings != null && featureSettings.isOpen()
5041 && featureSettings.fr.getViewport() != viewport)
5043 if (viewport.isShowSequenceFeatures())
5045 // refresh the featureSettings to reflect UI change
5046 showFeatureSettingsUI();
5050 // close feature settings for this view.
5051 featureSettings.close();
5058 * 'focus' any colour slider that is open to the selected viewport
5060 if (viewport.getConservationSelected())
5062 SliderPanel.setConservationSlider(alignPanel,
5063 viewport.getResidueShading(), alignPanel.getViewName());
5067 SliderPanel.hideConservationSlider();
5069 if (viewport.getAbovePIDThreshold())
5071 SliderPanel.setPIDSliderSource(alignPanel,
5072 viewport.getResidueShading(), alignPanel.getViewName());
5076 SliderPanel.hidePIDSlider();
5080 * If there is a frame linked to this one in a SplitPane, switch it to the
5081 * same view tab index. No infinite recursion of calls should happen, since
5082 * tabSelectionChanged() should not get invoked on setting the selected
5083 * index to an unchanged value. Guard against setting an invalid index
5084 * before the new view peer tab has been created.
5086 final AlignViewportI peer = viewport.getCodingComplement();
5089 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5090 .getAlignPanel().alignFrame;
5091 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5093 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5099 * On right mouse click on view tab, prompt for and set new view name.
5102 public void tabbedPane_mousePressed(MouseEvent e)
5104 if (e.isPopupTrigger())
5106 String msg = MessageManager.getString("label.enter_view_name");
5107 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5108 String reply = JvOptionPane.showInputDialog(msg, ttl);
5112 viewport.setViewName(reply);
5113 // TODO warn if reply is in getExistingViewNames()?
5114 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5119 public AlignViewport getCurrentView()
5125 * Open the dialog for regex description parsing.
5128 protected void extractScores_actionPerformed(ActionEvent e)
5130 ParseProperties pp = new jalview.analysis.ParseProperties(
5131 viewport.getAlignment());
5132 // TODO: verify regex and introduce GUI dialog for version 2.5
5133 // if (pp.getScoresFromDescription("col", "score column ",
5134 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5136 if (pp.getScoresFromDescription("description column",
5137 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5139 buildSortByAnnotationScoresMenu();
5147 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5151 protected void showDbRefs_actionPerformed(ActionEvent e)
5153 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5159 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5163 protected void showNpFeats_actionPerformed(ActionEvent e)
5165 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5169 * find the viewport amongst the tabs in this alignment frame and close that
5174 public boolean closeView(AlignViewportI av)
5178 this.closeMenuItem_actionPerformed(false);
5181 Component[] comp = tabbedPane.getComponents();
5182 for (int i = 0; comp != null && i < comp.length; i++)
5184 if (comp[i] instanceof AlignmentPanel)
5186 if (((AlignmentPanel) comp[i]).av == av)
5189 closeView((AlignmentPanel) comp[i]);
5197 protected void build_fetchdbmenu(JMenu webService)
5199 // Temporary hack - DBRef Fetcher always top level ws entry.
5200 // TODO We probably want to store a sequence database checklist in
5201 // preferences and have checkboxes.. rather than individual sources selected
5203 final JMenu rfetch = new JMenu(
5204 MessageManager.getString("action.fetch_db_references"));
5205 rfetch.setToolTipText(MessageManager.getString(
5206 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5207 webService.add(rfetch);
5209 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5210 MessageManager.getString("option.trim_retrieved_seqs"));
5211 trimrs.setToolTipText(
5212 MessageManager.getString("label.trim_retrieved_sequences"));
5214 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5215 trimrs.addActionListener(new ActionListener()
5218 public void actionPerformed(ActionEvent e)
5220 trimrs.setSelected(trimrs.isSelected());
5221 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5222 Boolean.valueOf(trimrs.isSelected()).toString());
5226 JMenuItem fetchr = new JMenuItem(
5227 MessageManager.getString("label.standard_databases"));
5228 fetchr.setToolTipText(
5229 MessageManager.getString("label.fetch_embl_uniprot"));
5230 fetchr.addActionListener(new ActionListener()
5234 public void actionPerformed(ActionEvent e)
5236 new Thread(new Runnable()
5241 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5242 .getAlignment().isNucleotide();
5243 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5244 alignPanel.av.getSequenceSelection(),
5245 alignPanel.alignFrame, null,
5246 alignPanel.alignFrame.featureSettings, isNucleotide);
5247 dbRefFetcher.addListener(new FetchFinishedListenerI()
5250 public void finished()
5253 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5254 .getFeatureSettingsModels())
5257 alignPanel.av.mergeFeaturesStyle(srcSettings);
5259 AlignFrame.this.setMenusForViewport();
5262 dbRefFetcher.fetchDBRefs(false);
5270 new Thread(new Runnable()
5275 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5276 .getSequenceFetcherSingleton();
5277 javax.swing.SwingUtilities.invokeLater(new Runnable()
5282 String[] dbclasses = sf.getNonAlignmentSources();
5283 List<DbSourceProxy> otherdb;
5284 JMenu dfetch = new JMenu();
5285 JMenu ifetch = new JMenu();
5286 JMenuItem fetchr = null;
5287 int comp = 0, icomp = 0, mcomp = 15;
5288 String mname = null;
5290 for (String dbclass : dbclasses)
5292 otherdb = sf.getSourceProxy(dbclass);
5293 // add a single entry for this class, or submenu allowing 'fetch
5295 if (otherdb == null || otherdb.size() < 1)
5301 mname = "From " + dbclass;
5303 if (otherdb.size() == 1)
5305 final DbSourceProxy[] dassource = otherdb
5306 .toArray(new DbSourceProxy[0]);
5307 DbSourceProxy src = otherdb.get(0);
5308 fetchr = new JMenuItem(src.getDbSource());
5309 fetchr.addActionListener(new ActionListener()
5313 public void actionPerformed(ActionEvent e)
5315 new Thread(new Runnable()
5321 boolean isNucleotide = alignPanel.alignFrame
5322 .getViewport().getAlignment()
5324 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5325 alignPanel.av.getSequenceSelection(),
5326 alignPanel.alignFrame, dassource,
5327 alignPanel.alignFrame.featureSettings,
5330 .addListener(new FetchFinishedListenerI()
5333 public void finished()
5335 FeatureSettingsModelI srcSettings = dassource[0]
5336 .getFeatureColourScheme();
5337 alignPanel.av.mergeFeaturesStyle(
5339 AlignFrame.this.setMenusForViewport();
5342 dbRefFetcher.fetchDBRefs(false);
5348 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5349 MessageManager.formatMessage(
5350 "label.fetch_retrieve_from", new Object[]
5351 { src.getDbName() })));
5357 final DbSourceProxy[] dassource = otherdb
5358 .toArray(new DbSourceProxy[0]);
5360 DbSourceProxy src = otherdb.get(0);
5361 fetchr = new JMenuItem(MessageManager
5362 .formatMessage("label.fetch_all_param", new Object[]
5363 { src.getDbSource() }));
5364 fetchr.addActionListener(new ActionListener()
5367 public void actionPerformed(ActionEvent e)
5369 new Thread(new Runnable()
5375 boolean isNucleotide = alignPanel.alignFrame
5376 .getViewport().getAlignment()
5378 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5379 alignPanel.av.getSequenceSelection(),
5380 alignPanel.alignFrame, dassource,
5381 alignPanel.alignFrame.featureSettings,
5384 .addListener(new FetchFinishedListenerI()
5387 public void finished()
5389 AlignFrame.this.setMenusForViewport();
5392 dbRefFetcher.fetchDBRefs(false);
5398 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5399 MessageManager.formatMessage(
5400 "label.fetch_retrieve_from_all_sources",
5402 { Integer.valueOf(otherdb.size())
5404 src.getDbSource(), src.getDbName() })));
5407 // and then build the rest of the individual menus
5408 ifetch = new JMenu(MessageManager.formatMessage(
5409 "label.source_from_db_source", new Object[]
5410 { src.getDbSource() }));
5412 String imname = null;
5414 for (DbSourceProxy sproxy : otherdb)
5416 String dbname = sproxy.getDbName();
5417 String sname = dbname.length() > 5
5418 ? dbname.substring(0, 5) + "..."
5420 String msname = dbname.length() > 10
5421 ? dbname.substring(0, 10) + "..."
5425 imname = MessageManager
5426 .formatMessage("label.from_msname", new Object[]
5429 fetchr = new JMenuItem(msname);
5430 final DbSourceProxy[] dassrc = { sproxy };
5431 fetchr.addActionListener(new ActionListener()
5435 public void actionPerformed(ActionEvent e)
5437 new Thread(new Runnable()
5443 boolean isNucleotide = alignPanel.alignFrame
5444 .getViewport().getAlignment()
5446 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5447 alignPanel.av.getSequenceSelection(),
5448 alignPanel.alignFrame, dassrc,
5449 alignPanel.alignFrame.featureSettings,
5452 .addListener(new FetchFinishedListenerI()
5455 public void finished()
5457 AlignFrame.this.setMenusForViewport();
5460 dbRefFetcher.fetchDBRefs(false);
5466 fetchr.setToolTipText(
5467 "<html>" + MessageManager.formatMessage(
5468 "label.fetch_retrieve_from", new Object[]
5472 if (++icomp >= mcomp || i == (otherdb.size()))
5474 ifetch.setText(MessageManager.formatMessage(
5475 "label.source_to_target", imname, sname));
5477 ifetch = new JMenu();
5485 if (comp >= mcomp || dbi >= (dbclasses.length))
5487 dfetch.setText(MessageManager.formatMessage(
5488 "label.source_to_target", mname, dbclass));
5490 dfetch = new JMenu();
5503 * Left justify the whole alignment.
5506 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5508 AlignmentI al = viewport.getAlignment();
5510 viewport.firePropertyChange("alignment", null, al);
5514 * Right justify the whole alignment.
5517 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5519 AlignmentI al = viewport.getAlignment();
5521 viewport.firePropertyChange("alignment", null, al);
5525 public void setShowSeqFeatures(boolean b)
5527 showSeqFeatures.setSelected(b);
5528 viewport.setShowSequenceFeatures(b);
5535 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5536 * awt.event.ActionEvent)
5539 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5541 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5542 alignPanel.paintAlignment(false, false);
5549 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5553 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5555 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5556 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5564 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5565 * .event.ActionEvent)
5568 protected void showGroupConservation_actionPerformed(ActionEvent e)
5570 viewport.setShowGroupConservation(showGroupConservation.getState());
5571 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5578 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5579 * .event.ActionEvent)
5582 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5584 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5585 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5592 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5593 * .event.ActionEvent)
5596 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5598 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5599 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5603 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5605 showSequenceLogo.setState(true);
5606 viewport.setShowSequenceLogo(true);
5607 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5608 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5612 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5614 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5621 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5622 * .event.ActionEvent)
5625 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5627 if (avc.makeGroupsFromSelection())
5629 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5630 alignPanel.updateAnnotation();
5631 alignPanel.paintAlignment(true,
5632 viewport.needToUpdateStructureViews());
5636 public void clearAlignmentSeqRep()
5638 // TODO refactor alignmentseqrep to controller
5639 if (viewport.getAlignment().hasSeqrep())
5641 viewport.getAlignment().setSeqrep(null);
5642 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5643 alignPanel.updateAnnotation();
5644 alignPanel.paintAlignment(true, true);
5649 protected void createGroup_actionPerformed(ActionEvent e)
5651 if (avc.createGroup())
5653 if (applyAutoAnnotationSettings.isSelected())
5655 alignPanel.updateAnnotation(true, false);
5657 alignPanel.alignmentChanged();
5662 protected void unGroup_actionPerformed(ActionEvent e)
5666 alignPanel.alignmentChanged();
5671 * make the given alignmentPanel the currently selected tab
5673 * @param alignmentPanel
5675 public void setDisplayedView(AlignmentPanel alignmentPanel)
5677 if (!viewport.getSequenceSetId()
5678 .equals(alignmentPanel.av.getSequenceSetId()))
5680 throw new Error(MessageManager.getString(
5681 "error.implementation_error_cannot_show_view_alignment_frame"));
5683 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5684 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5686 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5691 * Action on selection of menu options to Show or Hide annotations.
5694 * @param forSequences
5695 * update sequence-related annotations
5696 * @param forAlignment
5697 * update non-sequence-related annotations
5700 protected void setAnnotationsVisibility(boolean visible,
5701 boolean forSequences, boolean forAlignment)
5703 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5704 .getAlignmentAnnotation();
5709 for (AlignmentAnnotation aa : anns)
5712 * don't display non-positional annotations on an alignment
5714 if (aa.annotations == null)
5718 boolean apply = (aa.sequenceRef == null && forAlignment)
5719 || (aa.sequenceRef != null && forSequences);
5722 aa.visible = visible;
5725 alignPanel.validateAnnotationDimensions(true);
5726 alignPanel.alignmentChanged();
5730 * Store selected annotation sort order for the view and repaint.
5733 protected void sortAnnotations_actionPerformed()
5735 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5737 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5738 alignPanel.paintAlignment(false, false);
5743 * @return alignment panels in this alignment frame
5745 public List<? extends AlignmentViewPanel> getAlignPanels()
5747 // alignPanels is never null
5748 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5753 * Open a new alignment window, with the cDNA associated with this (protein)
5754 * alignment, aligned as is the protein.
5756 protected void viewAsCdna_actionPerformed()
5758 // TODO no longer a menu action - refactor as required
5759 final AlignmentI alignment = getViewport().getAlignment();
5760 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5761 if (mappings == null)
5765 List<SequenceI> cdnaSeqs = new ArrayList<>();
5766 for (SequenceI aaSeq : alignment.getSequences())
5768 for (AlignedCodonFrame acf : mappings)
5770 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5774 * There is a cDNA mapping for this protein sequence - add to new
5775 * alignment. It will share the same dataset sequence as other mapped
5776 * cDNA (no new mappings need to be created).
5778 final Sequence newSeq = new Sequence(dnaSeq);
5779 newSeq.setDatasetSequence(dnaSeq);
5780 cdnaSeqs.add(newSeq);
5784 if (cdnaSeqs.size() == 0)
5786 // show a warning dialog no mapped cDNA
5789 AlignmentI cdna = new Alignment(
5790 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5791 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5792 AlignFrame.DEFAULT_HEIGHT);
5793 cdna.alignAs(alignment);
5794 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5796 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5797 AlignFrame.DEFAULT_HEIGHT);
5801 * Set visibility of dna/protein complement view (available when shown in a
5807 protected void showComplement_actionPerformed(boolean show)
5809 SplitContainerI sf = getSplitViewContainer();
5812 sf.setComplementVisible(this, show);
5817 * Generate the reverse (optionally complemented) of the selected sequences,
5818 * and add them to the alignment
5821 protected void showReverse_actionPerformed(boolean complement)
5823 AlignmentI al = null;
5826 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5827 al = dna.reverseCdna(complement);
5828 viewport.addAlignment(al, "");
5829 addHistoryItem(new EditCommand(
5830 MessageManager.getString("label.add_sequences"), Action.PASTE,
5831 al.getSequencesArray(), 0, al.getWidth(),
5832 viewport.getAlignment()));
5833 } catch (Exception ex)
5835 System.err.println(ex.getMessage());
5841 * Try to run a script in the Groovy console, having first ensured that this
5842 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5843 * be targeted at this alignment.
5846 protected void runGroovy_actionPerformed()
5848 Jalview.setCurrentAlignFrame(this);
5849 groovy.ui.Console console = Desktop.getGroovyConsole();
5850 if (console != null)
5854 console.runScript();
5855 } catch (Exception ex)
5857 System.err.println((ex.toString()));
5858 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5859 MessageManager.getString("label.couldnt_run_groovy_script"),
5860 MessageManager.getString("label.groovy_support_failed"),
5861 JvOptionPane.ERROR_MESSAGE);
5866 System.err.println("Can't run Groovy script as console not found");
5871 * Hides columns containing (or not containing) a specified feature, provided
5872 * that would not leave all columns hidden
5874 * @param featureType
5875 * @param columnsContaining
5878 public boolean hideFeatureColumns(String featureType,
5879 boolean columnsContaining)
5881 boolean notForHiding = avc.markColumnsContainingFeatures(
5882 columnsContaining, false, false, featureType);
5885 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5886 false, featureType))
5888 getViewport().hideSelectedColumns();
5896 protected void selectHighlightedColumns_actionPerformed(
5897 ActionEvent actionEvent)
5899 // include key modifier check in case user selects from menu
5900 avc.markHighlightedColumns(
5901 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5902 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5903 | ActionEvent.CTRL_MASK)) != 0);
5907 protected void copyHighlightedColumns_actionPerformed(
5908 ActionEvent actionEvent)
5910 avc.copyHighlightedRegionsToClipboard();
5914 * Rebuilds the Colour menu, including any user-defined colours which have
5915 * been loaded either on startup or during the session
5917 public void buildColourMenu()
5919 colourMenu.removeAll();
5921 colourMenu.add(applyToAllGroups);
5922 colourMenu.add(textColour);
5923 colourMenu.addSeparator();
5925 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5926 viewport.getAlignment(), false);
5928 colourMenu.add(annotationColour);
5929 bg.add(annotationColour);
5930 colourMenu.addSeparator();
5931 colourMenu.add(conservationMenuItem);
5932 colourMenu.add(modifyConservation);
5933 colourMenu.add(abovePIDThreshold);
5934 colourMenu.add(modifyPID);
5936 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5937 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5941 * Open a dialog (if not already open) that allows the user to select and
5942 * calculate PCA or Tree analysis
5944 protected void openTreePcaDialog()
5946 if (alignPanel.getCalculationDialog() == null)
5948 new CalculationChooser(AlignFrame.this);
5953 protected void loadVcf_actionPerformed()
5955 JalviewFileChooser chooser = new JalviewFileChooser(
5956 Cache.getProperty("LAST_DIRECTORY"));
5957 chooser.setFileView(new JalviewFileView());
5958 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
5959 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
5960 final AlignFrame us = this;
5961 chooser.setResponseHandler(0, () -> {
5962 String choice = chooser.getSelectedFile().getPath();
5963 Cache.setProperty("LAST_DIRECTORY", choice);
5964 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
5965 new VCFLoader(choice).loadVCF(seqs, us);
5968 chooser.showOpenDialog(null);
5972 private Rectangle lastFeatureSettingsBounds = null;
5975 public void setFeatureSettingsGeometry(Rectangle bounds)
5977 lastFeatureSettingsBounds = bounds;
5981 public Rectangle getFeatureSettingsGeometry()
5983 return lastFeatureSettingsBounds;
5988 class PrintThread extends Thread
5992 public PrintThread(AlignmentPanel ap)
5997 static PageFormat pf;
6002 PrinterJob printJob = PrinterJob.getPrinterJob();
6006 printJob.setPrintable(ap, pf);
6010 printJob.setPrintable(ap);
6013 if (printJob.printDialog())
6018 } catch (Exception PrintException)
6020 PrintException.printStackTrace();