2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
63 import javax.swing.ButtonGroup;
64 import javax.swing.JCheckBoxMenuItem;
65 import javax.swing.JComponent;
66 import javax.swing.JEditorPane;
67 import javax.swing.JInternalFrame;
68 import javax.swing.JLabel;
69 import javax.swing.JLayeredPane;
70 import javax.swing.JMenu;
71 import javax.swing.JMenuItem;
72 import javax.swing.JPanel;
73 import javax.swing.JProgressBar;
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.ContactMatrixI;
116 import jalview.datamodel.HiddenColumns;
117 import jalview.datamodel.PDBEntry;
118 import jalview.datamodel.SeqCigar;
119 import jalview.datamodel.Sequence;
120 import jalview.datamodel.SequenceGroup;
121 import jalview.datamodel.SequenceI;
122 import jalview.gui.ColourMenuHelper.ColourChangeListener;
123 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
124 import jalview.io.AlignmentProperties;
125 import jalview.io.AnnotationFile;
126 import jalview.io.BackupFiles;
127 import jalview.io.BioJsHTMLOutput;
128 import jalview.io.DataSourceType;
129 import jalview.io.FileFormat;
130 import jalview.io.FileFormatI;
131 import jalview.io.FileFormats;
132 import jalview.io.FileLoader;
133 import jalview.io.FileParse;
134 import jalview.io.FormatAdapter;
135 import jalview.io.HtmlSvgOutput;
136 import jalview.io.IdentifyFile;
137 import jalview.io.JPredFile;
138 import jalview.io.JalviewFileChooser;
139 import jalview.io.JalviewFileView;
140 import jalview.io.JnetAnnotationMaker;
141 import jalview.io.NewickFile;
142 import jalview.io.ScoreMatrixFile;
143 import jalview.io.TCoffeeScoreFile;
144 import jalview.io.exceptions.ImageOutputException;
145 import jalview.io.vcf.VCFLoader;
146 import jalview.jbgui.GAlignFrame;
147 import jalview.project.Jalview2XML;
148 import jalview.schemes.ColourSchemeI;
149 import jalview.schemes.ColourSchemes;
150 import jalview.schemes.ResidueColourScheme;
151 import jalview.schemes.TCoffeeColourScheme;
152 import jalview.util.HttpUtils;
153 import jalview.util.ImageMaker.TYPE;
154 import jalview.util.MessageManager;
155 import jalview.util.Platform;
156 import jalview.util.imagemaker.BitmapImageSizing;
157 import jalview.viewmodel.AlignmentViewport;
158 import jalview.viewmodel.ViewportRanges;
159 import jalview.ws.DBRefFetcher;
160 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
161 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
162 import jalview.ws.jws1.Discoverer;
163 import jalview.ws.jws2.Jws2Discoverer;
164 import jalview.ws.jws2.jabaws2.Jws2Instance;
165 import jalview.ws.seqfetcher.DbSourceProxy;
171 * @version $Revision$
173 @SuppressWarnings("serial")
174 public class AlignFrame extends GAlignFrame implements DropTargetListener,
175 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
178 public static final int DEFAULT_WIDTH = 700;
180 public static final int DEFAULT_HEIGHT = 500;
183 * The currently displayed panel (selected tabbed view if more than one)
185 public AlignmentPanel alignPanel;
187 AlignViewport viewport;
189 public AlignViewControllerI avc;
191 List<AlignmentPanel> alignPanels = new ArrayList<>();
194 * Last format used to load or save alignments in this window
196 FileFormatI currentFileFormat = null;
199 * Current filename for this alignment
201 String fileName = null;
206 * Creates a new AlignFrame object with specific width and height.
212 public AlignFrame(AlignmentI al, int width, int height)
214 this(al, null, width, height);
218 * Creates a new AlignFrame object with specific width, height and
224 * @param sequenceSetId
226 public AlignFrame(AlignmentI al, int width, int height,
227 String sequenceSetId)
229 this(al, null, width, height, sequenceSetId);
233 * Creates a new AlignFrame object with specific width, height and
239 * @param sequenceSetId
242 public AlignFrame(AlignmentI al, int width, int height,
243 String sequenceSetId, String viewId)
245 this(al, null, width, height, sequenceSetId, viewId);
249 * new alignment window with hidden columns
253 * @param hiddenColumns
254 * ColumnSelection or null
256 * Width of alignment frame
260 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
263 this(al, hiddenColumns, width, height, null);
267 * Create alignment frame for al with hiddenColumns, a specific width and
268 * height, and specific sequenceId
271 * @param hiddenColumns
274 * @param sequenceSetId
277 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
278 int height, String sequenceSetId)
280 this(al, hiddenColumns, width, height, sequenceSetId, null);
284 * Create alignment frame for al with hiddenColumns, a specific width and
285 * height, and specific sequenceId
288 * @param hiddenColumns
291 * @param sequenceSetId
296 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
297 int height, String sequenceSetId, String viewId)
299 setSize(width, height);
301 if (al.getDataset() == null)
306 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
308 alignPanel = new AlignmentPanel(this, viewport);
310 addAlignmentPanel(alignPanel, true);
314 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
315 HiddenColumns hiddenColumns, int width, int height)
317 setSize(width, height);
319 if (al.getDataset() == null)
324 viewport = new AlignViewport(al, hiddenColumns);
326 if (hiddenSeqs != null && hiddenSeqs.length > 0)
328 viewport.hideSequence(hiddenSeqs);
330 alignPanel = new AlignmentPanel(this, viewport);
331 addAlignmentPanel(alignPanel, true);
336 * Make a new AlignFrame from existing alignmentPanels
343 public AlignFrame(AlignmentPanel ap)
347 addAlignmentPanel(ap, false);
352 * initalise the alignframe from the underlying viewport data and the
359 // setBackground(Color.white); // BH 2019
361 if (!Jalview.isHeadlessMode())
363 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
366 avc = new jalview.controller.AlignViewController(this, viewport,
368 if (viewport.getAlignmentConservationAnnotation() == null)
370 // BLOSUM62Colour.setEnabled(false);
371 conservationMenuItem.setEnabled(false);
372 modifyConservation.setEnabled(false);
373 // PIDColour.setEnabled(false);
374 // abovePIDThreshold.setEnabled(false);
375 // modifyPID.setEnabled(false);
378 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
380 if (sortby.equals("Id"))
382 sortIDMenuItem_actionPerformed(null);
384 else if (sortby.equals("Pairwise Identity"))
386 sortPairwiseMenuItem_actionPerformed(null);
390 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
392 setMenusFromViewport(viewport);
393 buildSortByAnnotationScoresMenu();
394 calculateTree.addActionListener(new ActionListener()
398 public void actionPerformed(ActionEvent e)
405 if (Desktop.desktop != null)
407 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
408 if (!Platform.isJS())
410 addServiceListeners();
415 if (viewport.getWrapAlignment())
417 wrapMenuItem_actionPerformed(null);
420 if (Cache.getDefault("SHOW_OVERVIEW", false))
422 this.overviewMenuItem_actionPerformed(null);
427 final List<AlignmentViewPanel> selviews = new ArrayList<>();
428 final List<AlignmentPanel> origview = new ArrayList<>();
429 final String menuLabel = MessageManager
430 .getString("label.copy_format_from");
431 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
432 new ViewSetProvider()
436 public AlignmentPanel[] getAllAlignmentPanels()
439 origview.add(alignPanel);
440 // make an array of all alignment panels except for this one
441 List<AlignmentPanel> aps = new ArrayList<>(
442 Arrays.asList(Desktop.getAlignmentPanels(null)));
443 aps.remove(AlignFrame.this.alignPanel);
444 return aps.toArray(new AlignmentPanel[aps.size()]);
446 }, selviews, new ItemListener()
450 public void itemStateChanged(ItemEvent e)
452 if (origview.size() > 0)
454 final AlignmentPanel ap = origview.get(0);
457 * Copy the ViewStyle of the selected panel to 'this one'.
458 * Don't change value of 'scaleProteinAsCdna' unless copying
461 ViewStyleI vs = selviews.get(0).getAlignViewport()
463 boolean fromSplitFrame = selviews.get(0)
464 .getAlignViewport().getCodingComplement() != null;
467 vs.setScaleProteinAsCdna(ap.getAlignViewport()
468 .getViewStyle().isScaleProteinAsCdna());
470 ap.getAlignViewport().setViewStyle(vs);
473 * Also rescale ViewStyle of SplitFrame complement if there is
474 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
475 * the whole ViewStyle (allow cDNA protein to have different
478 AlignViewportI complement = ap.getAlignViewport()
479 .getCodingComplement();
480 if (complement != null && vs.isScaleProteinAsCdna())
482 AlignFrame af = Desktop.getAlignFrameFor(complement);
483 ((SplitFrame) af.getSplitViewContainer())
485 af.setMenusForViewport();
489 ap.setSelected(true);
490 ap.alignFrame.setMenusForViewport();
495 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
496 .indexOf("devel") > -1
497 || Cache.getDefault("VERSION", "DEVELOPMENT")
498 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
500 formatMenu.add(vsel);
502 addFocusListener(new FocusAdapter()
505 public void focusGained(FocusEvent e)
507 Jalview.setCurrentAlignFrame(AlignFrame.this);
514 * Change the filename and format for the alignment, and enable the 'reload'
515 * button functionality.
522 public void setFileName(String file, FileFormatI format)
525 setFileFormat(format);
526 reload.setEnabled(true);
530 * JavaScript will have this, maybe others. More dependable than a file name
531 * and maintains a reference to the actual bytes loaded.
535 public void setFileObject(File file)
537 this.fileObject = file;
541 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
544 void addKeyListener()
546 addKeyListener(new KeyAdapter()
549 public void keyPressed(KeyEvent evt)
551 if (viewport.cursorMode
552 && ((evt.getKeyCode() >= KeyEvent.VK_0
553 && evt.getKeyCode() <= KeyEvent.VK_9)
554 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
555 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
556 && Character.isDigit(evt.getKeyChar()))
558 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
561 switch (evt.getKeyCode())
564 case 27: // escape key
565 deselectAllSequenceMenuItem_actionPerformed(null);
569 case KeyEvent.VK_DOWN:
570 if (evt.isAltDown() || !viewport.cursorMode)
572 moveSelectedSequences(false);
574 if (viewport.cursorMode)
576 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
581 if (evt.isAltDown() || !viewport.cursorMode)
583 moveSelectedSequences(true);
585 if (viewport.cursorMode)
587 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
592 case KeyEvent.VK_LEFT:
593 if (evt.isAltDown() || !viewport.cursorMode)
595 slideSequences(false,
596 alignPanel.getSeqPanel().getKeyboardNo1());
600 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
605 case KeyEvent.VK_RIGHT:
606 if (evt.isAltDown() || !viewport.cursorMode)
608 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
612 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
616 case KeyEvent.VK_SPACE:
617 if (viewport.cursorMode)
619 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
620 || evt.isShiftDown() || evt.isAltDown());
624 // case KeyEvent.VK_A:
625 // if (viewport.cursorMode)
627 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
628 // //System.out.println("A");
632 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
633 * System.out.println("closing bracket"); } break;
635 case KeyEvent.VK_DELETE:
636 case KeyEvent.VK_BACK_SPACE:
637 if (!viewport.cursorMode)
639 cut_actionPerformed();
643 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
644 || evt.isShiftDown() || evt.isAltDown());
650 if (viewport.cursorMode)
652 alignPanel.getSeqPanel().setCursorRow();
656 if (viewport.cursorMode && !evt.isControlDown())
658 alignPanel.getSeqPanel().setCursorColumn();
662 if (viewport.cursorMode)
664 alignPanel.getSeqPanel().setCursorPosition();
668 case KeyEvent.VK_ENTER:
669 case KeyEvent.VK_COMMA:
670 if (viewport.cursorMode)
672 alignPanel.getSeqPanel().setCursorRowAndColumn();
677 if (viewport.cursorMode)
679 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
683 if (viewport.cursorMode)
685 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
690 viewport.cursorMode = !viewport.cursorMode;
691 setStatus(MessageManager
692 .formatMessage("label.keyboard_editing_mode", new String[]
693 { (viewport.cursorMode ? "on" : "off") }));
694 if (viewport.cursorMode)
696 ViewportRanges ranges = viewport.getRanges();
697 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
699 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
702 alignPanel.getSeqPanel().seqCanvas.repaint();
708 Help.showHelpWindow();
709 } catch (Exception ex)
711 ex.printStackTrace();
716 boolean toggleSeqs = !evt.isControlDown();
717 boolean toggleCols = !evt.isShiftDown();
718 toggleHiddenRegions(toggleSeqs, toggleCols);
723 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
724 boolean modifyExisting = true; // always modify, don't clear
725 // evt.isShiftDown();
726 boolean invertHighlighted = evt.isAltDown();
727 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
731 case KeyEvent.VK_PAGE_UP:
732 viewport.getRanges().pageUp();
734 case KeyEvent.VK_PAGE_DOWN:
735 viewport.getRanges().pageDown();
741 public void keyReleased(KeyEvent evt)
743 switch (evt.getKeyCode())
745 case KeyEvent.VK_LEFT:
746 if (evt.isAltDown() || !viewport.cursorMode)
748 viewport.firePropertyChange("alignment", null,
749 viewport.getAlignment().getSequences());
753 case KeyEvent.VK_RIGHT:
754 if (evt.isAltDown() || !viewport.cursorMode)
756 viewport.firePropertyChange("alignment", null,
757 viewport.getAlignment().getSequences());
765 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
767 ap.alignFrame = this;
768 avc = new jalview.controller.AlignViewController(this, viewport,
773 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
775 int aSize = alignPanels.size();
777 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
779 if (aSize == 1 && ap.av.getViewName() == null)
781 this.getContentPane().add(ap, BorderLayout.CENTER);
787 setInitialTabVisible();
790 expandViews.setEnabled(true);
791 gatherViews.setEnabled(true);
792 tabbedPane.addTab(ap.av.getViewName(), ap);
794 ap.setVisible(false);
799 if (ap.av.isPadGaps())
801 ap.av.getAlignment().padGaps();
803 ap.av.updateConservation(ap);
804 ap.av.updateConsensus(ap);
805 ap.av.updateStrucConsensus(ap);
809 public void setInitialTabVisible()
811 expandViews.setEnabled(true);
812 gatherViews.setEnabled(true);
813 tabbedPane.setVisible(true);
814 AlignmentPanel first = alignPanels.get(0);
815 tabbedPane.addTab(first.av.getViewName(), first);
816 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
819 public AlignViewport getViewport()
824 /* Set up intrinsic listeners for dynamically generated GUI bits. */
825 private void addServiceListeners()
827 final java.beans.PropertyChangeListener thisListener;
828 Desktop.instance.addJalviewPropertyChangeListener("services",
829 thisListener = new java.beans.PropertyChangeListener()
832 public void propertyChange(PropertyChangeEvent evt)
834 // // System.out.println("Discoverer property change.");
835 // if (evt.getPropertyName().equals("services"))
837 SwingUtilities.invokeLater(new Runnable()
844 "Rebuild WS Menu for service change");
845 BuildWebServiceMenu();
852 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
855 public void internalFrameClosed(
856 javax.swing.event.InternalFrameEvent evt)
858 // System.out.println("deregistering discoverer listener");
859 Desktop.instance.removeJalviewPropertyChangeListener("services",
861 closeMenuItem_actionPerformed(true);
864 // Finally, build the menu once to get current service state
865 new Thread(new Runnable()
870 BuildWebServiceMenu();
876 * Configure menu items that vary according to whether the alignment is
877 * nucleotide or protein
879 public void setGUINucleotide()
881 AlignmentI al = getViewport().getAlignment();
882 boolean nucleotide = al.isNucleotide();
884 loadVcf.setVisible(nucleotide);
885 showTranslation.setVisible(nucleotide);
886 showReverse.setVisible(nucleotide);
887 showReverseComplement.setVisible(nucleotide);
888 conservationMenuItem.setEnabled(!nucleotide);
890 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
891 showGroupConservation.setEnabled(!nucleotide);
893 showComplementMenuItem
894 .setText(nucleotide ? MessageManager.getString("label.protein")
895 : MessageManager.getString("label.nucleotide"));
899 * set up menus for the current viewport. This may be called after any
900 * operation that affects the data in the current view (selection changed,
901 * etc) to update the menus to reflect the new state.
904 public void setMenusForViewport()
906 setMenusFromViewport(viewport);
910 * Need to call this method when tabs are selected for multiple views, or when
911 * loading from Jalview2XML.java
916 public void setMenusFromViewport(AlignViewport av)
918 padGapsMenuitem.setSelected(av.isPadGaps());
919 colourTextMenuItem.setSelected(av.isShowColourText());
920 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
921 modifyPID.setEnabled(abovePIDThreshold.isSelected());
922 conservationMenuItem.setSelected(av.getConservationSelected());
923 modifyConservation.setEnabled(conservationMenuItem.isSelected());
924 seqLimits.setSelected(av.getShowJVSuffix());
925 idRightAlign.setSelected(av.isRightAlignIds());
926 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
927 renderGapsMenuItem.setSelected(av.isRenderGaps());
928 wrapMenuItem.setSelected(av.getWrapAlignment());
929 scaleAbove.setVisible(av.getWrapAlignment());
930 scaleLeft.setVisible(av.getWrapAlignment());
931 scaleRight.setVisible(av.getWrapAlignment());
932 annotationPanelMenuItem.setState(av.isShowAnnotation());
934 * Show/hide annotations only enabled if annotation panel is shown
936 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
939 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
940 viewBoxesMenuItem.setSelected(av.getShowBoxes());
941 viewTextMenuItem.setSelected(av.getShowText());
942 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
943 showGroupConsensus.setSelected(av.isShowGroupConsensus());
944 showGroupConservation.setSelected(av.isShowGroupConservation());
945 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
946 showSequenceLogo.setSelected(av.isShowSequenceLogo());
947 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
949 ColourMenuHelper.setColourSelected(colourMenu,
950 av.getGlobalColourScheme());
952 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
953 hiddenMarkers.setState(av.getShowHiddenMarkers());
954 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
955 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
956 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
957 autoCalculate.setSelected(av.autoCalculateConsensus);
958 sortByTree.setSelected(av.sortByTree);
959 listenToViewSelections.setSelected(av.followSelection);
961 showProducts.setEnabled(canShowProducts());
962 setGroovyEnabled(Desktop.getGroovyConsole() != null);
968 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
972 public void setGroovyEnabled(boolean b)
974 runGroovy.setEnabled(b);
977 private IProgressIndicator progressBar;
982 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
985 public void setProgressBar(String message, long id)
987 if (!Platform.isHeadless() && progressBar != null)
988 progressBar.setProgressBar(message, id);
992 public JProgressBar getProgressBar(long id)
994 if (progressBar != null)
995 return progressBar.getProgressBar(id);
1000 public void registerHandler(final long id,
1001 final IProgressIndicatorHandler handler)
1003 if (progressBar != null)
1004 progressBar.registerHandler(id, handler);
1009 * @return true if any progress bars are still active
1012 public boolean operationInProgress()
1014 return progressBar == null ? false : progressBar.operationInProgress();
1018 * Sets the text of the status bar. Note that setting a null or empty value
1019 * will cause the status bar to be hidden, with possibly undesirable flicker
1020 * of the screen layout.
1023 public void setStatus(String text)
1025 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1029 * Added so Castor Mapping file can obtain Jalview Version
1031 public String getVersion()
1033 return Cache.getProperty("VERSION");
1036 public FeatureRenderer getFeatureRenderer()
1038 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1042 public void fetchSequence_actionPerformed()
1044 new SequenceFetcher(this);
1048 public void addFromFile_actionPerformed(ActionEvent e)
1050 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1054 public void reload_actionPerformed(ActionEvent e)
1056 if (fileName != null)
1058 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1059 // originating file's format
1060 // TODO: work out how to recover feature settings for correct view(s) when
1061 // file is reloaded.
1062 if (FileFormat.Jalview.equals(currentFileFormat))
1064 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1065 for (int i = 0; i < frames.length; i++)
1067 if (frames[i] instanceof AlignFrame && frames[i] != this
1068 && ((AlignFrame) frames[i]).fileName != null
1069 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1073 frames[i].setSelected(true);
1074 Desktop.instance.closeAssociatedWindows();
1075 } catch (java.beans.PropertyVetoException ex)
1081 Desktop.instance.closeAssociatedWindows();
1083 FileLoader loader = new FileLoader();
1084 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1085 ? DataSourceType.URL
1086 : DataSourceType.FILE;
1087 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1091 Rectangle bounds = this.getBounds();
1093 FileLoader loader = new FileLoader();
1095 AlignFrame newframe = null;
1097 if (fileObject == null)
1100 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1101 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1102 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1107 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1108 DataSourceType.FILE, currentFileFormat);
1111 newframe.setBounds(bounds);
1112 if (featureSettings != null && featureSettings.isShowing())
1114 final Rectangle fspos = featureSettings.frame.getBounds();
1115 // TODO: need a 'show feature settings' function that takes bounds -
1116 // need to refactor Desktop.addFrame
1117 newframe.featureSettings_actionPerformed(null);
1118 final FeatureSettings nfs = newframe.featureSettings;
1119 SwingUtilities.invokeLater(new Runnable()
1124 nfs.frame.setBounds(fspos);
1127 this.featureSettings.close();
1128 this.featureSettings = null;
1130 this.closeMenuItem_actionPerformed(true);
1136 public void addFromText_actionPerformed(ActionEvent e)
1139 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1143 public void addFromURL_actionPerformed(ActionEvent e)
1145 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1149 public void save_actionPerformed(ActionEvent e)
1151 if (fileName == null || (currentFileFormat == null)
1152 || HttpUtils.startsWithHttpOrHttps(fileName))
1154 saveAs_actionPerformed();
1158 saveAlignment(fileName, currentFileFormat);
1163 * Saves the alignment to a file with a name chosen by the user, if necessary
1164 * warning if a file would be overwritten
1167 public void saveAs_actionPerformed()
1169 String format = currentFileFormat == null ? null
1170 : currentFileFormat.getName();
1171 JalviewFileChooser chooser = JalviewFileChooser
1172 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1174 chooser.setFileView(new JalviewFileView());
1175 chooser.setDialogTitle(
1176 MessageManager.getString("label.save_alignment_to_file"));
1177 chooser.setToolTipText(MessageManager.getString("action.save"));
1179 int value = chooser.showSaveDialog(this);
1181 if (value != JalviewFileChooser.APPROVE_OPTION)
1185 currentFileFormat = chooser.getSelectedFormat();
1186 // todo is this (2005) test now obsolete - value is never null?
1187 while (currentFileFormat == null)
1189 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1191 .getString("label.select_file_format_before_saving"),
1192 MessageManager.getString("label.file_format_not_specified"),
1193 JvOptionPane.WARNING_MESSAGE);
1194 currentFileFormat = chooser.getSelectedFormat();
1195 value = chooser.showSaveDialog(this);
1196 if (value != JalviewFileChooser.APPROVE_OPTION)
1202 fileName = chooser.getSelectedFile().getPath();
1204 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1205 Cache.setProperty("LAST_DIRECTORY", fileName);
1206 saveAlignment(fileName, currentFileFormat);
1209 boolean lastSaveSuccessful = false;
1211 FileFormatI lastFormatSaved;
1213 String lastFilenameSaved;
1216 * Raise a dialog or status message for the last call to saveAlignment.
1218 * @return true if last call to saveAlignment(file, format) was successful.
1220 public boolean isSaveAlignmentSuccessful()
1223 if (!lastSaveSuccessful)
1225 if (!Platform.isHeadless())
1227 JvOptionPane.showInternalMessageDialog(this, MessageManager
1228 .formatMessage("label.couldnt_save_file", new Object[]
1229 { lastFilenameSaved }),
1230 MessageManager.getString("label.error_saving_file"),
1231 JvOptionPane.WARNING_MESSAGE);
1235 Console.error(MessageManager
1236 .formatMessage("label.couldnt_save_file", new Object[]
1237 { lastFilenameSaved }));
1243 setStatus(MessageManager.formatMessage(
1244 "label.successfully_saved_to_file_in_format", new Object[]
1245 { lastFilenameSaved, lastFormatSaved }));
1248 return lastSaveSuccessful;
1252 * Saves the alignment to the specified file path, in the specified format,
1253 * which may be an alignment format, or Jalview project format. If the
1254 * alignment has hidden regions, or the format is one capable of including
1255 * non-sequence data (features, annotations, groups), then the user may be
1256 * prompted to specify what to include in the output.
1261 public void saveAlignment(String file, FileFormatI format)
1263 lastSaveSuccessful = true;
1264 lastFilenameSaved = file;
1265 lastFormatSaved = format;
1267 if (FileFormat.Jalview.equals(format))
1269 String shortName = title;
1270 if (shortName.indexOf(File.separatorChar) > -1)
1272 shortName = shortName
1273 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1275 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1278 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1279 if (lastSaveSuccessful)
1281 this.getViewport().setSavedUpToDate(true);
1284 statusBar.setText(MessageManager.formatMessage(
1285 "label.successfully_saved_to_file_in_format", new Object[]
1291 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1292 Runnable cancelAction = () -> {
1293 lastSaveSuccessful = false;
1295 Runnable outputAction = () -> {
1296 // todo defer this to inside formatSequences (or later)
1297 AlignmentExportData exportData = viewport.getAlignExportData(options);
1298 String output = new FormatAdapter(alignPanel, options)
1299 .formatSequences(format, exportData.getAlignment(),
1300 exportData.getOmitHidden(),
1301 exportData.getStartEndPostions(),
1302 viewport.getAlignment().getHiddenColumns());
1305 lastSaveSuccessful = false;
1309 // create backupfiles object and get new temp filename destination
1310 boolean doBackup = BackupFiles.getEnabled();
1311 BackupFiles backupfiles = null;
1314 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1315 backupfiles = new BackupFiles(file);
1319 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1321 Console.trace("ALIGNFRAME setting PrintWriter");
1322 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1324 if (backupfiles != null)
1326 Console.trace("ALIGNFRAME about to write to temp file "
1327 + backupfiles.getTempFilePath());
1331 Console.trace("ALIGNFRAME about to close file");
1333 Console.trace("ALIGNFRAME closed file");
1334 AlignFrame.this.setTitle(file);
1335 statusBar.setText(MessageManager.formatMessage(
1336 "label.successfully_saved_to_file_in_format", new Object[]
1337 { fileName, format.getName() }));
1338 lastSaveSuccessful = true;
1339 } catch (IOException e)
1341 lastSaveSuccessful = false;
1343 "ALIGNFRAME Something happened writing the temp file");
1344 Console.error(e.getMessage());
1345 Console.debug(Cache.getStackTraceString(e));
1346 } catch (Exception ex)
1348 lastSaveSuccessful = false;
1350 "ALIGNFRAME Something unexpected happened writing the temp file");
1351 Console.error(ex.getMessage());
1352 Console.debug(Cache.getStackTraceString(ex));
1357 backupfiles.setWriteSuccess(lastSaveSuccessful);
1358 Console.debug("ALIGNFRAME writing temp file was "
1359 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1360 // do the backup file roll and rename the temp file to actual file
1361 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1362 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1363 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1364 + (lastSaveSuccessful ? "" : "un") + "successfully");
1367 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1368 if (lastSaveSuccessful)
1370 AlignFrame.this.getViewport().setSavedUpToDate(true);
1376 * show dialog with export options if applicable; else just do it
1378 if (AlignExportOptions.isNeeded(viewport, format))
1380 AlignExportOptions choices = new AlignExportOptions(
1381 alignPanel.getAlignViewport(), format, options);
1382 choices.setResponseAction(0, outputAction);
1383 choices.setResponseAction(1, cancelAction);
1384 choices.showDialog();
1391 } catch (Exception e)
1393 // TODO Auto-generated catch block
1394 e.printStackTrace();
1400 * Outputs the alignment to textbox in the requested format, if necessary
1401 * first prompting the user for whether to include hidden regions or
1404 * @param fileFormatName
1407 protected void outputText_actionPerformed(String fileFormatName)
1409 FileFormatI fileFormat = FileFormats.getInstance()
1410 .forName(fileFormatName);
1411 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1412 Runnable outputAction = () -> {
1413 // todo defer this to inside formatSequences (or later)
1414 AlignmentExportData exportData = viewport.getAlignExportData(options);
1415 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1416 cap.setForInput(null);
1419 FileFormatI format = fileFormat;
1420 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1421 format, exportData.getAlignment(),
1422 exportData.getOmitHidden(),
1423 exportData.getStartEndPostions(),
1424 viewport.getAlignment().getHiddenColumns()));
1425 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1426 "label.alignment_output_command", new Object[]
1427 { fileFormat.getName() }), 600, 500);
1428 } catch (OutOfMemoryError oom)
1430 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1437 * show dialog with export options if applicable; else just do it
1439 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1441 AlignExportOptions choices = new AlignExportOptions(
1442 alignPanel.getAlignViewport(), fileFormat, options);
1443 choices.setResponseAction(0, outputAction);
1444 choices.showDialog();
1451 } catch (Exception e)
1453 e.printStackTrace();
1465 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1467 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1469 htmlSVG.exportHTML(null);
1470 } catch (ImageOutputException x) {
1471 // report problem to console and raise dialog
1476 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1478 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1480 bjs.exportHTML(null);
1481 } catch (ImageOutputException x) {
1482 // report problem to console and raise dialog
1486 public void createImageMap(File file, String image)
1489 alignPanel.makePNGImageMap(file, image);
1490 } catch (ImageOutputException x) {
1491 // report problem to console and raise dialog
1496 public void createPNG_actionPerformed(ActionEvent e) {
1499 } catch (ImageOutputException ioex)
1501 // raise dialog, and report via console
1505 public void createEPS_actionPerformed(ActionEvent e) {
1508 } catch (ImageOutputException ioex)
1510 // raise dialog, and report via console
1515 public void createSVG_actionPerformed(ActionEvent e) {
1518 } catch (ImageOutputException ioex)
1520 // raise dialog, and report via console
1525 * Creates a PNG image of the alignment and writes it to the given file. If
1526 * the file is null, the user is prompted to choose a file.
1530 public void createPNG(File f) throws ImageOutputException
1532 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1535 public void createPNG(File f, String renderer, BitmapImageSizing userBis) throws ImageOutputException
1537 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1541 * Creates an EPS image of the alignment and writes it to the given file. If
1542 * the file is null, the user is prompted to choose a file.
1546 public void createEPS(File f) throws ImageOutputException
1551 public void createEPS(File f, String renderer) throws ImageOutputException
1553 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1557 * Creates an SVG image of the alignment and writes it to the given file. If
1558 * the file is null, the user is prompted to choose a file.
1562 public void createSVG(File f) throws ImageOutputException
1567 public void createSVG(File f, String renderer) throws ImageOutputException
1569 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1573 public void pageSetup_actionPerformed(ActionEvent e)
1575 PrinterJob printJob = PrinterJob.getPrinterJob();
1576 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1586 public void printMenuItem_actionPerformed(ActionEvent e)
1588 // Putting in a thread avoids Swing painting problems
1589 PrintThread thread = new PrintThread(alignPanel);
1594 public void exportFeatures_actionPerformed(ActionEvent e)
1596 new AnnotationExporter(alignPanel).exportFeatures();
1600 public void exportAnnotations_actionPerformed(ActionEvent e)
1602 new AnnotationExporter(alignPanel).exportAnnotations();
1606 public void associatedData_actionPerformed(ActionEvent e)
1608 final JalviewFileChooser chooser = new JalviewFileChooser(
1609 Cache.getProperty("LAST_DIRECTORY"));
1610 chooser.setFileView(new JalviewFileView());
1611 String tooltip = MessageManager
1612 .getString("label.load_jalview_annotations");
1613 chooser.setDialogTitle(tooltip);
1614 chooser.setToolTipText(tooltip);
1615 chooser.setResponseHandler(0, () -> {
1616 String choice = chooser.getSelectedFile().getPath();
1617 Cache.setProperty("LAST_DIRECTORY", choice);
1618 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1621 chooser.showOpenDialog(this);
1625 * Close the current view or all views in the alignment frame. If the frame
1626 * only contains one view then the alignment will be removed from memory.
1628 * @param closeAllTabs
1631 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1633 if (alignPanels != null && alignPanels.size() < 2)
1635 closeAllTabs = true;
1640 if (alignPanels != null)
1644 if (this.isClosed())
1646 // really close all the windows - otherwise wait till
1647 // setClosed(true) is called
1648 for (int i = 0; i < alignPanels.size(); i++)
1650 AlignmentPanel ap = alignPanels.get(i);
1657 closeView(alignPanel);
1662 if (featureSettings != null && featureSettings.isOpen())
1664 featureSettings.close();
1665 featureSettings = null;
1668 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1669 * be called recursively, with the frame now in 'closed' state
1671 this.setClosed(true);
1673 } catch (Exception ex)
1675 ex.printStackTrace();
1680 * Close the specified panel and close up tabs appropriately.
1682 * @param panelToClose
1684 public void closeView(AlignmentPanel panelToClose)
1686 int index = tabbedPane.getSelectedIndex();
1687 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1688 alignPanels.remove(panelToClose);
1689 panelToClose.closePanel();
1690 panelToClose = null;
1692 tabbedPane.removeTabAt(closedindex);
1693 tabbedPane.validate();
1695 if (index > closedindex || index == tabbedPane.getTabCount())
1697 // modify currently selected tab index if necessary.
1701 this.tabSelectionChanged(index);
1707 void updateEditMenuBar()
1710 if (viewport.getHistoryList().size() > 0)
1712 undoMenuItem.setEnabled(true);
1713 CommandI command = viewport.getHistoryList().peek();
1714 undoMenuItem.setText(MessageManager
1715 .formatMessage("label.undo_command", new Object[]
1716 { command.getDescription() }));
1720 undoMenuItem.setEnabled(false);
1721 undoMenuItem.setText(MessageManager.getString("action.undo"));
1724 if (viewport.getRedoList().size() > 0)
1726 redoMenuItem.setEnabled(true);
1728 CommandI command = viewport.getRedoList().peek();
1729 redoMenuItem.setText(MessageManager
1730 .formatMessage("label.redo_command", new Object[]
1731 { command.getDescription() }));
1735 redoMenuItem.setEnabled(false);
1736 redoMenuItem.setText(MessageManager.getString("action.redo"));
1741 public void addHistoryItem(CommandI command)
1743 if (command.getSize() > 0)
1745 viewport.addToHistoryList(command);
1746 viewport.clearRedoList();
1747 updateEditMenuBar();
1748 viewport.updateHiddenColumns();
1749 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1750 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1751 // viewport.getColumnSelection()
1752 // .getHiddenColumns().size() > 0);
1758 * @return alignment objects for all views
1760 AlignmentI[] getViewAlignments()
1762 if (alignPanels != null)
1764 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1766 for (AlignmentPanel ap : alignPanels)
1768 als[i++] = ap.av.getAlignment();
1772 if (viewport != null)
1774 return new AlignmentI[] { viewport.getAlignment() };
1786 protected void undoMenuItem_actionPerformed(ActionEvent e)
1788 if (viewport.getHistoryList().isEmpty())
1792 CommandI command = viewport.getHistoryList().pop();
1793 viewport.addToRedoList(command);
1794 command.undoCommand(getViewAlignments());
1796 AlignmentViewport originalSource = getOriginatingSource(command);
1797 updateEditMenuBar();
1799 if (originalSource != null)
1801 if (originalSource != viewport)
1804 "Implementation worry: mismatch of viewport origin for undo");
1806 originalSource.updateHiddenColumns();
1807 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1809 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1810 // viewport.getColumnSelection()
1811 // .getHiddenColumns().size() > 0);
1812 originalSource.firePropertyChange("alignment", null,
1813 originalSource.getAlignment().getSequences());
1824 protected void redoMenuItem_actionPerformed(ActionEvent e)
1826 if (viewport.getRedoList().size() < 1)
1831 CommandI command = viewport.getRedoList().pop();
1832 viewport.addToHistoryList(command);
1833 command.doCommand(getViewAlignments());
1835 AlignmentViewport originalSource = getOriginatingSource(command);
1836 updateEditMenuBar();
1838 if (originalSource != null)
1841 if (originalSource != viewport)
1844 "Implementation worry: mismatch of viewport origin for redo");
1846 originalSource.updateHiddenColumns();
1847 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1849 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1850 // viewport.getColumnSelection()
1851 // .getHiddenColumns().size() > 0);
1852 originalSource.firePropertyChange("alignment", null,
1853 originalSource.getAlignment().getSequences());
1857 AlignmentViewport getOriginatingSource(CommandI command)
1859 AlignmentViewport originalSource = null;
1860 // For sequence removal and addition, we need to fire
1861 // the property change event FROM the viewport where the
1862 // original alignment was altered
1863 AlignmentI al = null;
1864 if (command instanceof EditCommand)
1866 EditCommand editCommand = (EditCommand) command;
1867 al = editCommand.getAlignment();
1868 List<Component> comps = PaintRefresher.components
1869 .get(viewport.getSequenceSetId());
1871 for (Component comp : comps)
1873 if (comp instanceof AlignmentPanel)
1875 if (al == ((AlignmentPanel) comp).av.getAlignment())
1877 originalSource = ((AlignmentPanel) comp).av;
1884 if (originalSource == null)
1886 // The original view is closed, we must validate
1887 // the current view against the closed view first
1890 PaintRefresher.validateSequences(al, viewport.getAlignment());
1893 originalSource = viewport;
1896 return originalSource;
1900 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1901 * or the sequence under cursor in keyboard mode
1906 public void moveSelectedSequences(boolean up)
1908 SequenceGroup sg = viewport.getSelectionGroup();
1912 if (viewport.cursorMode)
1914 sg = new SequenceGroup();
1915 sg.addSequence(viewport.getAlignment().getSequenceAt(
1916 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1924 if (sg.getSize() < 1)
1929 // TODO: JAL-3733 - add an event to the undo buffer for this !
1931 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1932 viewport.getHiddenRepSequences(), up);
1933 alignPanel.paintAlignment(true, false);
1936 synchronized void slideSequences(boolean right, int size)
1938 List<SequenceI> sg = new ArrayList<>();
1939 if (viewport.cursorMode)
1941 sg.add(viewport.getAlignment()
1942 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1944 else if (viewport.getSelectionGroup() != null
1945 && viewport.getSelectionGroup().getSize() != viewport
1946 .getAlignment().getHeight())
1948 sg = viewport.getSelectionGroup()
1949 .getSequences(viewport.getHiddenRepSequences());
1957 List<SequenceI> invertGroup = new ArrayList<>();
1959 for (SequenceI seq : viewport.getAlignment().getSequences())
1961 if (!sg.contains(seq))
1963 invertGroup.add(seq);
1967 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1969 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1970 for (int i = 0; i < invertGroup.size(); i++)
1972 seqs2[i] = invertGroup.get(i);
1975 SlideSequencesCommand ssc;
1978 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1979 viewport.getGapCharacter());
1983 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1984 viewport.getGapCharacter());
1987 int groupAdjustment = 0;
1988 if (ssc.getGapsInsertedBegin() && right)
1990 if (viewport.cursorMode)
1992 alignPanel.getSeqPanel().moveCursor(size, 0);
1996 groupAdjustment = size;
1999 else if (!ssc.getGapsInsertedBegin() && !right)
2001 if (viewport.cursorMode)
2003 alignPanel.getSeqPanel().moveCursor(-size, 0);
2007 groupAdjustment = -size;
2011 if (groupAdjustment != 0)
2013 viewport.getSelectionGroup().setStartRes(
2014 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2015 viewport.getSelectionGroup().setEndRes(
2016 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2020 * just extend the last slide command if compatible; but not if in
2021 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2023 boolean appendHistoryItem = false;
2024 Deque<CommandI> historyList = viewport.getHistoryList();
2025 boolean inSplitFrame = getSplitViewContainer() != null;
2026 if (!inSplitFrame && historyList != null && historyList.size() > 0
2027 && historyList.peek() instanceof SlideSequencesCommand)
2029 appendHistoryItem = ssc.appendSlideCommand(
2030 (SlideSequencesCommand) historyList.peek());
2033 if (!appendHistoryItem)
2035 addHistoryItem(ssc);
2048 protected void copy_actionPerformed()
2050 if (viewport.getSelectionGroup() == null)
2054 // TODO: preserve the ordering of displayed alignment annotation in any
2055 // internal paste (particularly sequence associated annotation)
2056 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2057 String[] omitHidden = null;
2059 if (viewport.hasHiddenColumns())
2061 omitHidden = viewport.getViewAsString(true);
2064 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2065 seqs, omitHidden, null);
2067 StringSelection ss = new StringSelection(output);
2071 jalview.gui.Desktop.internalCopy = true;
2072 // Its really worth setting the clipboard contents
2073 // to empty before setting the large StringSelection!!
2074 Toolkit.getDefaultToolkit().getSystemClipboard()
2075 .setContents(new StringSelection(""), null);
2077 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2079 } catch (OutOfMemoryError er)
2081 new OOMWarning("copying region", er);
2085 HiddenColumns hiddenColumns = null;
2086 if (viewport.hasHiddenColumns())
2088 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2089 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2091 // create new HiddenColumns object with copy of hidden regions
2092 // between startRes and endRes, offset by startRes
2093 hiddenColumns = new HiddenColumns(
2094 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2095 hiddenCutoff, hiddenOffset);
2098 Desktop.jalviewClipboard = new Object[] { seqs,
2099 viewport.getAlignment().getDataset(), hiddenColumns };
2100 setStatus(MessageManager.formatMessage(
2101 "label.copied_sequences_to_clipboard", new Object[]
2102 { Integer.valueOf(seqs.length).toString() }));
2112 protected void pasteNew_actionPerformed(ActionEvent e)
2124 protected void pasteThis_actionPerformed(ActionEvent e)
2130 * Paste contents of Jalview clipboard
2132 * @param newAlignment
2133 * true to paste to a new alignment, otherwise add to this.
2135 void paste(boolean newAlignment)
2137 boolean externalPaste = true;
2140 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2141 Transferable contents = c.getContents(this);
2143 if (contents == null)
2152 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2153 if (str.length() < 1)
2158 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2160 } catch (OutOfMemoryError er)
2162 new OOMWarning("Out of memory pasting sequences!!", er);
2166 SequenceI[] sequences;
2167 boolean annotationAdded = false;
2168 AlignmentI alignment = null;
2170 if (Desktop.jalviewClipboard != null)
2172 // The clipboard was filled from within Jalview, we must use the
2174 // And dataset from the copied alignment
2175 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2176 // be doubly sure that we create *new* sequence objects.
2177 sequences = new SequenceI[newseq.length];
2178 for (int i = 0; i < newseq.length; i++)
2180 sequences[i] = new Sequence(newseq[i]);
2182 alignment = new Alignment(sequences);
2183 externalPaste = false;
2187 // parse the clipboard as an alignment.
2188 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2190 sequences = alignment.getSequencesArray();
2194 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2200 if (Desktop.jalviewClipboard != null)
2202 // dataset is inherited
2203 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2207 // new dataset is constructed
2208 alignment.setDataset(null);
2210 alwidth = alignment.getWidth() + 1;
2214 AlignmentI pastedal = alignment; // preserve pasted alignment object
2215 // Add pasted sequences and dataset into existing alignment.
2216 alignment = viewport.getAlignment();
2217 alwidth = alignment.getWidth() + 1;
2218 // decide if we need to import sequences from an existing dataset
2219 boolean importDs = Desktop.jalviewClipboard != null
2220 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2221 // importDs==true instructs us to copy over new dataset sequences from
2222 // an existing alignment
2223 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2225 // minimum dataset set
2227 for (int i = 0; i < sequences.length; i++)
2231 newDs.addElement(null);
2233 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2235 if (importDs && ds != null)
2237 if (!newDs.contains(ds))
2239 newDs.setElementAt(ds, i);
2240 ds = new Sequence(ds);
2241 // update with new dataset sequence
2242 sequences[i].setDatasetSequence(ds);
2246 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2251 // copy and derive new dataset sequence
2252 sequences[i] = sequences[i].deriveSequence();
2253 alignment.getDataset()
2254 .addSequence(sequences[i].getDatasetSequence());
2255 // TODO: avoid creation of duplicate dataset sequences with a
2256 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2258 alignment.addSequence(sequences[i]); // merges dataset
2262 newDs.clear(); // tidy up
2264 if (alignment.getAlignmentAnnotation() != null)
2266 for (AlignmentAnnotation alan : alignment
2267 .getAlignmentAnnotation())
2269 if (alan.graphGroup > fgroup)
2271 fgroup = alan.graphGroup;
2275 if (pastedal.getAlignmentAnnotation() != null)
2277 // Add any annotation attached to alignment.
2278 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2279 for (int i = 0; i < alann.length; i++)
2281 annotationAdded = true;
2282 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2284 AlignmentAnnotation newann = new AlignmentAnnotation(
2286 if (newann.graphGroup > -1)
2288 if (newGraphGroups.size() <= newann.graphGroup
2289 || newGraphGroups.get(newann.graphGroup) == null)
2291 for (int q = newGraphGroups
2292 .size(); q <= newann.graphGroup; q++)
2294 newGraphGroups.add(q, null);
2296 newGraphGroups.set(newann.graphGroup,
2297 Integer.valueOf(++fgroup));
2299 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2303 newann.padAnnotation(alwidth);
2304 alignment.addAnnotation(newann);
2314 addHistoryItem(new EditCommand(
2315 MessageManager.getString("label.add_sequences"),
2316 Action.PASTE, sequences, 0, alignment.getWidth(),
2319 // Add any annotations attached to sequences
2320 for (int i = 0; i < sequences.length; i++)
2322 if (sequences[i].getAnnotation() != null)
2324 AlignmentAnnotation newann;
2325 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2327 annotationAdded = true;
2328 newann = sequences[i].getAnnotation()[a];
2329 newann.adjustForAlignment();
2330 newann.padAnnotation(alwidth);
2331 if (newann.graphGroup > -1)
2333 if (newann.graphGroup > -1)
2335 if (newGraphGroups.size() <= newann.graphGroup
2336 || newGraphGroups.get(newann.graphGroup) == null)
2338 for (int q = newGraphGroups
2339 .size(); q <= newann.graphGroup; q++)
2341 newGraphGroups.add(q, null);
2343 newGraphGroups.set(newann.graphGroup,
2344 Integer.valueOf(++fgroup));
2346 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2350 // annotation was duplicated earlier
2351 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2352 // take care of contact matrix too
2353 ContactMatrixI cm=sequences[i].getContactMatrixFor(sequences[i].getAnnotation()[a]);
2356 alignment.addContactListFor(sequences[i].getAnnotation()[a], cm);
2359 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2367 // propagate alignment changed.
2368 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2369 if (annotationAdded)
2371 // Duplicate sequence annotation in all views.
2372 AlignmentI[] alview = this.getViewAlignments();
2373 for (int i = 0; i < sequences.length; i++)
2375 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2380 for (int avnum = 0; avnum < alview.length; avnum++)
2382 if (alview[avnum] != alignment)
2384 // duplicate in a view other than the one with input focus
2385 int avwidth = alview[avnum].getWidth() + 1;
2386 // this relies on sann being preserved after we
2387 // modify the sequence's annotation array for each duplication
2388 for (int a = 0; a < sann.length; a++)
2390 AlignmentAnnotation newann = new AlignmentAnnotation(
2392 sequences[i].addAlignmentAnnotation(newann);
2393 newann.padAnnotation(avwidth);
2394 alview[avnum].addAnnotation(newann); // annotation was
2395 // duplicated earlier
2396 // TODO JAL-1145 graphGroups are not updated for sequence
2397 // annotation added to several views. This may cause
2399 alview[avnum].setAnnotationIndex(newann, a);
2404 buildSortByAnnotationScoresMenu();
2406 viewport.firePropertyChange("alignment", null,
2407 alignment.getSequences());
2408 if (alignPanels != null)
2410 for (AlignmentPanel ap : alignPanels)
2412 ap.validateAnnotationDimensions(false);
2417 alignPanel.validateAnnotationDimensions(false);
2423 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2425 String newtitle = new String("Copied sequences");
2427 if (Desktop.jalviewClipboard != null
2428 && Desktop.jalviewClipboard[2] != null)
2430 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2431 af.viewport.setHiddenColumns(hc);
2434 // >>>This is a fix for the moment, until a better solution is
2436 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2437 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2438 .getFeatureRenderer());
2440 // TODO: maintain provenance of an alignment, rather than just make the
2441 // title a concatenation of operations.
2444 if (title.startsWith("Copied sequences"))
2450 newtitle = newtitle.concat("- from " + title);
2455 newtitle = new String("Pasted sequences");
2458 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2463 } catch (Exception ex)
2465 ex.printStackTrace();
2466 System.out.println("Exception whilst pasting: " + ex);
2467 // could be anything being pasted in here
2473 protected void expand_newalign(ActionEvent e)
2477 AlignmentI alignment = AlignmentUtils
2478 .expandContext(getViewport().getAlignment(), -1);
2479 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2481 String newtitle = new String("Flanking alignment");
2483 if (Desktop.jalviewClipboard != null
2484 && Desktop.jalviewClipboard[2] != null)
2486 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2487 af.viewport.setHiddenColumns(hc);
2490 // >>>This is a fix for the moment, until a better solution is
2492 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2493 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2494 .getFeatureRenderer());
2496 // TODO: maintain provenance of an alignment, rather than just make the
2497 // title a concatenation of operations.
2499 if (title.startsWith("Copied sequences"))
2505 newtitle = newtitle.concat("- from " + title);
2509 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2511 } catch (Exception ex)
2513 ex.printStackTrace();
2514 System.out.println("Exception whilst pasting: " + ex);
2515 // could be anything being pasted in here
2516 } catch (OutOfMemoryError oom)
2518 new OOMWarning("Viewing flanking region of alignment", oom);
2523 * Action Cut (delete and copy) the selected region
2526 protected void cut_actionPerformed()
2528 copy_actionPerformed();
2529 delete_actionPerformed();
2533 * Performs menu option to Delete the currently selected region
2536 protected void delete_actionPerformed()
2539 SequenceGroup sg = viewport.getSelectionGroup();
2545 Runnable okAction = () -> {
2546 SequenceI[] cut = sg.getSequences()
2547 .toArray(new SequenceI[sg.getSize()]);
2549 addHistoryItem(new EditCommand(
2550 MessageManager.getString("label.cut_sequences"), Action.CUT,
2551 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2552 viewport.getAlignment()));
2554 viewport.setSelectionGroup(null);
2555 viewport.sendSelection();
2556 viewport.getAlignment().deleteGroup(sg);
2558 viewport.firePropertyChange("alignment", null,
2559 viewport.getAlignment().getSequences());
2560 if (viewport.getAlignment().getHeight() < 1)
2564 AlignFrame.this.setClosed(true);
2565 } catch (Exception ex)
2572 * If the cut affects all sequences, prompt for confirmation
2574 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2576 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2577 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2578 if (wholeHeight && wholeWidth)
2580 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2581 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2582 Object[] options = new Object[] {
2583 MessageManager.getString("action.ok"),
2584 MessageManager.getString("action.cancel") };
2585 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2586 MessageManager.getString("label.delete_all"),
2587 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2588 options, options[0]);
2595 } catch (Exception e)
2597 e.printStackTrace();
2609 protected void deleteGroups_actionPerformed(ActionEvent e)
2611 if (avc.deleteGroups())
2613 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2614 alignPanel.updateAnnotation();
2615 alignPanel.paintAlignment(true, true);
2626 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2628 SequenceGroup sg = new SequenceGroup(
2629 viewport.getAlignment().getSequences());
2631 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2632 viewport.setSelectionGroup(sg);
2633 viewport.isSelectionGroupChanged(true);
2634 viewport.sendSelection();
2635 // JAL-2034 - should delegate to
2636 // alignPanel to decide if overview needs
2638 alignPanel.paintAlignment(false, false);
2639 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2649 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2651 if (viewport.cursorMode)
2653 alignPanel.getSeqPanel().keyboardNo1 = null;
2654 alignPanel.getSeqPanel().keyboardNo2 = null;
2656 viewport.setSelectionGroup(null);
2657 viewport.getColumnSelection().clear();
2658 viewport.setSearchResults(null);
2659 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2660 // JAL-2034 - should delegate to
2661 // alignPanel to decide if overview needs
2663 alignPanel.paintAlignment(false, false);
2664 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2665 viewport.sendSelection();
2675 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2677 SequenceGroup sg = viewport.getSelectionGroup();
2681 selectAllSequenceMenuItem_actionPerformed(null);
2686 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2688 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2690 // JAL-2034 - should delegate to
2691 // alignPanel to decide if overview needs
2694 alignPanel.paintAlignment(true, false);
2695 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2696 viewport.sendSelection();
2700 public void invertColSel_actionPerformed(ActionEvent e)
2702 viewport.invertColumnSelection();
2703 alignPanel.paintAlignment(true, false);
2704 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2705 viewport.sendSelection();
2715 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2717 trimAlignment(true);
2727 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2729 trimAlignment(false);
2732 void trimAlignment(boolean trimLeft)
2734 ColumnSelection colSel = viewport.getColumnSelection();
2737 if (!colSel.isEmpty())
2741 column = colSel.getMin();
2745 column = colSel.getMax();
2749 if (viewport.getSelectionGroup() != null)
2751 seqs = viewport.getSelectionGroup()
2752 .getSequencesAsArray(viewport.getHiddenRepSequences());
2756 seqs = viewport.getAlignment().getSequencesArray();
2759 TrimRegionCommand trimRegion;
2762 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2763 column, viewport.getAlignment());
2764 viewport.getRanges().setStartRes(0);
2768 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2769 column, viewport.getAlignment());
2772 setStatus(MessageManager.formatMessage("label.removed_columns",
2774 { Integer.valueOf(trimRegion.getSize()).toString() }));
2776 addHistoryItem(trimRegion);
2778 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2780 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2781 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2783 viewport.getAlignment().deleteGroup(sg);
2787 viewport.firePropertyChange("alignment", null,
2788 viewport.getAlignment().getSequences());
2799 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2801 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2804 if (viewport.getSelectionGroup() != null)
2806 seqs = viewport.getSelectionGroup()
2807 .getSequencesAsArray(viewport.getHiddenRepSequences());
2808 start = viewport.getSelectionGroup().getStartRes();
2809 end = viewport.getSelectionGroup().getEndRes();
2813 seqs = viewport.getAlignment().getSequencesArray();
2816 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2817 "Remove Gapped Columns", seqs, start, end,
2818 viewport.getAlignment());
2820 addHistoryItem(removeGapCols);
2822 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2824 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2826 // This is to maintain viewport position on first residue
2827 // of first sequence
2828 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2829 ViewportRanges ranges = viewport.getRanges();
2830 int startRes = seq.findPosition(ranges.getStartRes());
2831 // ShiftList shifts;
2832 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2833 // edit.alColumnChanges=shifts.getInverse();
2834 // if (viewport.hasHiddenColumns)
2835 // viewport.getColumnSelection().compensateForEdits(shifts);
2836 ranges.setStartRes(seq.findIndex(startRes) - 1);
2837 viewport.firePropertyChange("alignment", null,
2838 viewport.getAlignment().getSequences());
2849 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2851 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2854 if (viewport.getSelectionGroup() != null)
2856 seqs = viewport.getSelectionGroup()
2857 .getSequencesAsArray(viewport.getHiddenRepSequences());
2858 start = viewport.getSelectionGroup().getStartRes();
2859 end = viewport.getSelectionGroup().getEndRes();
2863 seqs = viewport.getAlignment().getSequencesArray();
2866 // This is to maintain viewport position on first residue
2867 // of first sequence
2868 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2869 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2871 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2872 viewport.getAlignment()));
2874 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2876 viewport.firePropertyChange("alignment", null,
2877 viewport.getAlignment().getSequences());
2888 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2890 viewport.setPadGaps(padGapsMenuitem.isSelected());
2891 viewport.firePropertyChange("alignment", null,
2892 viewport.getAlignment().getSequences());
2896 * Opens a Finder dialog
2901 public void findMenuItem_actionPerformed(ActionEvent e)
2903 new Finder(alignPanel, false, null);
2907 * Create a new view of the current alignment.
2910 public void newView_actionPerformed(ActionEvent e)
2912 newView(null, true);
2916 * Creates and shows a new view of the current alignment.
2919 * title of newly created view; if null, one will be generated
2920 * @param copyAnnotation
2921 * if true then duplicate all annnotation, groups and settings
2922 * @return new alignment panel, already displayed.
2924 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2927 * Create a new AlignmentPanel (with its own, new Viewport)
2929 AlignmentPanel newap = new jalview.project.Jalview2XML()
2930 .copyAlignPanel(alignPanel);
2931 if (!copyAnnotation)
2934 * remove all groups and annotation except for the automatic stuff
2936 newap.av.getAlignment().deleteAllGroups();
2937 newap.av.getAlignment().deleteAllAnnotations(false);
2940 newap.av.setGatherViewsHere(false);
2942 if (viewport.getViewName() == null)
2944 viewport.setViewName(
2945 MessageManager.getString("label.view_name_original"));
2949 * Views share the same edits undo and redo stacks
2951 newap.av.setHistoryList(viewport.getHistoryList());
2952 newap.av.setRedoList(viewport.getRedoList());
2955 * copy any visualisation settings that are not saved in the project
2957 newap.av.setColourAppliesToAllGroups(
2958 viewport.getColourAppliesToAllGroups());
2961 * Views share the same mappings; need to deregister any new mappings
2962 * created by copyAlignPanel, and register the new reference to the shared
2965 newap.av.replaceMappings(viewport.getAlignment());
2968 * start up cDNA consensus (if applicable) now mappings are in place
2970 if (newap.av.initComplementConsensus())
2972 newap.refresh(true); // adjust layout of annotations
2975 newap.av.setViewName(getNewViewName(viewTitle));
2977 addAlignmentPanel(newap, true);
2978 newap.alignmentChanged();
2980 if (alignPanels.size() == 2)
2982 viewport.setGatherViewsHere(true);
2984 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2990 * Make a new name for the view, ensuring it is unique within the current
2991 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2992 * these now use viewId. Unique view names are still desirable for usability.)
2997 protected String getNewViewName(String viewTitle)
2999 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3000 boolean addFirstIndex = false;
3001 if (viewTitle == null || viewTitle.trim().length() == 0)
3003 viewTitle = MessageManager.getString("action.view");
3004 addFirstIndex = true;
3008 index = 1;// we count from 1 if given a specific name
3010 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3012 List<Component> comps = PaintRefresher.components
3013 .get(viewport.getSequenceSetId());
3015 List<String> existingNames = getExistingViewNames(comps);
3017 while (existingNames.contains(newViewName))
3019 newViewName = viewTitle + " " + (++index);
3025 * Returns a list of distinct view names found in the given list of
3026 * components. View names are held on the viewport of an AlignmentPanel.
3031 protected List<String> getExistingViewNames(List<Component> comps)
3033 List<String> existingNames = new ArrayList<>();
3034 for (Component comp : comps)
3036 if (comp instanceof AlignmentPanel)
3038 AlignmentPanel ap = (AlignmentPanel) comp;
3039 if (!existingNames.contains(ap.av.getViewName()))
3041 existingNames.add(ap.av.getViewName());
3045 return existingNames;
3049 * Explode tabbed views into separate windows.
3052 public void expandViews_actionPerformed(ActionEvent e)
3054 Desktop.explodeViews(this);
3058 * Gather views in separate windows back into a tabbed presentation.
3061 public void gatherViews_actionPerformed(ActionEvent e)
3063 Desktop.instance.gatherViews(this);
3073 public void font_actionPerformed(ActionEvent e)
3075 new FontChooser(alignPanel);
3085 protected void seqLimit_actionPerformed(ActionEvent e)
3087 viewport.setShowJVSuffix(seqLimits.isSelected());
3089 alignPanel.getIdPanel().getIdCanvas()
3090 .setPreferredSize(alignPanel.calculateIdWidth());
3091 alignPanel.paintAlignment(true, false);
3095 public void idRightAlign_actionPerformed(ActionEvent e)
3097 viewport.setRightAlignIds(idRightAlign.isSelected());
3098 alignPanel.paintAlignment(false, false);
3102 public void centreColumnLabels_actionPerformed(ActionEvent e)
3104 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3105 alignPanel.paintAlignment(false, false);
3111 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3114 protected void followHighlight_actionPerformed()
3117 * Set the 'follow' flag on the Viewport (and scroll to position if now
3120 final boolean state = this.followHighlightMenuItem.getState();
3121 viewport.setFollowHighlight(state);
3124 alignPanel.scrollToPosition(viewport.getSearchResults());
3135 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3137 viewport.setColourText(colourTextMenuItem.isSelected());
3138 alignPanel.paintAlignment(false, false);
3148 public void wrapMenuItem_actionPerformed(ActionEvent e)
3150 scaleAbove.setVisible(wrapMenuItem.isSelected());
3151 scaleLeft.setVisible(wrapMenuItem.isSelected());
3152 scaleRight.setVisible(wrapMenuItem.isSelected());
3153 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3154 alignPanel.updateLayout();
3158 public void showAllSeqs_actionPerformed(ActionEvent e)
3160 viewport.showAllHiddenSeqs();
3164 public void showAllColumns_actionPerformed(ActionEvent e)
3166 viewport.showAllHiddenColumns();
3167 alignPanel.paintAlignment(true, true);
3168 viewport.sendSelection();
3172 public void hideSelSequences_actionPerformed(ActionEvent e)
3174 viewport.hideAllSelectedSeqs();
3178 * called by key handler and the hide all/show all menu items
3183 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3186 boolean hide = false;
3187 SequenceGroup sg = viewport.getSelectionGroup();
3188 if (!toggleSeqs && !toggleCols)
3190 // Hide everything by the current selection - this is a hack - we do the
3191 // invert and then hide
3192 // first check that there will be visible columns after the invert.
3193 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3194 && sg.getStartRes() <= sg.getEndRes()))
3196 // now invert the sequence set, if required - empty selection implies
3197 // that no hiding is required.
3200 invertSequenceMenuItem_actionPerformed(null);
3201 sg = viewport.getSelectionGroup();
3205 viewport.expandColSelection(sg, true);
3206 // finally invert the column selection and get the new sequence
3208 invertColSel_actionPerformed(null);
3215 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3217 hideSelSequences_actionPerformed(null);
3220 else if (!(toggleCols && viewport.hasSelectedColumns()))
3222 showAllSeqs_actionPerformed(null);
3228 if (viewport.hasSelectedColumns())
3230 hideSelColumns_actionPerformed(null);
3233 viewport.setSelectionGroup(sg);
3238 showAllColumns_actionPerformed(null);
3247 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3248 * event.ActionEvent)
3251 public void hideAllButSelection_actionPerformed(ActionEvent e)
3253 toggleHiddenRegions(false, false);
3254 viewport.sendSelection();
3261 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3265 public void hideAllSelection_actionPerformed(ActionEvent e)
3267 SequenceGroup sg = viewport.getSelectionGroup();
3268 viewport.expandColSelection(sg, false);
3269 viewport.hideAllSelectedSeqs();
3270 viewport.hideSelectedColumns();
3271 alignPanel.updateLayout();
3272 alignPanel.paintAlignment(true, true);
3273 viewport.sendSelection();
3280 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3284 public void showAllhidden_actionPerformed(ActionEvent e)
3286 viewport.showAllHiddenColumns();
3287 viewport.showAllHiddenSeqs();
3288 alignPanel.paintAlignment(true, true);
3289 viewport.sendSelection();
3293 public void hideSelColumns_actionPerformed(ActionEvent e)
3295 viewport.hideSelectedColumns();
3296 alignPanel.updateLayout();
3297 alignPanel.paintAlignment(true, true);
3298 viewport.sendSelection();
3302 public void hiddenMarkers_actionPerformed(ActionEvent e)
3304 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3315 protected void scaleAbove_actionPerformed(ActionEvent e)
3317 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3318 alignPanel.updateLayout();
3319 alignPanel.paintAlignment(true, false);
3329 protected void scaleLeft_actionPerformed(ActionEvent e)
3331 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3332 alignPanel.updateLayout();
3333 alignPanel.paintAlignment(true, false);
3343 protected void scaleRight_actionPerformed(ActionEvent e)
3345 viewport.setScaleRightWrapped(scaleRight.isSelected());
3346 alignPanel.updateLayout();
3347 alignPanel.paintAlignment(true, false);
3357 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3359 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3360 alignPanel.paintAlignment(false, false);
3370 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3372 viewport.setShowText(viewTextMenuItem.isSelected());
3373 alignPanel.paintAlignment(false, false);
3383 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3385 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3386 alignPanel.paintAlignment(false, false);
3389 public FeatureSettings featureSettings;
3392 public FeatureSettingsControllerI getFeatureSettingsUI()
3394 return featureSettings;
3398 public void featureSettings_actionPerformed(ActionEvent e)
3400 showFeatureSettingsUI();
3404 public FeatureSettingsControllerI showFeatureSettingsUI()
3406 if (featureSettings != null)
3408 featureSettings.closeOldSettings();
3409 featureSettings = null;
3411 if (!showSeqFeatures.isSelected())
3413 // make sure features are actually displayed
3414 showSeqFeatures.setSelected(true);
3415 showSeqFeatures_actionPerformed(null);
3417 featureSettings = new FeatureSettings(this);
3418 return featureSettings;
3422 * Set or clear 'Show Sequence Features'
3428 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3430 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3431 alignPanel.paintAlignment(true, true);
3435 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3436 * the annotations panel as a whole.
3438 * The options to show/hide all annotations should be enabled when the panel
3439 * is shown, and disabled when the panel is hidden.
3444 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3446 final boolean setVisible = annotationPanelMenuItem.isSelected();
3447 viewport.setShowAnnotation(setVisible);
3448 this.showAllSeqAnnotations.setEnabled(setVisible);
3449 this.hideAllSeqAnnotations.setEnabled(setVisible);
3450 this.showAllAlAnnotations.setEnabled(setVisible);
3451 this.hideAllAlAnnotations.setEnabled(setVisible);
3452 alignPanel.updateLayout();
3456 public void alignmentProperties()
3459 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3462 String content = MessageManager.formatMessage("label.html_content",
3464 { contents.toString() });
3467 if (Platform.isJS())
3469 JLabel textLabel = new JLabel();
3470 textLabel.setText(content);
3471 textLabel.setBackground(Color.WHITE);
3473 pane = new JPanel(new BorderLayout());
3474 ((JPanel) pane).setOpaque(true);
3475 pane.setBackground(Color.WHITE);
3476 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3485 JEditorPane editPane = new JEditorPane("text/html", "");
3486 editPane.setEditable(false);
3487 editPane.setText(content);
3491 JInternalFrame frame = new JInternalFrame();
3493 frame.getContentPane().add(new JScrollPane(pane));
3495 Desktop.addInternalFrame(frame, MessageManager
3496 .formatMessage("label.alignment_properties", new Object[]
3497 { getTitle() }), 500, 400);
3501 * Opens an Overview panel for the alignment, unless one is open already
3506 public void overviewMenuItem_actionPerformed(ActionEvent e)
3508 boolean showHiddenRegions = Cache
3509 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3510 openOverviewPanel(showHiddenRegions);
3513 public OverviewPanel openOverviewPanel(boolean showHidden)
3515 if (alignPanel.overviewPanel != null)
3517 return alignPanel.overviewPanel;
3519 JInternalFrame frame = new JInternalFrame();
3520 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3522 frame.setContentPane(overview);
3523 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3524 frame.getHeight(), true, true);
3525 frame.setFrameIcon(null);
3527 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3528 final AlignmentPanel thePanel = this.alignPanel;
3529 frame.addInternalFrameListener(
3530 new javax.swing.event.InternalFrameAdapter()
3533 public void internalFrameClosed(
3534 javax.swing.event.InternalFrameEvent evt)
3537 thePanel.setOverviewPanel(null);
3540 if (getKeyListeners().length > 0)
3542 frame.addKeyListener(getKeyListeners()[0]);
3545 alignPanel.setOverviewPanel(overview);
3546 alignPanel.setOverviewTitle(this);
3552 public void textColour_actionPerformed()
3554 new TextColourChooser().chooseColour(alignPanel, null);
3558 * public void covariationColour_actionPerformed() {
3560 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3564 public void annotationColour_actionPerformed()
3566 new AnnotationColourChooser(viewport, alignPanel);
3570 public void annotationColumn_actionPerformed(ActionEvent e)
3572 new AnnotationColumnChooser(viewport, alignPanel);
3576 * Action on the user checking or unchecking the option to apply the selected
3577 * colour scheme to all groups. If unchecked, groups may have their own
3578 * independent colour schemes.
3583 public void applyToAllGroups_actionPerformed(boolean selected)
3585 viewport.setColourAppliesToAllGroups(selected);
3589 * Action on user selecting a colour from the colour menu
3592 * the name (not the menu item label!) of the colour scheme
3595 public void changeColour_actionPerformed(String name)
3598 * 'User Defined' opens a panel to configure or load a
3599 * user-defined colour scheme
3601 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3603 new UserDefinedColours(alignPanel);
3608 * otherwise set the chosen colour scheme (or null for 'None')
3610 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3611 viewport, viewport.getAlignment(),
3612 viewport.getHiddenRepSequences());
3617 * Actions on setting or changing the alignment colour scheme
3622 public void changeColour(ColourSchemeI cs)
3624 // TODO: pull up to controller method
3625 ColourMenuHelper.setColourSelected(colourMenu, cs);
3627 viewport.setGlobalColourScheme(cs);
3629 alignPanel.paintAlignment(true, true);
3633 * Show the PID threshold slider panel
3636 protected void modifyPID_actionPerformed()
3638 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3639 alignPanel.getViewName());
3640 SliderPanel.showPIDSlider();
3644 * Show the Conservation slider panel
3647 protected void modifyConservation_actionPerformed()
3649 SliderPanel.setConservationSlider(alignPanel,
3650 viewport.getResidueShading(), alignPanel.getViewName());
3651 SliderPanel.showConservationSlider();
3655 * Action on selecting or deselecting (Colour) By Conservation
3658 public void conservationMenuItem_actionPerformed(boolean selected)
3660 modifyConservation.setEnabled(selected);
3661 viewport.setConservationSelected(selected);
3662 viewport.getResidueShading().setConservationApplied(selected);
3664 changeColour(viewport.getGlobalColourScheme());
3667 modifyConservation_actionPerformed();
3671 SliderPanel.hideConservationSlider();
3676 * Action on selecting or deselecting (Colour) Above PID Threshold
3679 public void abovePIDThreshold_actionPerformed(boolean selected)
3681 modifyPID.setEnabled(selected);
3682 viewport.setAbovePIDThreshold(selected);
3685 viewport.getResidueShading().setThreshold(0,
3686 viewport.isIgnoreGapsConsensus());
3689 changeColour(viewport.getGlobalColourScheme());
3692 modifyPID_actionPerformed();
3696 SliderPanel.hidePIDSlider();
3707 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3709 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3710 AlignmentSorter.sortByPID(viewport.getAlignment(),
3711 viewport.getAlignment().getSequenceAt(0));
3712 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3713 viewport.getAlignment()));
3714 alignPanel.paintAlignment(true, false);
3724 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3726 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3727 AlignmentSorter.sortByID(viewport.getAlignment());
3729 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3730 alignPanel.paintAlignment(true, false);
3740 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3742 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3743 AlignmentSorter.sortByLength(viewport.getAlignment());
3744 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3745 viewport.getAlignment()));
3746 alignPanel.paintAlignment(true, false);
3756 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3758 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3759 AlignmentSorter.sortByGroup(viewport.getAlignment());
3760 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3761 viewport.getAlignment()));
3763 alignPanel.paintAlignment(true, false);
3773 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3775 new RedundancyPanel(alignPanel, this);
3785 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3787 if ((viewport.getSelectionGroup() == null)
3788 || (viewport.getSelectionGroup().getSize() < 2))
3790 JvOptionPane.showInternalMessageDialog(this,
3791 MessageManager.getString(
3792 "label.you_must_select_least_two_sequences"),
3793 MessageManager.getString("label.invalid_selection"),
3794 JvOptionPane.WARNING_MESSAGE);
3798 JInternalFrame frame = new JInternalFrame();
3799 frame.setContentPane(new PairwiseAlignPanel(viewport));
3800 Desktop.addInternalFrame(frame,
3801 MessageManager.getString("action.pairwise_alignment"), 600,
3807 public void autoCalculate_actionPerformed(ActionEvent e)
3809 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3810 if (viewport.autoCalculateConsensus)
3812 viewport.firePropertyChange("alignment", null,
3813 viewport.getAlignment().getSequences());
3818 public void sortByTreeOption_actionPerformed(ActionEvent e)
3820 viewport.sortByTree = sortByTree.isSelected();
3824 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3826 viewport.followSelection = listenToViewSelections.isSelected();
3830 * Constructs a tree panel and adds it to the desktop
3833 * tree type (NJ or AV)
3835 * name of score model used to compute the tree
3837 * parameters for the distance or similarity calculation
3839 void newTreePanel(String type, String modelName,
3840 SimilarityParamsI options)
3842 String frameTitle = "";
3845 boolean onSelection = false;
3846 if (viewport.getSelectionGroup() != null
3847 && viewport.getSelectionGroup().getSize() > 0)
3849 SequenceGroup sg = viewport.getSelectionGroup();
3851 /* Decide if the selection is a column region */
3852 for (SequenceI _s : sg.getSequences())
3854 if (_s.getLength() < sg.getEndRes())
3856 JvOptionPane.showMessageDialog(Desktop.desktop,
3857 MessageManager.getString(
3858 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3859 MessageManager.getString(
3860 "label.sequences_selection_not_aligned"),
3861 JvOptionPane.WARNING_MESSAGE);
3870 if (viewport.getAlignment().getHeight() < 2)
3876 tp = new TreePanel(alignPanel, type, modelName, options);
3877 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3879 frameTitle += " from ";
3881 if (viewport.getViewName() != null)
3883 frameTitle += viewport.getViewName() + " of ";
3886 frameTitle += this.title;
3888 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3899 public void addSortByOrderMenuItem(String title,
3900 final AlignmentOrder order)
3902 final JMenuItem item = new JMenuItem(MessageManager
3903 .formatMessage("action.by_title_param", new Object[]
3906 item.addActionListener(new java.awt.event.ActionListener()
3909 public void actionPerformed(ActionEvent e)
3911 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3913 // TODO: JBPNote - have to map order entries to curent SequenceI
3915 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3917 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3918 viewport.getAlignment()));
3920 alignPanel.paintAlignment(true, false);
3926 * Add a new sort by annotation score menu item
3929 * the menu to add the option to
3931 * the label used to retrieve scores for each sequence on the
3934 public void addSortByAnnotScoreMenuItem(JMenu sort,
3935 final String scoreLabel)
3937 final JMenuItem item = new JMenuItem(scoreLabel);
3939 item.addActionListener(new java.awt.event.ActionListener()
3942 public void actionPerformed(ActionEvent e)
3944 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3945 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3946 viewport.getAlignment());// ,viewport.getSelectionGroup());
3947 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3948 viewport.getAlignment()));
3949 alignPanel.paintAlignment(true, false);
3955 * last hash for alignment's annotation array - used to minimise cost of
3958 protected int _annotationScoreVectorHash;
3961 * search the alignment and rebuild the sort by annotation score submenu the
3962 * last alignment annotation vector hash is stored to minimize cost of
3963 * rebuilding in subsequence calls.
3967 public void buildSortByAnnotationScoresMenu()
3969 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3974 if (viewport.getAlignment().getAlignmentAnnotation()
3975 .hashCode() != _annotationScoreVectorHash)
3977 sortByAnnotScore.removeAll();
3978 // almost certainly a quicker way to do this - but we keep it simple
3979 Hashtable<String, String> scoreSorts = new Hashtable<>();
3980 AlignmentAnnotation aann[];
3981 for (SequenceI sqa : viewport.getAlignment().getSequences())
3983 aann = sqa.getAnnotation();
3984 for (int i = 0; aann != null && i < aann.length; i++)
3986 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3988 scoreSorts.put(aann[i].label, aann[i].label);
3992 Enumeration<String> labels = scoreSorts.keys();
3993 while (labels.hasMoreElements())
3995 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3997 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4000 _annotationScoreVectorHash = viewport.getAlignment()
4001 .getAlignmentAnnotation().hashCode();
4006 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4007 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4008 * call. Listeners are added to remove the menu item when the treePanel is
4009 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4013 public void buildTreeSortMenu()
4015 sortByTreeMenu.removeAll();
4017 List<Component> comps = PaintRefresher.components
4018 .get(viewport.getSequenceSetId());
4019 List<TreePanel> treePanels = new ArrayList<>();
4020 for (Component comp : comps)
4022 if (comp instanceof TreePanel)
4024 treePanels.add((TreePanel) comp);
4028 if (treePanels.size() < 1)
4030 sortByTreeMenu.setVisible(false);
4034 sortByTreeMenu.setVisible(true);
4036 for (final TreePanel tp : treePanels)
4038 final JMenuItem item = new JMenuItem(tp.getTitle());
4039 item.addActionListener(new java.awt.event.ActionListener()
4042 public void actionPerformed(ActionEvent e)
4044 tp.sortByTree_actionPerformed();
4045 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4050 sortByTreeMenu.add(item);
4054 public boolean sortBy(AlignmentOrder alorder, String undoname)
4056 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4057 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4058 if (undoname != null)
4060 addHistoryItem(new OrderCommand(undoname, oldOrder,
4061 viewport.getAlignment()));
4063 alignPanel.paintAlignment(true, false);
4068 * Work out whether the whole set of sequences or just the selected set will
4069 * be submitted for multiple alignment.
4072 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4074 // Now, check we have enough sequences
4075 AlignmentView msa = null;
4077 if ((viewport.getSelectionGroup() != null)
4078 && (viewport.getSelectionGroup().getSize() > 1))
4080 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4081 // some common interface!
4083 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4084 * SequenceI[sz = seqs.getSize(false)];
4086 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4087 * seqs.getSequenceAt(i); }
4089 msa = viewport.getAlignmentView(true);
4091 else if (viewport.getSelectionGroup() != null
4092 && viewport.getSelectionGroup().getSize() == 1)
4094 int option = JvOptionPane.showConfirmDialog(this,
4095 MessageManager.getString("warn.oneseq_msainput_selection"),
4096 MessageManager.getString("label.invalid_selection"),
4097 JvOptionPane.OK_CANCEL_OPTION);
4098 if (option == JvOptionPane.OK_OPTION)
4100 msa = viewport.getAlignmentView(false);
4105 msa = viewport.getAlignmentView(false);
4111 * Decides what is submitted to a secondary structure prediction service: the
4112 * first sequence in the alignment, or in the current selection, or, if the
4113 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4114 * region or the whole alignment. (where the first sequence in the set is the
4115 * one that the prediction will be for).
4117 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4119 AlignmentView seqs = null;
4121 if ((viewport.getSelectionGroup() != null)
4122 && (viewport.getSelectionGroup().getSize() > 0))
4124 seqs = viewport.getAlignmentView(true);
4128 seqs = viewport.getAlignmentView(false);
4130 // limit sequences - JBPNote in future - could spawn multiple prediction
4132 // TODO: viewport.getAlignment().isAligned is a global state - the local
4133 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4134 if (!viewport.getAlignment().isAligned(false))
4136 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4137 // TODO: if seqs.getSequences().length>1 then should really have warned
4151 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4153 // Pick the tree file
4154 JalviewFileChooser chooser = new JalviewFileChooser(
4155 Cache.getProperty("LAST_DIRECTORY"));
4156 chooser.setFileView(new JalviewFileView());
4157 chooser.setDialogTitle(
4158 MessageManager.getString("label.select_newick_like_tree_file"));
4159 chooser.setToolTipText(
4160 MessageManager.getString("label.load_tree_file"));
4162 chooser.setResponseHandler(0, () -> {
4163 String filePath = chooser.getSelectedFile().getPath();
4164 Cache.setProperty("LAST_DIRECTORY", filePath);
4165 NewickFile fin = null;
4168 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4169 DataSourceType.FILE));
4170 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4171 } catch (Exception ex)
4173 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4174 MessageManager.getString("label.problem_reading_tree_file"),
4175 JvOptionPane.WARNING_MESSAGE);
4176 ex.printStackTrace();
4178 if (fin != null && fin.hasWarningMessage())
4180 JvOptionPane.showMessageDialog(Desktop.desktop,
4181 fin.getWarningMessage(),
4183 .getString("label.possible_problem_with_tree_file"),
4184 JvOptionPane.WARNING_MESSAGE);
4187 chooser.showOpenDialog(this);
4190 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4192 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4195 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4196 int h, int x, int y)
4198 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4202 * Add a treeviewer for the tree extracted from a Newick file object to the
4203 * current alignment view
4210 * Associated alignment input data (or null)
4219 * @return TreePanel handle
4221 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4222 AlignmentView input, int w, int h, int x, int y)
4224 TreePanel tp = null;
4230 if (nf.getTree() != null)
4232 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4238 tp.setLocation(x, y);
4241 Desktop.addInternalFrame(tp, treeTitle, w, h);
4243 } catch (Exception ex)
4245 ex.printStackTrace();
4251 public void showContactMapTree(AlignmentAnnotation aa,
4255 int w = 400, h = 500;
4259 NewickFile fin = new NewickFile(
4260 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4261 String title = aa.label + " "
4262 + cm.getTreeMethod() + " tree" + (aa.sequenceRef != null
4263 ? (" for " + aa.sequenceRef.getDisplayId(false))
4266 showColumnWiseTree(fin, aa, title, w, h, x, y);
4267 } catch (Throwable xx)
4269 Console.error("Unexpected exception showing tree for contact matrix",
4274 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4275 String treeTitle, int w, int h, int x, int y)
4280 if (nf.getTree() == null)
4284 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4290 tp.setLocation(x, y);
4293 Desktop.addInternalFrame(tp, treeTitle, w, h);
4295 } catch (Throwable xx)
4297 Console.error("Unexpected exception showing tree for contact matrix",
4303 private boolean buildingMenu = false;
4306 * Generates menu items and listener event actions for web service clients
4309 public void BuildWebServiceMenu()
4311 while (buildingMenu)
4315 System.err.println("Waiting for building menu to finish.");
4317 } catch (Exception e)
4321 final AlignFrame me = this;
4322 buildingMenu = true;
4323 new Thread(new Runnable()
4328 final List<JMenuItem> legacyItems = new ArrayList<>();
4331 // System.err.println("Building ws menu again "
4332 // + Thread.currentThread());
4333 // TODO: add support for context dependent disabling of services based
4335 // alignment and current selection
4336 // TODO: add additional serviceHandle parameter to specify abstract
4338 // class independently of AbstractName
4339 // TODO: add in rediscovery GUI function to restart discoverer
4340 // TODO: group services by location as well as function and/or
4342 // object broker mechanism.
4343 final Vector<JMenu> wsmenu = new Vector<>();
4344 final IProgressIndicator af = me;
4347 * do not i18n these strings - they are hard-coded in class
4348 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4349 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4351 final JMenu msawsmenu = new JMenu("Alignment");
4352 final JMenu secstrmenu = new JMenu(
4353 "Secondary Structure Prediction");
4354 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4355 final JMenu analymenu = new JMenu("Analysis");
4356 final JMenu dismenu = new JMenu("Protein Disorder");
4357 // JAL-940 - only show secondary structure prediction services from
4358 // the legacy server
4359 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4361 Discoverer.services != null && (Discoverer.services.size() > 0))
4363 // TODO: refactor to allow list of AbstractName/Handler bindings to
4365 // stored or retrieved from elsewhere
4366 // No MSAWS used any more:
4367 // Vector msaws = null; // (Vector)
4368 // Discoverer.services.get("MsaWS");
4369 Vector<ServiceHandle> secstrpr = Discoverer.services
4371 if (secstrpr != null)
4373 // Add any secondary structure prediction services
4374 for (int i = 0, j = secstrpr.size(); i < j; i++)
4376 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4377 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4378 .getServiceClient(sh);
4379 int p = secstrmenu.getItemCount();
4380 impl.attachWSMenuEntry(secstrmenu, me);
4381 int q = secstrmenu.getItemCount();
4382 for (int litm = p; litm < q; litm++)
4384 legacyItems.add(secstrmenu.getItem(litm));
4390 // Add all submenus in the order they should appear on the web
4392 wsmenu.add(msawsmenu);
4393 wsmenu.add(secstrmenu);
4394 wsmenu.add(dismenu);
4395 wsmenu.add(analymenu);
4396 // No search services yet
4397 // wsmenu.add(seqsrchmenu);
4399 javax.swing.SwingUtilities.invokeLater(new Runnable()
4406 webService.removeAll();
4407 // first, add discovered services onto the webservices menu
4408 if (wsmenu.size() > 0)
4410 for (int i = 0, j = wsmenu.size(); i < j; i++)
4412 webService.add(wsmenu.get(i));
4417 webService.add(me.webServiceNoServices);
4419 // TODO: move into separate menu builder class.
4421 // logic for 2.11.1.4 is
4422 // always look to see if there is a discover. if there isn't
4423 // we can't show any Jws2 services
4424 // if there are services available, show them - regardless of
4425 // the 'show JWS2 preference'
4426 // if the discoverer is running then say so
4427 // otherwise offer to trigger discovery if 'show JWS2' is not
4429 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4430 if (jws2servs != null)
4432 if (jws2servs.hasServices())
4434 jws2servs.attachWSMenuEntry(webService, me);
4435 for (Jws2Instance sv : jws2servs.getServices())
4437 if (sv.description.toLowerCase(Locale.ROOT)
4440 for (JMenuItem jmi : legacyItems)
4442 jmi.setVisible(false);
4448 if (jws2servs.isRunning())
4450 JMenuItem tm = new JMenuItem(
4451 "Still discovering JABA Services");
4452 tm.setEnabled(false);
4455 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4457 JMenuItem enableJws2 = new JMenuItem(
4458 "Discover Web Services");
4459 enableJws2.setToolTipText(
4460 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4461 enableJws2.setEnabled(true);
4462 enableJws2.addActionListener(new ActionListener()
4466 public void actionPerformed(ActionEvent e)
4468 // start service discoverer, but ignore preference
4469 Desktop.instance.startServiceDiscovery(false,
4473 webService.add(enableJws2);
4477 build_urlServiceMenu(me.webService);
4478 build_fetchdbmenu(webService);
4479 for (JMenu item : wsmenu)
4481 if (item.getItemCount() == 0)
4483 item.setEnabled(false);
4487 item.setEnabled(true);
4490 } catch (Exception e)
4493 "Exception during web service menu building process.",
4498 } catch (Exception e)
4501 buildingMenu = false;
4508 * construct any groupURL type service menu entries.
4512 protected void build_urlServiceMenu(JMenu webService)
4514 // TODO: remove this code when 2.7 is released
4515 // DEBUG - alignmentView
4517 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4518 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4520 * @Override public void actionPerformed(ActionEvent e) {
4521 * jalview.datamodel.AlignmentView
4522 * .testSelectionViews(af.viewport.getAlignment(),
4523 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4525 * }); webService.add(testAlView);
4527 // TODO: refactor to RestClient discoverer and merge menu entries for
4528 // rest-style services with other types of analysis/calculation service
4529 // SHmmr test client - still being implemented.
4530 // DEBUG - alignmentView
4532 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4535 client.attachWSMenuEntry(
4536 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4542 * Searches the alignment sequences for xRefs and builds the Show
4543 * Cross-References menu (formerly called Show Products), with database
4544 * sources for which cross-references are found (protein sources for a
4545 * nucleotide alignment and vice versa)
4547 * @return true if Show Cross-references menu should be enabled
4549 public boolean canShowProducts()
4551 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4552 AlignmentI dataset = viewport.getAlignment().getDataset();
4554 showProducts.removeAll();
4555 final boolean dna = viewport.getAlignment().isNucleotide();
4557 if (seqs == null || seqs.length == 0)
4559 // nothing to see here.
4563 boolean showp = false;
4566 List<String> ptypes = new CrossRef(seqs, dataset)
4567 .findXrefSourcesForSequences(dna);
4569 for (final String source : ptypes)
4572 final AlignFrame af = this;
4573 JMenuItem xtype = new JMenuItem(source);
4574 xtype.addActionListener(new ActionListener()
4577 public void actionPerformed(ActionEvent e)
4579 showProductsFor(af.viewport.getSequenceSelection(), dna,
4583 showProducts.add(xtype);
4585 showProducts.setVisible(showp);
4586 showProducts.setEnabled(showp);
4587 } catch (Exception e)
4590 "canShowProducts threw an exception - please report to help@jalview.org",
4598 * Finds and displays cross-references for the selected sequences (protein
4599 * products for nucleotide sequences, dna coding sequences for peptides).
4602 * the sequences to show cross-references for
4604 * true if from a nucleotide alignment (so showing proteins)
4606 * the database to show cross-references for
4608 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4609 final String source)
4611 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4616 * Construct and display a new frame containing the translation of this
4617 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4620 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4622 AlignmentI al = null;
4625 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4627 al = dna.translateCdna(codeTable);
4628 } catch (Exception ex)
4630 Console.error("Exception during translation. Please report this !",
4632 final String msg = MessageManager.getString(
4633 "label.error_when_translating_sequences_submit_bug_report");
4634 final String errorTitle = MessageManager
4635 .getString("label.implementation_error")
4636 + MessageManager.getString("label.translation_failed");
4637 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4638 JvOptionPane.ERROR_MESSAGE);
4641 if (al == null || al.getHeight() == 0)
4643 final String msg = MessageManager.getString(
4644 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4645 final String errorTitle = MessageManager
4646 .getString("label.translation_failed");
4647 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4648 JvOptionPane.WARNING_MESSAGE);
4652 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4653 af.setFileFormat(this.currentFileFormat);
4654 final String newTitle = MessageManager
4655 .formatMessage("label.translation_of_params", new Object[]
4656 { this.getTitle(), codeTable.getId() });
4657 af.setTitle(newTitle);
4658 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4660 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4661 viewport.openSplitFrame(af, new Alignment(seqs));
4665 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4672 * Set the file format
4676 public void setFileFormat(FileFormatI format)
4678 this.currentFileFormat = format;
4682 * Try to load a features file onto the alignment.
4685 * contents or path to retrieve file or a File object
4687 * access mode of file (see jalview.io.AlignFile)
4688 * @return true if features file was parsed correctly.
4690 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4693 return avc.parseFeaturesFile(file, sourceType,
4694 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4699 public void refreshFeatureUI(boolean enableIfNecessary)
4701 // note - currently this is only still here rather than in the controller
4702 // because of the featureSettings hard reference that is yet to be
4704 if (enableIfNecessary)
4706 viewport.setShowSequenceFeatures(true);
4707 showSeqFeatures.setSelected(true);
4713 public void dragEnter(DropTargetDragEvent evt)
4718 public void dragExit(DropTargetEvent evt)
4723 public void dragOver(DropTargetDragEvent evt)
4728 public void dropActionChanged(DropTargetDragEvent evt)
4733 public void drop(DropTargetDropEvent evt)
4735 // JAL-1552 - acceptDrop required before getTransferable call for
4736 // Java's Transferable for native dnd
4737 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4738 Transferable t = evt.getTransferable();
4740 final AlignFrame thisaf = this;
4741 final List<Object> files = new ArrayList<>();
4742 List<DataSourceType> protocols = new ArrayList<>();
4746 Desktop.transferFromDropTarget(files, protocols, evt, t);
4747 } catch (Exception e)
4749 e.printStackTrace();
4753 new Thread(new Runnable()
4760 // check to see if any of these files have names matching sequences
4763 SequenceIdMatcher idm = new SequenceIdMatcher(
4764 viewport.getAlignment().getSequencesArray());
4766 * Object[] { String,SequenceI}
4768 ArrayList<Object[]> filesmatched = new ArrayList<>();
4769 ArrayList<Object> filesnotmatched = new ArrayList<>();
4770 for (int i = 0; i < files.size(); i++)
4773 Object file = files.get(i);
4774 String fileName = file.toString();
4776 DataSourceType protocol = (file instanceof File
4777 ? DataSourceType.FILE
4778 : FormatAdapter.checkProtocol(fileName));
4779 if (protocol == DataSourceType.FILE)
4782 if (file instanceof File)
4785 Platform.cacheFileData(fl);
4789 fl = new File(fileName);
4791 pdbfn = fl.getName();
4793 else if (protocol == DataSourceType.URL)
4795 URL url = new URL(fileName);
4796 pdbfn = url.getFile();
4798 if (pdbfn.length() > 0)
4800 // attempt to find a match in the alignment
4801 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4802 int l = 0, c = pdbfn.indexOf(".");
4803 while (mtch == null && c != -1)
4808 } while ((c = pdbfn.indexOf(".", l)) > l);
4811 pdbfn = pdbfn.substring(0, l);
4813 mtch = idm.findAllIdMatches(pdbfn);
4820 type = new IdentifyFile().identify(file, protocol);
4821 } catch (Exception ex)
4825 if (type != null && type.isStructureFile())
4827 filesmatched.add(new Object[] { file, protocol, mtch });
4831 // File wasn't named like one of the sequences or wasn't a PDB
4833 filesnotmatched.add(file);
4837 if (filesmatched.size() > 0)
4839 boolean autoAssociate = Cache
4840 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4843 String msg = MessageManager.formatMessage(
4844 "label.automatically_associate_structure_files_with_sequences_same_name",
4846 { Integer.valueOf(filesmatched.size())
4848 String ttl = MessageManager.getString(
4849 "label.automatically_associate_structure_files_by_name");
4850 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4851 ttl, JvOptionPane.YES_NO_OPTION);
4852 autoAssociate = choice == JvOptionPane.YES_OPTION;
4856 for (Object[] fm : filesmatched)
4858 // try and associate
4859 // TODO: may want to set a standard ID naming formalism for
4860 // associating PDB files which have no IDs.
4861 for (SequenceI toassoc : (SequenceI[]) fm[2])
4863 PDBEntry pe = new AssociatePdbFileWithSeq()
4864 .associatePdbWithSeq(fm[0].toString(),
4865 (DataSourceType) fm[1], toassoc, false,
4869 System.err.println("Associated file : "
4870 + (fm[0].toString()) + " with "
4871 + toassoc.getDisplayId(true));
4875 // TODO: do we need to update overview ? only if features are
4877 alignPanel.paintAlignment(true, false);
4883 * add declined structures as sequences
4885 for (Object[] o : filesmatched)
4887 filesnotmatched.add(o[0]);
4891 if (filesnotmatched.size() > 0)
4893 if (assocfiles > 0 && (Cache.getDefault(
4894 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4895 || JvOptionPane.showConfirmDialog(thisaf,
4896 "<html>" + MessageManager.formatMessage(
4897 "label.ignore_unmatched_dropped_files_info",
4900 filesnotmatched.size())
4903 MessageManager.getString(
4904 "label.ignore_unmatched_dropped_files"),
4905 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4909 for (Object fn : filesnotmatched)
4911 loadJalviewDataFile(fn, null, null, null);
4915 } catch (Exception ex)
4917 ex.printStackTrace();
4925 * Attempt to load a "dropped" file or URL string, by testing in turn for
4927 * <li>an Annotation file</li>
4928 * <li>a JNet file</li>
4929 * <li>a features file</li>
4930 * <li>else try to interpret as an alignment file</li>
4934 * either a filename or a URL string.
4936 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4937 FileFormatI format, SequenceI assocSeq)
4939 // BH 2018 was String file
4942 if (sourceType == null)
4944 sourceType = FormatAdapter.checkProtocol(file);
4946 // if the file isn't identified, or not positively identified as some
4947 // other filetype (PFAM is default unidentified alignment file type) then
4948 // try to parse as annotation.
4949 boolean isAnnotation = (format == null
4950 || FileFormat.Pfam.equals(format))
4951 ? new AnnotationFile().annotateAlignmentView(viewport,
4957 // first see if its a T-COFFEE score file
4958 TCoffeeScoreFile tcf = null;
4961 tcf = new TCoffeeScoreFile(file, sourceType);
4964 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4968 new TCoffeeColourScheme(viewport.getAlignment()));
4969 isAnnotation = true;
4970 setStatus(MessageManager.getString(
4971 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4975 // some problem - if no warning its probable that the ID matching
4976 // process didn't work
4977 JvOptionPane.showMessageDialog(Desktop.desktop,
4978 tcf.getWarningMessage() == null
4979 ? MessageManager.getString(
4980 "label.check_file_matches_sequence_ids_alignment")
4981 : tcf.getWarningMessage(),
4982 MessageManager.getString(
4983 "label.problem_reading_tcoffee_score_file"),
4984 JvOptionPane.WARNING_MESSAGE);
4991 } catch (Exception x)
4994 "Exception when processing data source as T-COFFEE score file",
5000 // try to see if its a JNet 'concise' style annotation file *before*
5002 // try to parse it as a features file
5005 format = new IdentifyFile().identify(file, sourceType);
5007 if (FileFormat.ScoreMatrix == format)
5009 ScoreMatrixFile sm = new ScoreMatrixFile(
5010 new FileParse(file, sourceType));
5012 // todo: i18n this message
5013 setStatus(MessageManager.formatMessage(
5014 "label.successfully_loaded_matrix",
5015 sm.getMatrixName()));
5017 else if (FileFormat.Jnet.equals(format))
5019 JPredFile predictions = new JPredFile(file, sourceType);
5020 new JnetAnnotationMaker();
5021 JnetAnnotationMaker.add_annotation(predictions,
5022 viewport.getAlignment(), 0, false);
5023 viewport.getAlignment().setupJPredAlignment();
5024 isAnnotation = true;
5026 // else if (IdentifyFile.FeaturesFile.equals(format))
5027 else if (FileFormat.Features.equals(format))
5029 if (parseFeaturesFile(file, sourceType))
5031 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5032 if (splitFrame != null)
5034 splitFrame.repaint();
5038 alignPanel.paintAlignment(true, true);
5044 new FileLoader().LoadFile(viewport, file, sourceType, format);
5051 alignPanel.adjustAnnotationHeight();
5052 viewport.updateSequenceIdColours();
5053 buildSortByAnnotationScoresMenu();
5054 alignPanel.paintAlignment(true, true);
5056 } catch (Exception ex)
5058 ex.printStackTrace();
5059 } catch (OutOfMemoryError oom)
5064 } catch (Exception x)
5069 + (sourceType != null
5070 ? (sourceType == DataSourceType.PASTE
5072 : "using " + sourceType + " from "
5076 ? "(parsing as '" + format + "' file)"
5078 oom, Desktop.desktop);
5083 * Method invoked by the ChangeListener on the tabbed pane, in other words
5084 * when a different tabbed pane is selected by the user or programmatically.
5087 public void tabSelectionChanged(int index)
5092 * update current Overview window title (if there is one)
5093 * to add view name "Original" if necessary
5095 alignPanel.setOverviewTitle(this);
5098 * switch panels and set Overview title (if there is one
5099 * because it was opened automatically)
5101 alignPanel = alignPanels.get(index);
5102 alignPanel.setOverviewTitle(this);
5104 viewport = alignPanel.av;
5105 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5106 setMenusFromViewport(viewport);
5107 if (featureSettings != null && featureSettings.isOpen()
5108 && featureSettings.fr.getViewport() != viewport)
5110 if (viewport.isShowSequenceFeatures())
5112 // refresh the featureSettings to reflect UI change
5113 showFeatureSettingsUI();
5117 // close feature settings for this view.
5118 featureSettings.close();
5125 * 'focus' any colour slider that is open to the selected viewport
5127 if (viewport.getConservationSelected())
5129 SliderPanel.setConservationSlider(alignPanel,
5130 viewport.getResidueShading(), alignPanel.getViewName());
5134 SliderPanel.hideConservationSlider();
5136 if (viewport.getAbovePIDThreshold())
5138 SliderPanel.setPIDSliderSource(alignPanel,
5139 viewport.getResidueShading(), alignPanel.getViewName());
5143 SliderPanel.hidePIDSlider();
5147 * If there is a frame linked to this one in a SplitPane, switch it to the
5148 * same view tab index. No infinite recursion of calls should happen, since
5149 * tabSelectionChanged() should not get invoked on setting the selected
5150 * index to an unchanged value. Guard against setting an invalid index
5151 * before the new view peer tab has been created.
5153 final AlignViewportI peer = viewport.getCodingComplement();
5156 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5157 .getAlignPanel().alignFrame;
5158 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5160 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5166 * On right mouse click on view tab, prompt for and set new view name.
5169 public void tabbedPane_mousePressed(MouseEvent e)
5171 if (e.isPopupTrigger())
5173 String msg = MessageManager.getString("label.enter_view_name");
5174 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5175 String reply = JvOptionPane.showInputDialog(msg, ttl);
5179 viewport.setViewName(reply);
5180 // TODO warn if reply is in getExistingViewNames()?
5181 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5186 public AlignViewport getCurrentView()
5192 * Open the dialog for regex description parsing.
5195 protected void extractScores_actionPerformed(ActionEvent e)
5197 ParseProperties pp = new jalview.analysis.ParseProperties(
5198 viewport.getAlignment());
5199 // TODO: verify regex and introduce GUI dialog for version 2.5
5200 // if (pp.getScoresFromDescription("col", "score column ",
5201 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5203 if (pp.getScoresFromDescription("description column",
5204 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5206 buildSortByAnnotationScoresMenu();
5214 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5218 protected void showDbRefs_actionPerformed(ActionEvent e)
5220 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5226 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5230 protected void showNpFeats_actionPerformed(ActionEvent e)
5232 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5236 * find the viewport amongst the tabs in this alignment frame and close that
5241 public boolean closeView(AlignViewportI av)
5245 this.closeMenuItem_actionPerformed(false);
5248 Component[] comp = tabbedPane.getComponents();
5249 for (int i = 0; comp != null && i < comp.length; i++)
5251 if (comp[i] instanceof AlignmentPanel)
5253 if (((AlignmentPanel) comp[i]).av == av)
5256 closeView((AlignmentPanel) comp[i]);
5264 protected void build_fetchdbmenu(JMenu webService)
5266 // Temporary hack - DBRef Fetcher always top level ws entry.
5267 // TODO We probably want to store a sequence database checklist in
5268 // preferences and have checkboxes.. rather than individual sources selected
5270 final JMenu rfetch = new JMenu(
5271 MessageManager.getString("action.fetch_db_references"));
5272 rfetch.setToolTipText(MessageManager.getString(
5273 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5274 webService.add(rfetch);
5276 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5277 MessageManager.getString("option.trim_retrieved_seqs"));
5278 trimrs.setToolTipText(
5279 MessageManager.getString("label.trim_retrieved_sequences"));
5281 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5282 trimrs.addActionListener(new ActionListener()
5285 public void actionPerformed(ActionEvent e)
5287 trimrs.setSelected(trimrs.isSelected());
5288 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5289 Boolean.valueOf(trimrs.isSelected()).toString());
5293 JMenuItem fetchr = new JMenuItem(
5294 MessageManager.getString("label.standard_databases"));
5295 fetchr.setToolTipText(
5296 MessageManager.getString("label.fetch_embl_uniprot"));
5297 fetchr.addActionListener(new ActionListener()
5301 public void actionPerformed(ActionEvent e)
5303 new Thread(new Runnable()
5308 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5309 .getAlignment().isNucleotide();
5310 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5311 alignPanel.av.getSequenceSelection(),
5312 alignPanel.alignFrame, null,
5313 alignPanel.alignFrame.featureSettings, isNucleotide);
5314 dbRefFetcher.addListener(new FetchFinishedListenerI()
5317 public void finished()
5320 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5321 .getFeatureSettingsModels())
5324 alignPanel.av.mergeFeaturesStyle(srcSettings);
5326 AlignFrame.this.setMenusForViewport();
5329 dbRefFetcher.fetchDBRefs(false);
5337 new Thread(new Runnable()
5342 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5343 .getSequenceFetcherSingleton();
5344 javax.swing.SwingUtilities.invokeLater(new Runnable()
5349 String[] dbclasses = sf.getNonAlignmentSources();
5350 List<DbSourceProxy> otherdb;
5351 JMenu dfetch = new JMenu();
5352 JMenu ifetch = new JMenu();
5353 JMenuItem fetchr = null;
5354 int comp = 0, icomp = 0, mcomp = 15;
5355 String mname = null;
5357 for (String dbclass : dbclasses)
5359 otherdb = sf.getSourceProxy(dbclass);
5360 // add a single entry for this class, or submenu allowing 'fetch
5362 if (otherdb == null || otherdb.size() < 1)
5368 mname = "From " + dbclass;
5370 if (otherdb.size() == 1)
5372 final DbSourceProxy[] dassource = otherdb
5373 .toArray(new DbSourceProxy[0]);
5374 DbSourceProxy src = otherdb.get(0);
5375 fetchr = new JMenuItem(src.getDbSource());
5376 fetchr.addActionListener(new ActionListener()
5380 public void actionPerformed(ActionEvent e)
5382 new Thread(new Runnable()
5388 boolean isNucleotide = alignPanel.alignFrame
5389 .getViewport().getAlignment()
5391 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5392 alignPanel.av.getSequenceSelection(),
5393 alignPanel.alignFrame, dassource,
5394 alignPanel.alignFrame.featureSettings,
5397 .addListener(new FetchFinishedListenerI()
5400 public void finished()
5402 FeatureSettingsModelI srcSettings = dassource[0]
5403 .getFeatureColourScheme();
5404 alignPanel.av.mergeFeaturesStyle(
5406 AlignFrame.this.setMenusForViewport();
5409 dbRefFetcher.fetchDBRefs(false);
5415 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5416 MessageManager.formatMessage(
5417 "label.fetch_retrieve_from", new Object[]
5418 { src.getDbName() })));
5424 final DbSourceProxy[] dassource = otherdb
5425 .toArray(new DbSourceProxy[0]);
5427 DbSourceProxy src = otherdb.get(0);
5428 fetchr = new JMenuItem(MessageManager
5429 .formatMessage("label.fetch_all_param", new Object[]
5430 { src.getDbSource() }));
5431 fetchr.addActionListener(new ActionListener()
5434 public void actionPerformed(ActionEvent e)
5436 new Thread(new Runnable()
5442 boolean isNucleotide = alignPanel.alignFrame
5443 .getViewport().getAlignment()
5445 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5446 alignPanel.av.getSequenceSelection(),
5447 alignPanel.alignFrame, dassource,
5448 alignPanel.alignFrame.featureSettings,
5451 .addListener(new FetchFinishedListenerI()
5454 public void finished()
5456 AlignFrame.this.setMenusForViewport();
5459 dbRefFetcher.fetchDBRefs(false);
5465 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5466 MessageManager.formatMessage(
5467 "label.fetch_retrieve_from_all_sources",
5469 { Integer.valueOf(otherdb.size())
5471 src.getDbSource(), src.getDbName() })));
5474 // and then build the rest of the individual menus
5475 ifetch = new JMenu(MessageManager.formatMessage(
5476 "label.source_from_db_source", new Object[]
5477 { src.getDbSource() }));
5479 String imname = null;
5481 for (DbSourceProxy sproxy : otherdb)
5483 String dbname = sproxy.getDbName();
5484 String sname = dbname.length() > 5
5485 ? dbname.substring(0, 5) + "..."
5487 String msname = dbname.length() > 10
5488 ? dbname.substring(0, 10) + "..."
5492 imname = MessageManager
5493 .formatMessage("label.from_msname", new Object[]
5496 fetchr = new JMenuItem(msname);
5497 final DbSourceProxy[] dassrc = { sproxy };
5498 fetchr.addActionListener(new ActionListener()
5502 public void actionPerformed(ActionEvent e)
5504 new Thread(new Runnable()
5510 boolean isNucleotide = alignPanel.alignFrame
5511 .getViewport().getAlignment()
5513 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5514 alignPanel.av.getSequenceSelection(),
5515 alignPanel.alignFrame, dassrc,
5516 alignPanel.alignFrame.featureSettings,
5519 .addListener(new FetchFinishedListenerI()
5522 public void finished()
5524 AlignFrame.this.setMenusForViewport();
5527 dbRefFetcher.fetchDBRefs(false);
5533 fetchr.setToolTipText(
5534 "<html>" + MessageManager.formatMessage(
5535 "label.fetch_retrieve_from", new Object[]
5539 if (++icomp >= mcomp || i == (otherdb.size()))
5541 ifetch.setText(MessageManager.formatMessage(
5542 "label.source_to_target", imname, sname));
5544 ifetch = new JMenu();
5552 if (comp >= mcomp || dbi >= (dbclasses.length))
5554 dfetch.setText(MessageManager.formatMessage(
5555 "label.source_to_target", mname, dbclass));
5557 dfetch = new JMenu();
5570 * Left justify the whole alignment.
5573 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5575 AlignmentI al = viewport.getAlignment();
5577 viewport.firePropertyChange("alignment", null, al);
5581 * Right justify the whole alignment.
5584 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5586 AlignmentI al = viewport.getAlignment();
5588 viewport.firePropertyChange("alignment", null, al);
5592 public void setShowSeqFeatures(boolean b)
5594 showSeqFeatures.setSelected(b);
5595 viewport.setShowSequenceFeatures(b);
5602 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5603 * awt.event.ActionEvent)
5606 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5608 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5609 alignPanel.paintAlignment(false, false);
5616 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5620 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5622 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5623 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5631 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5632 * .event.ActionEvent)
5635 protected void showGroupConservation_actionPerformed(ActionEvent e)
5637 viewport.setShowGroupConservation(showGroupConservation.getState());
5638 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5645 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5646 * .event.ActionEvent)
5649 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5651 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5652 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5659 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5660 * .event.ActionEvent)
5663 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5665 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5666 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5670 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5672 showSequenceLogo.setState(true);
5673 viewport.setShowSequenceLogo(true);
5674 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5675 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5679 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5681 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5688 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5689 * .event.ActionEvent)
5692 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5694 if (avc.makeGroupsFromSelection())
5696 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5697 alignPanel.updateAnnotation();
5698 alignPanel.paintAlignment(true,
5699 viewport.needToUpdateStructureViews());
5703 public void clearAlignmentSeqRep()
5705 // TODO refactor alignmentseqrep to controller
5706 if (viewport.getAlignment().hasSeqrep())
5708 viewport.getAlignment().setSeqrep(null);
5709 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5710 alignPanel.updateAnnotation();
5711 alignPanel.paintAlignment(true, true);
5716 protected void createGroup_actionPerformed(ActionEvent e)
5718 if (avc.createGroup())
5720 if (applyAutoAnnotationSettings.isSelected())
5722 alignPanel.updateAnnotation(true, false);
5724 alignPanel.alignmentChanged();
5729 protected void unGroup_actionPerformed(ActionEvent e)
5733 alignPanel.alignmentChanged();
5738 * make the given alignmentPanel the currently selected tab
5740 * @param alignmentPanel
5742 public void setDisplayedView(AlignmentPanel alignmentPanel)
5744 if (!viewport.getSequenceSetId()
5745 .equals(alignmentPanel.av.getSequenceSetId()))
5747 throw new Error(MessageManager.getString(
5748 "error.implementation_error_cannot_show_view_alignment_frame"));
5750 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5751 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5753 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5758 * Action on selection of menu options to Show or Hide annotations.
5761 * @param forSequences
5762 * update sequence-related annotations
5763 * @param forAlignment
5764 * update non-sequence-related annotations
5767 public void setAnnotationsVisibility(boolean visible,
5768 boolean forSequences, boolean forAlignment)
5770 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5771 .getAlignmentAnnotation();
5776 for (AlignmentAnnotation aa : anns)
5779 * don't display non-positional annotations on an alignment
5781 if (aa.annotations == null)
5785 boolean apply = (aa.sequenceRef == null && forAlignment)
5786 || (aa.sequenceRef != null && forSequences);
5789 aa.visible = visible;
5792 alignPanel.validateAnnotationDimensions(true);
5793 alignPanel.alignmentChanged();
5797 * Store selected annotation sort order for the view and repaint.
5800 protected void sortAnnotations_actionPerformed()
5802 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5804 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5805 alignPanel.paintAlignment(false, false);
5810 * @return alignment panels in this alignment frame
5812 public List<? extends AlignmentViewPanel> getAlignPanels()
5814 // alignPanels is never null
5815 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5820 * Open a new alignment window, with the cDNA associated with this (protein)
5821 * alignment, aligned as is the protein.
5823 protected void viewAsCdna_actionPerformed()
5825 // TODO no longer a menu action - refactor as required
5826 final AlignmentI alignment = getViewport().getAlignment();
5827 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5828 if (mappings == null)
5832 List<SequenceI> cdnaSeqs = new ArrayList<>();
5833 for (SequenceI aaSeq : alignment.getSequences())
5835 for (AlignedCodonFrame acf : mappings)
5837 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5841 * There is a cDNA mapping for this protein sequence - add to new
5842 * alignment. It will share the same dataset sequence as other mapped
5843 * cDNA (no new mappings need to be created).
5845 final Sequence newSeq = new Sequence(dnaSeq);
5846 newSeq.setDatasetSequence(dnaSeq);
5847 cdnaSeqs.add(newSeq);
5851 if (cdnaSeqs.size() == 0)
5853 // show a warning dialog no mapped cDNA
5856 AlignmentI cdna = new Alignment(
5857 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5858 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5859 AlignFrame.DEFAULT_HEIGHT);
5860 cdna.alignAs(alignment);
5861 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5863 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5864 AlignFrame.DEFAULT_HEIGHT);
5868 * Set visibility of dna/protein complement view (available when shown in a
5874 protected void showComplement_actionPerformed(boolean show)
5876 SplitContainerI sf = getSplitViewContainer();
5879 sf.setComplementVisible(this, show);
5884 * Generate the reverse (optionally complemented) of the selected sequences,
5885 * and add them to the alignment
5888 protected void showReverse_actionPerformed(boolean complement)
5890 AlignmentI al = null;
5893 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5894 al = dna.reverseCdna(complement);
5895 viewport.addAlignment(al, "");
5896 addHistoryItem(new EditCommand(
5897 MessageManager.getString("label.add_sequences"), Action.PASTE,
5898 al.getSequencesArray(), 0, al.getWidth(),
5899 viewport.getAlignment()));
5900 } catch (Exception ex)
5902 System.err.println(ex.getMessage());
5908 * Try to run a script in the Groovy console, having first ensured that this
5909 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5910 * be targeted at this alignment.
5913 protected void runGroovy_actionPerformed()
5915 Jalview.setCurrentAlignFrame(this);
5916 groovy.ui.Console console = Desktop.getGroovyConsole();
5917 if (console != null)
5921 console.runScript();
5922 } catch (Exception ex)
5924 System.err.println((ex.toString()));
5925 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5926 MessageManager.getString("label.couldnt_run_groovy_script"),
5927 MessageManager.getString("label.groovy_support_failed"),
5928 JvOptionPane.ERROR_MESSAGE);
5933 System.err.println("Can't run Groovy script as console not found");
5938 * Hides columns containing (or not containing) a specified feature, provided
5939 * that would not leave all columns hidden
5941 * @param featureType
5942 * @param columnsContaining
5945 public boolean hideFeatureColumns(String featureType,
5946 boolean columnsContaining)
5948 boolean notForHiding = avc.markColumnsContainingFeatures(
5949 columnsContaining, false, false, featureType);
5952 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5953 false, featureType))
5955 getViewport().hideSelectedColumns();
5963 protected void selectHighlightedColumns_actionPerformed(
5964 ActionEvent actionEvent)
5966 // include key modifier check in case user selects from menu
5967 avc.markHighlightedColumns(
5968 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5969 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5970 | ActionEvent.CTRL_MASK)) != 0);
5974 protected void copyHighlightedColumns_actionPerformed(
5975 ActionEvent actionEvent)
5977 avc.copyHighlightedRegionsToClipboard();
5981 * Rebuilds the Colour menu, including any user-defined colours which have
5982 * been loaded either on startup or during the session
5984 public void buildColourMenu()
5986 colourMenu.removeAll();
5988 colourMenu.add(applyToAllGroups);
5989 colourMenu.add(textColour);
5990 colourMenu.addSeparator();
5992 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5993 viewport.getAlignment(), false);
5995 colourMenu.add(annotationColour);
5996 bg.add(annotationColour);
5997 colourMenu.addSeparator();
5998 colourMenu.add(conservationMenuItem);
5999 colourMenu.add(modifyConservation);
6000 colourMenu.add(abovePIDThreshold);
6001 colourMenu.add(modifyPID);
6003 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6004 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6008 * Open a dialog (if not already open) that allows the user to select and
6009 * calculate PCA or Tree analysis
6011 protected void openTreePcaDialog()
6013 if (alignPanel.getCalculationDialog() == null)
6015 new CalculationChooser(AlignFrame.this);
6020 protected void loadVcf_actionPerformed()
6022 JalviewFileChooser chooser = new JalviewFileChooser(
6023 Cache.getProperty("LAST_DIRECTORY"));
6024 chooser.setFileView(new JalviewFileView());
6025 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6026 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6027 final AlignFrame us = this;
6028 chooser.setResponseHandler(0, () -> {
6029 String choice = chooser.getSelectedFile().getPath();
6030 Cache.setProperty("LAST_DIRECTORY", choice);
6031 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6032 new VCFLoader(choice).loadVCF(seqs, us);
6034 chooser.showOpenDialog(null);
6038 private Rectangle lastFeatureSettingsBounds = null;
6041 public void setFeatureSettingsGeometry(Rectangle bounds)
6043 lastFeatureSettingsBounds = bounds;
6047 public Rectangle getFeatureSettingsGeometry()
6049 return lastFeatureSettingsBounds;
6054 class PrintThread extends Thread
6058 public PrintThread(AlignmentPanel ap)
6063 static PageFormat pf;
6068 PrinterJob printJob = PrinterJob.getPrinterJob();
6072 printJob.setPrintable(ap, pf);
6076 printJob.setPrintable(ap);
6079 if (printJob.printDialog())
6084 } catch (Exception PrintException)
6086 PrintException.printStackTrace();