2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
63 import javax.swing.ButtonGroup;
64 import javax.swing.JCheckBoxMenuItem;
65 import javax.swing.JComponent;
66 import javax.swing.JEditorPane;
67 import javax.swing.JInternalFrame;
68 import javax.swing.JLabel;
69 import javax.swing.JLayeredPane;
70 import javax.swing.JMenu;
71 import javax.swing.JMenuItem;
72 import javax.swing.JPanel;
73 import javax.swing.JScrollPane;
74 import javax.swing.SwingUtilities;
76 import ext.vamsas.ServiceHandle;
77 import jalview.analysis.AlignmentSorter;
78 import jalview.analysis.AlignmentUtils;
79 import jalview.analysis.CrossRef;
80 import jalview.analysis.Dna;
81 import jalview.analysis.GeneticCodeI;
82 import jalview.analysis.ParseProperties;
83 import jalview.analysis.SequenceIdMatcher;
84 import jalview.api.AlignExportSettingsI;
85 import jalview.api.AlignViewControllerGuiI;
86 import jalview.api.AlignViewControllerI;
87 import jalview.api.AlignViewportI;
88 import jalview.api.AlignmentViewPanel;
89 import jalview.api.FeatureSettingsControllerI;
90 import jalview.api.FeatureSettingsModelI;
91 import jalview.api.SplitContainerI;
92 import jalview.api.ViewStyleI;
93 import jalview.api.analysis.SimilarityParamsI;
94 import jalview.bin.Cache;
95 import jalview.bin.Console;
96 import jalview.bin.Jalview;
97 import jalview.commands.CommandI;
98 import jalview.commands.EditCommand;
99 import jalview.commands.EditCommand.Action;
100 import jalview.commands.OrderCommand;
101 import jalview.commands.RemoveGapColCommand;
102 import jalview.commands.RemoveGapsCommand;
103 import jalview.commands.SlideSequencesCommand;
104 import jalview.commands.TrimRegionCommand;
105 import jalview.datamodel.AlignExportSettingsAdapter;
106 import jalview.datamodel.AlignedCodonFrame;
107 import jalview.datamodel.Alignment;
108 import jalview.datamodel.AlignmentAnnotation;
109 import jalview.datamodel.AlignmentExportData;
110 import jalview.datamodel.AlignmentI;
111 import jalview.datamodel.AlignmentOrder;
112 import jalview.datamodel.AlignmentView;
113 import jalview.datamodel.ColumnSelection;
114 import jalview.datamodel.ContactMatrixI;
115 import jalview.datamodel.HiddenColumns;
116 import jalview.datamodel.PDBEntry;
117 import jalview.datamodel.SeqCigar;
118 import jalview.datamodel.Sequence;
119 import jalview.datamodel.SequenceGroup;
120 import jalview.datamodel.SequenceI;
121 import jalview.gui.ColourMenuHelper.ColourChangeListener;
122 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
123 import jalview.io.AlignmentProperties;
124 import jalview.io.AnnotationFile;
125 import jalview.io.BackupFiles;
126 import jalview.io.BioJsHTMLOutput;
127 import jalview.io.DataSourceType;
128 import jalview.io.FileFormat;
129 import jalview.io.FileFormatI;
130 import jalview.io.FileFormats;
131 import jalview.io.FileLoader;
132 import jalview.io.FileParse;
133 import jalview.io.FormatAdapter;
134 import jalview.io.HtmlSvgOutput;
135 import jalview.io.IdentifyFile;
136 import jalview.io.JPredFile;
137 import jalview.io.JalviewFileChooser;
138 import jalview.io.JalviewFileView;
139 import jalview.io.JnetAnnotationMaker;
140 import jalview.io.NewickFile;
141 import jalview.io.ScoreMatrixFile;
142 import jalview.io.TCoffeeScoreFile;
143 import jalview.io.exceptions.ImageOutputException;
144 import jalview.io.vcf.VCFLoader;
145 import jalview.jbgui.GAlignFrame;
146 import jalview.project.Jalview2XML;
147 import jalview.schemes.ColourSchemeI;
148 import jalview.schemes.ColourSchemes;
149 import jalview.schemes.ResidueColourScheme;
150 import jalview.schemes.TCoffeeColourScheme;
151 import jalview.util.HttpUtils;
152 import jalview.util.ImageMaker.TYPE;
153 import jalview.util.MessageManager;
154 import jalview.util.Platform;
155 import jalview.util.imagemaker.BitmapImageSizing;
156 import jalview.viewmodel.AlignmentViewport;
157 import jalview.viewmodel.ViewportRanges;
158 import jalview.ws.DBRefFetcher;
159 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
160 import jalview.ws.jws1.Discoverer;
161 import jalview.ws.jws2.Jws2Discoverer;
162 import jalview.ws.jws2.jabaws2.Jws2Instance;
163 import jalview.ws.seqfetcher.DbSourceProxy;
169 * @version $Revision$
171 @SuppressWarnings("serial")
172 public class AlignFrame extends GAlignFrame implements DropTargetListener,
173 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
176 public static final int DEFAULT_WIDTH = 700;
178 public static final int DEFAULT_HEIGHT = 500;
181 * The currently displayed panel (selected tabbed view if more than one)
183 public AlignmentPanel alignPanel;
185 AlignViewport viewport;
187 public AlignViewControllerI avc;
189 List<AlignmentPanel> alignPanels = new ArrayList<>();
192 * Last format used to load or save alignments in this window
194 FileFormatI currentFileFormat = null;
197 * Current filename for this alignment
199 String fileName = null;
204 * Creates a new AlignFrame object with specific width and height.
210 public AlignFrame(AlignmentI al, int width, int height)
212 this(al, null, width, height);
216 * Creates a new AlignFrame object with specific width, height and
222 * @param sequenceSetId
224 public AlignFrame(AlignmentI al, int width, int height,
225 String sequenceSetId)
227 this(al, null, width, height, sequenceSetId);
231 * Creates a new AlignFrame object with specific width, height and
237 * @param sequenceSetId
240 public AlignFrame(AlignmentI al, int width, int height,
241 String sequenceSetId, String viewId)
243 this(al, null, width, height, sequenceSetId, viewId);
247 * new alignment window with hidden columns
251 * @param hiddenColumns
252 * ColumnSelection or null
254 * Width of alignment frame
258 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
261 this(al, hiddenColumns, width, height, null);
265 * Create alignment frame for al with hiddenColumns, a specific width and
266 * height, and specific sequenceId
269 * @param hiddenColumns
272 * @param sequenceSetId
275 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
276 int height, String sequenceSetId)
278 this(al, hiddenColumns, width, height, sequenceSetId, null);
282 * Create alignment frame for al with hiddenColumns, a specific width and
283 * height, and specific sequenceId
286 * @param hiddenColumns
289 * @param sequenceSetId
294 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
295 int height, String sequenceSetId, String viewId)
297 setSize(width, height);
299 if (al.getDataset() == null)
304 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
306 alignPanel = new AlignmentPanel(this, viewport);
308 addAlignmentPanel(alignPanel, true);
312 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
313 HiddenColumns hiddenColumns, int width, int height)
315 setSize(width, height);
317 if (al.getDataset() == null)
322 viewport = new AlignViewport(al, hiddenColumns);
324 if (hiddenSeqs != null && hiddenSeqs.length > 0)
326 viewport.hideSequence(hiddenSeqs);
328 alignPanel = new AlignmentPanel(this, viewport);
329 addAlignmentPanel(alignPanel, true);
334 * Make a new AlignFrame from existing alignmentPanels
341 public AlignFrame(AlignmentPanel ap)
345 addAlignmentPanel(ap, false);
350 * initalise the alignframe from the underlying viewport data and the
357 // setBackground(Color.white); // BH 2019
359 if (!Jalview.isHeadlessMode())
361 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
364 avc = new jalview.controller.AlignViewController(this, viewport,
366 if (viewport.getAlignmentConservationAnnotation() == null)
368 // BLOSUM62Colour.setEnabled(false);
369 conservationMenuItem.setEnabled(false);
370 modifyConservation.setEnabled(false);
371 // PIDColour.setEnabled(false);
372 // abovePIDThreshold.setEnabled(false);
373 // modifyPID.setEnabled(false);
376 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
378 if (sortby.equals("Id"))
380 sortIDMenuItem_actionPerformed(null);
382 else if (sortby.equals("Pairwise Identity"))
384 sortPairwiseMenuItem_actionPerformed(null);
388 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
390 setMenusFromViewport(viewport);
391 buildSortByAnnotationScoresMenu();
392 calculateTree.addActionListener(new ActionListener()
396 public void actionPerformed(ActionEvent e)
403 if (Desktop.desktop != null)
405 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
406 if (!Platform.isJS())
408 addServiceListeners();
413 if (viewport.getWrapAlignment())
415 wrapMenuItem_actionPerformed(null);
418 if (Cache.getDefault("SHOW_OVERVIEW", false))
420 this.overviewMenuItem_actionPerformed(null);
425 final List<AlignmentViewPanel> selviews = new ArrayList<>();
426 final List<AlignmentPanel> origview = new ArrayList<>();
427 final String menuLabel = MessageManager
428 .getString("label.copy_format_from");
429 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
430 new ViewSetProvider()
434 public AlignmentPanel[] getAllAlignmentPanels()
437 origview.add(alignPanel);
438 // make an array of all alignment panels except for this one
439 List<AlignmentPanel> aps = new ArrayList<>(
440 Arrays.asList(Desktop.getAlignmentPanels(null)));
441 aps.remove(AlignFrame.this.alignPanel);
442 return aps.toArray(new AlignmentPanel[aps.size()]);
444 }, selviews, new ItemListener()
448 public void itemStateChanged(ItemEvent e)
450 if (origview.size() > 0)
452 final AlignmentPanel ap = origview.get(0);
455 * Copy the ViewStyle of the selected panel to 'this one'.
456 * Don't change value of 'scaleProteinAsCdna' unless copying
459 ViewStyleI vs = selviews.get(0).getAlignViewport()
461 boolean fromSplitFrame = selviews.get(0)
462 .getAlignViewport().getCodingComplement() != null;
465 vs.setScaleProteinAsCdna(ap.getAlignViewport()
466 .getViewStyle().isScaleProteinAsCdna());
468 ap.getAlignViewport().setViewStyle(vs);
471 * Also rescale ViewStyle of SplitFrame complement if there is
472 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
473 * the whole ViewStyle (allow cDNA protein to have different
476 AlignViewportI complement = ap.getAlignViewport()
477 .getCodingComplement();
478 if (complement != null && vs.isScaleProteinAsCdna())
480 AlignFrame af = Desktop.getAlignFrameFor(complement);
481 ((SplitFrame) af.getSplitViewContainer())
483 af.setMenusForViewport();
487 ap.setSelected(true);
488 ap.alignFrame.setMenusForViewport();
493 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
494 .indexOf("devel") > -1
495 || Cache.getDefault("VERSION", "DEVELOPMENT")
496 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
498 formatMenu.add(vsel);
500 addFocusListener(new FocusAdapter()
503 public void focusGained(FocusEvent e)
505 Jalview.setCurrentAlignFrame(AlignFrame.this);
512 * Change the filename and format for the alignment, and enable the 'reload'
513 * button functionality.
520 public void setFileName(String file, FileFormatI format)
523 setFileFormat(format);
524 reload.setEnabled(true);
528 * JavaScript will have this, maybe others. More dependable than a file name
529 * and maintains a reference to the actual bytes loaded.
533 public void setFileObject(File file)
535 this.fileObject = file;
539 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
542 void addKeyListener()
544 addKeyListener(new KeyAdapter()
547 public void keyPressed(KeyEvent evt)
549 if (viewport.cursorMode
550 && ((evt.getKeyCode() >= KeyEvent.VK_0
551 && evt.getKeyCode() <= KeyEvent.VK_9)
552 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
553 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
554 && Character.isDigit(evt.getKeyChar()))
556 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
559 switch (evt.getKeyCode())
562 case 27: // escape key
563 deselectAllSequenceMenuItem_actionPerformed(null);
567 case KeyEvent.VK_DOWN:
568 if (evt.isAltDown() || !viewport.cursorMode)
570 moveSelectedSequences(false);
572 if (viewport.cursorMode)
574 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
579 if (evt.isAltDown() || !viewport.cursorMode)
581 moveSelectedSequences(true);
583 if (viewport.cursorMode)
585 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
590 case KeyEvent.VK_LEFT:
591 if (evt.isAltDown() || !viewport.cursorMode)
593 slideSequences(false,
594 alignPanel.getSeqPanel().getKeyboardNo1());
598 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
603 case KeyEvent.VK_RIGHT:
604 if (evt.isAltDown() || !viewport.cursorMode)
606 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
610 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
614 case KeyEvent.VK_SPACE:
615 if (viewport.cursorMode)
617 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
618 || evt.isShiftDown() || evt.isAltDown());
622 // case KeyEvent.VK_A:
623 // if (viewport.cursorMode)
625 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
626 // //System.out.println("A");
630 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
631 * System.out.println("closing bracket"); } break;
633 case KeyEvent.VK_DELETE:
634 case KeyEvent.VK_BACK_SPACE:
635 if (!viewport.cursorMode)
637 cut_actionPerformed();
641 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
642 || evt.isShiftDown() || evt.isAltDown());
648 if (viewport.cursorMode)
650 alignPanel.getSeqPanel().setCursorRow();
654 if (viewport.cursorMode && !evt.isControlDown())
656 alignPanel.getSeqPanel().setCursorColumn();
660 if (viewport.cursorMode)
662 alignPanel.getSeqPanel().setCursorPosition();
666 case KeyEvent.VK_ENTER:
667 case KeyEvent.VK_COMMA:
668 if (viewport.cursorMode)
670 alignPanel.getSeqPanel().setCursorRowAndColumn();
675 if (viewport.cursorMode)
677 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
681 if (viewport.cursorMode)
683 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
688 viewport.cursorMode = !viewport.cursorMode;
689 setStatus(MessageManager
690 .formatMessage("label.keyboard_editing_mode", new String[]
691 { (viewport.cursorMode ? "on" : "off") }));
692 if (viewport.cursorMode)
694 ViewportRanges ranges = viewport.getRanges();
695 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
697 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
700 alignPanel.getSeqPanel().seqCanvas.repaint();
706 Help.showHelpWindow();
707 } catch (Exception ex)
709 ex.printStackTrace();
714 boolean toggleSeqs = !evt.isControlDown();
715 boolean toggleCols = !evt.isShiftDown();
716 toggleHiddenRegions(toggleSeqs, toggleCols);
721 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
722 boolean modifyExisting = true; // always modify, don't clear
723 // evt.isShiftDown();
724 boolean invertHighlighted = evt.isAltDown();
725 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
729 case KeyEvent.VK_PAGE_UP:
730 viewport.getRanges().pageUp();
732 case KeyEvent.VK_PAGE_DOWN:
733 viewport.getRanges().pageDown();
739 public void keyReleased(KeyEvent evt)
741 switch (evt.getKeyCode())
743 case KeyEvent.VK_LEFT:
744 if (evt.isAltDown() || !viewport.cursorMode)
746 viewport.firePropertyChange("alignment", null,
747 viewport.getAlignment().getSequences());
751 case KeyEvent.VK_RIGHT:
752 if (evt.isAltDown() || !viewport.cursorMode)
754 viewport.firePropertyChange("alignment", null,
755 viewport.getAlignment().getSequences());
763 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
765 ap.alignFrame = this;
766 avc = new jalview.controller.AlignViewController(this, viewport,
771 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
773 int aSize = alignPanels.size();
775 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
777 if (aSize == 1 && ap.av.getViewName() == null)
779 this.getContentPane().add(ap, BorderLayout.CENTER);
785 setInitialTabVisible();
788 expandViews.setEnabled(true);
789 gatherViews.setEnabled(true);
790 tabbedPane.addTab(ap.av.getViewName(), ap);
792 ap.setVisible(false);
797 if (ap.av.isPadGaps())
799 ap.av.getAlignment().padGaps();
801 ap.av.updateConservation(ap);
802 ap.av.updateConsensus(ap);
803 ap.av.updateStrucConsensus(ap);
807 public void setInitialTabVisible()
809 expandViews.setEnabled(true);
810 gatherViews.setEnabled(true);
811 tabbedPane.setVisible(true);
812 AlignmentPanel first = alignPanels.get(0);
813 tabbedPane.addTab(first.av.getViewName(), first);
814 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
817 public AlignViewport getViewport()
822 /* Set up intrinsic listeners for dynamically generated GUI bits. */
823 private void addServiceListeners()
825 final java.beans.PropertyChangeListener thisListener;
826 Desktop.instance.addJalviewPropertyChangeListener("services",
827 thisListener = new java.beans.PropertyChangeListener()
830 public void propertyChange(PropertyChangeEvent evt)
832 // // System.out.println("Discoverer property change.");
833 // if (evt.getPropertyName().equals("services"))
835 SwingUtilities.invokeLater(new Runnable()
842 "Rebuild WS Menu for service change");
843 BuildWebServiceMenu();
850 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
853 public void internalFrameClosed(
854 javax.swing.event.InternalFrameEvent evt)
856 // System.out.println("deregistering discoverer listener");
857 Desktop.instance.removeJalviewPropertyChangeListener("services",
859 closeMenuItem_actionPerformed(true);
862 // Finally, build the menu once to get current service state
863 new Thread(new Runnable()
868 BuildWebServiceMenu();
874 * Configure menu items that vary according to whether the alignment is
875 * nucleotide or protein
877 public void setGUINucleotide()
879 AlignmentI al = getViewport().getAlignment();
880 boolean nucleotide = al.isNucleotide();
882 loadVcf.setVisible(nucleotide);
883 showTranslation.setVisible(nucleotide);
884 showReverse.setVisible(nucleotide);
885 showReverseComplement.setVisible(nucleotide);
886 conservationMenuItem.setEnabled(!nucleotide);
888 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
889 showGroupConservation.setEnabled(!nucleotide);
891 showComplementMenuItem
892 .setText(nucleotide ? MessageManager.getString("label.protein")
893 : MessageManager.getString("label.nucleotide"));
897 * set up menus for the current viewport. This may be called after any
898 * operation that affects the data in the current view (selection changed,
899 * etc) to update the menus to reflect the new state.
902 public void setMenusForViewport()
904 setMenusFromViewport(viewport);
908 * Need to call this method when tabs are selected for multiple views, or when
909 * loading from Jalview2XML.java
914 public void setMenusFromViewport(AlignViewport av)
916 padGapsMenuitem.setSelected(av.isPadGaps());
917 colourTextMenuItem.setSelected(av.isShowColourText());
918 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
919 modifyPID.setEnabled(abovePIDThreshold.isSelected());
920 conservationMenuItem.setSelected(av.getConservationSelected());
921 modifyConservation.setEnabled(conservationMenuItem.isSelected());
922 seqLimits.setSelected(av.getShowJVSuffix());
923 idRightAlign.setSelected(av.isRightAlignIds());
924 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
925 renderGapsMenuItem.setSelected(av.isRenderGaps());
926 wrapMenuItem.setSelected(av.getWrapAlignment());
927 scaleAbove.setVisible(av.getWrapAlignment());
928 scaleLeft.setVisible(av.getWrapAlignment());
929 scaleRight.setVisible(av.getWrapAlignment());
930 annotationPanelMenuItem.setState(av.isShowAnnotation());
932 * Show/hide annotations only enabled if annotation panel is shown
934 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
935 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
936 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 viewBoxesMenuItem.setSelected(av.getShowBoxes());
939 viewTextMenuItem.setSelected(av.getShowText());
940 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
941 showGroupConsensus.setSelected(av.isShowGroupConsensus());
942 showGroupConservation.setSelected(av.isShowGroupConservation());
943 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
944 showSequenceLogo.setSelected(av.isShowSequenceLogo());
945 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
947 ColourMenuHelper.setColourSelected(colourMenu,
948 av.getGlobalColourScheme());
950 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
951 hiddenMarkers.setState(av.getShowHiddenMarkers());
952 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
953 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
954 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
955 autoCalculate.setSelected(av.autoCalculateConsensus);
956 sortByTree.setSelected(av.sortByTree);
957 listenToViewSelections.setSelected(av.followSelection);
959 showProducts.setEnabled(canShowProducts());
960 setGroovyEnabled(Desktop.getGroovyConsole() != null);
966 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
970 public void setGroovyEnabled(boolean b)
972 runGroovy.setEnabled(b);
975 private IProgressIndicator progressBar;
980 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
983 public void setProgressBar(String message, long id)
985 if (!Platform.isHeadless() && progressBar != null)
986 progressBar.setProgressBar(message, id);
990 public void registerHandler(final long id,
991 final IProgressIndicatorHandler handler)
993 if (progressBar != null)
994 progressBar.registerHandler(id, handler);
999 * @return true if any progress bars are still active
1002 public boolean operationInProgress()
1004 return progressBar == null ? false : progressBar.operationInProgress();
1008 * Sets the text of the status bar. Note that setting a null or empty value
1009 * will cause the status bar to be hidden, with possibly undesirable flicker
1010 * of the screen layout.
1013 public void setStatus(String text)
1015 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1019 * Added so Castor Mapping file can obtain Jalview Version
1021 public String getVersion()
1023 return Cache.getProperty("VERSION");
1026 public FeatureRenderer getFeatureRenderer()
1028 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1032 public void fetchSequence_actionPerformed()
1034 new SequenceFetcher(this);
1038 public void addFromFile_actionPerformed(ActionEvent e)
1040 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1044 public void reload_actionPerformed(ActionEvent e)
1046 if (fileName != null)
1048 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1049 // originating file's format
1050 // TODO: work out how to recover feature settings for correct view(s) when
1051 // file is reloaded.
1052 if (FileFormat.Jalview.equals(currentFileFormat))
1054 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1055 for (int i = 0; i < frames.length; i++)
1057 if (frames[i] instanceof AlignFrame && frames[i] != this
1058 && ((AlignFrame) frames[i]).fileName != null
1059 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1063 frames[i].setSelected(true);
1064 Desktop.instance.closeAssociatedWindows();
1065 } catch (java.beans.PropertyVetoException ex)
1071 Desktop.instance.closeAssociatedWindows();
1073 FileLoader loader = new FileLoader();
1074 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1075 ? DataSourceType.URL
1076 : DataSourceType.FILE;
1077 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1081 Rectangle bounds = this.getBounds();
1083 FileLoader loader = new FileLoader();
1085 AlignFrame newframe = null;
1087 if (fileObject == null)
1090 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1091 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1092 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1097 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1098 DataSourceType.FILE, currentFileFormat);
1101 newframe.setBounds(bounds);
1102 if (featureSettings != null && featureSettings.isShowing())
1104 final Rectangle fspos = featureSettings.frame.getBounds();
1105 // TODO: need a 'show feature settings' function that takes bounds -
1106 // need to refactor Desktop.addFrame
1107 newframe.featureSettings_actionPerformed(null);
1108 final FeatureSettings nfs = newframe.featureSettings;
1109 SwingUtilities.invokeLater(new Runnable()
1114 nfs.frame.setBounds(fspos);
1117 this.featureSettings.close();
1118 this.featureSettings = null;
1120 this.closeMenuItem_actionPerformed(true);
1126 public void addFromText_actionPerformed(ActionEvent e)
1129 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1133 public void addFromURL_actionPerformed(ActionEvent e)
1135 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1139 public void save_actionPerformed(ActionEvent e)
1141 if (fileName == null || (currentFileFormat == null)
1142 || HttpUtils.startsWithHttpOrHttps(fileName))
1144 saveAs_actionPerformed();
1148 saveAlignment(fileName, currentFileFormat);
1153 * Saves the alignment to a file with a name chosen by the user, if necessary
1154 * warning if a file would be overwritten
1157 public void saveAs_actionPerformed()
1159 String format = currentFileFormat == null ? null
1160 : currentFileFormat.getName();
1161 JalviewFileChooser chooser = JalviewFileChooser
1162 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1164 chooser.setFileView(new JalviewFileView());
1165 chooser.setDialogTitle(
1166 MessageManager.getString("label.save_alignment_to_file"));
1167 chooser.setToolTipText(MessageManager.getString("action.save"));
1169 int value = chooser.showSaveDialog(this);
1171 if (value != JalviewFileChooser.APPROVE_OPTION)
1175 currentFileFormat = chooser.getSelectedFormat();
1176 // todo is this (2005) test now obsolete - value is never null?
1177 while (currentFileFormat == null)
1179 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1181 .getString("label.select_file_format_before_saving"),
1182 MessageManager.getString("label.file_format_not_specified"),
1183 JvOptionPane.WARNING_MESSAGE);
1184 currentFileFormat = chooser.getSelectedFormat();
1185 value = chooser.showSaveDialog(this);
1186 if (value != JalviewFileChooser.APPROVE_OPTION)
1192 fileName = chooser.getSelectedFile().getPath();
1194 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1195 Cache.setProperty("LAST_DIRECTORY", fileName);
1196 saveAlignment(fileName, currentFileFormat);
1199 boolean lastSaveSuccessful = false;
1201 FileFormatI lastFormatSaved;
1203 String lastFilenameSaved;
1206 * Raise a dialog or status message for the last call to saveAlignment.
1208 * @return true if last call to saveAlignment(file, format) was successful.
1210 public boolean isSaveAlignmentSuccessful()
1213 if (!lastSaveSuccessful)
1215 if (!Platform.isHeadless())
1217 JvOptionPane.showInternalMessageDialog(this, MessageManager
1218 .formatMessage("label.couldnt_save_file", new Object[]
1219 { lastFilenameSaved }),
1220 MessageManager.getString("label.error_saving_file"),
1221 JvOptionPane.WARNING_MESSAGE);
1225 Console.error(MessageManager
1226 .formatMessage("label.couldnt_save_file", new Object[]
1227 { lastFilenameSaved }));
1233 setStatus(MessageManager.formatMessage(
1234 "label.successfully_saved_to_file_in_format", new Object[]
1235 { lastFilenameSaved, lastFormatSaved }));
1238 return lastSaveSuccessful;
1242 * Saves the alignment to the specified file path, in the specified format,
1243 * which may be an alignment format, or Jalview project format. If the
1244 * alignment has hidden regions, or the format is one capable of including
1245 * non-sequence data (features, annotations, groups), then the user may be
1246 * prompted to specify what to include in the output.
1251 public void saveAlignment(String file, FileFormatI format)
1253 lastSaveSuccessful = true;
1254 lastFilenameSaved = file;
1255 lastFormatSaved = format;
1257 if (FileFormat.Jalview.equals(format))
1259 String shortName = title;
1260 if (shortName.indexOf(File.separatorChar) > -1)
1262 shortName = shortName
1263 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1265 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1268 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1269 if (lastSaveSuccessful)
1271 this.getViewport().setSavedUpToDate(true);
1274 statusBar.setText(MessageManager.formatMessage(
1275 "label.successfully_saved_to_file_in_format", new Object[]
1281 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1282 Runnable cancelAction = () -> {
1283 lastSaveSuccessful = false;
1285 Runnable outputAction = () -> {
1286 // todo defer this to inside formatSequences (or later)
1287 AlignmentExportData exportData = viewport.getAlignExportData(options);
1288 String output = new FormatAdapter(alignPanel, options)
1289 .formatSequences(format, exportData.getAlignment(),
1290 exportData.getOmitHidden(),
1291 exportData.getStartEndPostions(),
1292 viewport.getAlignment().getHiddenColumns());
1295 lastSaveSuccessful = false;
1299 // create backupfiles object and get new temp filename destination
1300 boolean doBackup = BackupFiles.getEnabled();
1301 BackupFiles backupfiles = null;
1304 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1305 backupfiles = new BackupFiles(file);
1309 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1311 Console.trace("ALIGNFRAME setting PrintWriter");
1312 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1314 if (backupfiles != null)
1316 Console.trace("ALIGNFRAME about to write to temp file "
1317 + backupfiles.getTempFilePath());
1321 Console.trace("ALIGNFRAME about to close file");
1323 Console.trace("ALIGNFRAME closed file");
1324 AlignFrame.this.setTitle(file);
1325 statusBar.setText(MessageManager.formatMessage(
1326 "label.successfully_saved_to_file_in_format", new Object[]
1327 { fileName, format.getName() }));
1328 lastSaveSuccessful = true;
1329 } catch (IOException e)
1331 lastSaveSuccessful = false;
1333 "ALIGNFRAME Something happened writing the temp file");
1334 Console.error(e.getMessage());
1335 Console.debug(Cache.getStackTraceString(e));
1336 } catch (Exception ex)
1338 lastSaveSuccessful = false;
1340 "ALIGNFRAME Something unexpected happened writing the temp file");
1341 Console.error(ex.getMessage());
1342 Console.debug(Cache.getStackTraceString(ex));
1347 backupfiles.setWriteSuccess(lastSaveSuccessful);
1348 Console.debug("ALIGNFRAME writing temp file was "
1349 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1350 // do the backup file roll and rename the temp file to actual file
1351 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1352 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1353 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1354 + (lastSaveSuccessful ? "" : "un") + "successfully");
1357 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1358 if (lastSaveSuccessful)
1360 AlignFrame.this.getViewport().setSavedUpToDate(true);
1366 * show dialog with export options if applicable; else just do it
1368 if (AlignExportOptions.isNeeded(viewport, format))
1370 AlignExportOptions choices = new AlignExportOptions(
1371 alignPanel.getAlignViewport(), format, options);
1372 choices.setResponseAction(0, outputAction);
1373 choices.setResponseAction(1, cancelAction);
1374 choices.showDialog();
1381 } catch (Exception e)
1383 // TODO Auto-generated catch block
1384 e.printStackTrace();
1390 * Outputs the alignment to textbox in the requested format, if necessary
1391 * first prompting the user for whether to include hidden regions or
1394 * @param fileFormatName
1397 protected void outputText_actionPerformed(String fileFormatName)
1399 FileFormatI fileFormat = FileFormats.getInstance()
1400 .forName(fileFormatName);
1401 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1402 Runnable outputAction = () -> {
1403 // todo defer this to inside formatSequences (or later)
1404 AlignmentExportData exportData = viewport.getAlignExportData(options);
1405 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1406 cap.setForInput(null);
1409 FileFormatI format = fileFormat;
1410 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1411 format, exportData.getAlignment(),
1412 exportData.getOmitHidden(),
1413 exportData.getStartEndPostions(),
1414 viewport.getAlignment().getHiddenColumns()));
1415 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1416 "label.alignment_output_command", new Object[]
1417 { fileFormat.getName() }), 600, 500);
1418 } catch (OutOfMemoryError oom)
1420 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1427 * show dialog with export options if applicable; else just do it
1429 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1431 AlignExportOptions choices = new AlignExportOptions(
1432 alignPanel.getAlignViewport(), fileFormat, options);
1433 choices.setResponseAction(0, outputAction);
1434 choices.showDialog();
1441 } catch (Exception e)
1443 e.printStackTrace();
1455 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1457 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1460 htmlSVG.exportHTML(null);
1461 } catch (ImageOutputException x)
1463 // report problem to console and raise dialog
1468 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1470 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1473 bjs.exportHTML(null);
1474 } catch (ImageOutputException x)
1476 // report problem to console and raise dialog
1480 public void createImageMap(File file, String image)
1484 alignPanel.makePNGImageMap(file, image);
1485 } catch (ImageOutputException x)
1487 // report problem to console and raise dialog
1492 public void createPNG_actionPerformed(ActionEvent e)
1497 } catch (ImageOutputException ioex)
1499 // raise dialog, and report via console
1504 public void createEPS_actionPerformed(ActionEvent e)
1509 } catch (ImageOutputException ioex)
1511 // raise dialog, and report via console
1517 public void createSVG_actionPerformed(ActionEvent e)
1522 } catch (ImageOutputException ioex)
1524 // raise dialog, and report via console
1530 * Creates a PNG image of the alignment and writes it to the given file. If
1531 * the file is null, the user is prompted to choose a file.
1535 public void createPNG(File f) throws ImageOutputException
1537 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1540 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1541 throws ImageOutputException
1543 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1547 * Creates an EPS image of the alignment and writes it to the given file. If
1548 * the file is null, the user is prompted to choose a file.
1552 public void createEPS(File f) throws ImageOutputException
1557 public void createEPS(File f, String renderer) throws ImageOutputException
1559 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1563 * Creates an SVG image of the alignment and writes it to the given file. If
1564 * the file is null, the user is prompted to choose a file.
1568 public void createSVG(File f) throws ImageOutputException
1573 public void createSVG(File f, String renderer) throws ImageOutputException
1575 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1579 public void pageSetup_actionPerformed(ActionEvent e)
1581 PrinterJob printJob = PrinterJob.getPrinterJob();
1582 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1592 public void printMenuItem_actionPerformed(ActionEvent e)
1594 // Putting in a thread avoids Swing painting problems
1595 PrintThread thread = new PrintThread(alignPanel);
1600 public void exportFeatures_actionPerformed(ActionEvent e)
1602 new AnnotationExporter(alignPanel).exportFeatures();
1606 public void exportAnnotations_actionPerformed(ActionEvent e)
1608 new AnnotationExporter(alignPanel).exportAnnotations();
1612 public void associatedData_actionPerformed(ActionEvent e)
1614 final JalviewFileChooser chooser = new JalviewFileChooser(
1615 Cache.getProperty("LAST_DIRECTORY"));
1616 chooser.setFileView(new JalviewFileView());
1617 String tooltip = MessageManager
1618 .getString("label.load_jalview_annotations");
1619 chooser.setDialogTitle(tooltip);
1620 chooser.setToolTipText(tooltip);
1621 chooser.setResponseHandler(0, () -> {
1622 String choice = chooser.getSelectedFile().getPath();
1623 Cache.setProperty("LAST_DIRECTORY", choice);
1624 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1627 chooser.showOpenDialog(this);
1631 * Close the current view or all views in the alignment frame. If the frame
1632 * only contains one view then the alignment will be removed from memory.
1634 * @param closeAllTabs
1637 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1639 if (alignPanels != null && alignPanels.size() < 2)
1641 closeAllTabs = true;
1646 if (alignPanels != null)
1650 if (this.isClosed())
1652 // really close all the windows - otherwise wait till
1653 // setClosed(true) is called
1654 for (int i = 0; i < alignPanels.size(); i++)
1656 AlignmentPanel ap = alignPanels.get(i);
1663 closeView(alignPanel);
1668 if (featureSettings != null && featureSettings.isOpen())
1670 featureSettings.close();
1671 featureSettings = null;
1674 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1675 * be called recursively, with the frame now in 'closed' state
1677 this.setClosed(true);
1679 } catch (Exception ex)
1681 ex.printStackTrace();
1686 * Close the specified panel and close up tabs appropriately.
1688 * @param panelToClose
1690 public void closeView(AlignmentPanel panelToClose)
1692 int index = tabbedPane.getSelectedIndex();
1693 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1694 alignPanels.remove(panelToClose);
1695 panelToClose.closePanel();
1696 panelToClose = null;
1698 tabbedPane.removeTabAt(closedindex);
1699 tabbedPane.validate();
1701 if (index > closedindex || index == tabbedPane.getTabCount())
1703 // modify currently selected tab index if necessary.
1707 this.tabSelectionChanged(index);
1713 void updateEditMenuBar()
1716 if (viewport.getHistoryList().size() > 0)
1718 undoMenuItem.setEnabled(true);
1719 CommandI command = viewport.getHistoryList().peek();
1720 undoMenuItem.setText(MessageManager
1721 .formatMessage("label.undo_command", new Object[]
1722 { command.getDescription() }));
1726 undoMenuItem.setEnabled(false);
1727 undoMenuItem.setText(MessageManager.getString("action.undo"));
1730 if (viewport.getRedoList().size() > 0)
1732 redoMenuItem.setEnabled(true);
1734 CommandI command = viewport.getRedoList().peek();
1735 redoMenuItem.setText(MessageManager
1736 .formatMessage("label.redo_command", new Object[]
1737 { command.getDescription() }));
1741 redoMenuItem.setEnabled(false);
1742 redoMenuItem.setText(MessageManager.getString("action.redo"));
1747 public void addHistoryItem(CommandI command)
1749 if (command.getSize() > 0)
1751 viewport.addToHistoryList(command);
1752 viewport.clearRedoList();
1753 updateEditMenuBar();
1754 viewport.updateHiddenColumns();
1755 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1756 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1757 // viewport.getColumnSelection()
1758 // .getHiddenColumns().size() > 0);
1764 * @return alignment objects for all views
1766 AlignmentI[] getViewAlignments()
1768 if (alignPanels != null)
1770 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1772 for (AlignmentPanel ap : alignPanels)
1774 als[i++] = ap.av.getAlignment();
1778 if (viewport != null)
1780 return new AlignmentI[] { viewport.getAlignment() };
1792 protected void undoMenuItem_actionPerformed(ActionEvent e)
1794 if (viewport.getHistoryList().isEmpty())
1798 CommandI command = viewport.getHistoryList().pop();
1799 viewport.addToRedoList(command);
1800 command.undoCommand(getViewAlignments());
1802 AlignmentViewport originalSource = getOriginatingSource(command);
1803 updateEditMenuBar();
1805 if (originalSource != null)
1807 if (originalSource != viewport)
1810 "Implementation worry: mismatch of viewport origin for undo");
1812 originalSource.updateHiddenColumns();
1813 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1815 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1816 // viewport.getColumnSelection()
1817 // .getHiddenColumns().size() > 0);
1818 originalSource.firePropertyChange("alignment", null,
1819 originalSource.getAlignment().getSequences());
1830 protected void redoMenuItem_actionPerformed(ActionEvent e)
1832 if (viewport.getRedoList().size() < 1)
1837 CommandI command = viewport.getRedoList().pop();
1838 viewport.addToHistoryList(command);
1839 command.doCommand(getViewAlignments());
1841 AlignmentViewport originalSource = getOriginatingSource(command);
1842 updateEditMenuBar();
1844 if (originalSource != null)
1847 if (originalSource != viewport)
1850 "Implementation worry: mismatch of viewport origin for redo");
1852 originalSource.updateHiddenColumns();
1853 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1855 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1856 // viewport.getColumnSelection()
1857 // .getHiddenColumns().size() > 0);
1858 originalSource.firePropertyChange("alignment", null,
1859 originalSource.getAlignment().getSequences());
1863 AlignmentViewport getOriginatingSource(CommandI command)
1865 AlignmentViewport originalSource = null;
1866 // For sequence removal and addition, we need to fire
1867 // the property change event FROM the viewport where the
1868 // original alignment was altered
1869 AlignmentI al = null;
1870 if (command instanceof EditCommand)
1872 EditCommand editCommand = (EditCommand) command;
1873 al = editCommand.getAlignment();
1874 List<Component> comps = PaintRefresher.components
1875 .get(viewport.getSequenceSetId());
1877 for (Component comp : comps)
1879 if (comp instanceof AlignmentPanel)
1881 if (al == ((AlignmentPanel) comp).av.getAlignment())
1883 originalSource = ((AlignmentPanel) comp).av;
1890 if (originalSource == null)
1892 // The original view is closed, we must validate
1893 // the current view against the closed view first
1896 PaintRefresher.validateSequences(al, viewport.getAlignment());
1899 originalSource = viewport;
1902 return originalSource;
1906 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1907 * or the sequence under cursor in keyboard mode
1912 public void moveSelectedSequences(boolean up)
1914 SequenceGroup sg = viewport.getSelectionGroup();
1918 if (viewport.cursorMode)
1920 sg = new SequenceGroup();
1921 sg.addSequence(viewport.getAlignment().getSequenceAt(
1922 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1930 if (sg.getSize() < 1)
1935 // TODO: JAL-3733 - add an event to the undo buffer for this !
1937 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1938 viewport.getHiddenRepSequences(), up);
1939 alignPanel.paintAlignment(true, false);
1942 synchronized void slideSequences(boolean right, int size)
1944 List<SequenceI> sg = new ArrayList<>();
1945 if (viewport.cursorMode)
1947 sg.add(viewport.getAlignment()
1948 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1950 else if (viewport.getSelectionGroup() != null
1951 && viewport.getSelectionGroup().getSize() != viewport
1952 .getAlignment().getHeight())
1954 sg = viewport.getSelectionGroup()
1955 .getSequences(viewport.getHiddenRepSequences());
1963 List<SequenceI> invertGroup = new ArrayList<>();
1965 for (SequenceI seq : viewport.getAlignment().getSequences())
1967 if (!sg.contains(seq))
1969 invertGroup.add(seq);
1973 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1975 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1976 for (int i = 0; i < invertGroup.size(); i++)
1978 seqs2[i] = invertGroup.get(i);
1981 SlideSequencesCommand ssc;
1984 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1985 viewport.getGapCharacter());
1989 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1990 viewport.getGapCharacter());
1993 int groupAdjustment = 0;
1994 if (ssc.getGapsInsertedBegin() && right)
1996 if (viewport.cursorMode)
1998 alignPanel.getSeqPanel().moveCursor(size, 0);
2002 groupAdjustment = size;
2005 else if (!ssc.getGapsInsertedBegin() && !right)
2007 if (viewport.cursorMode)
2009 alignPanel.getSeqPanel().moveCursor(-size, 0);
2013 groupAdjustment = -size;
2017 if (groupAdjustment != 0)
2019 viewport.getSelectionGroup().setStartRes(
2020 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2021 viewport.getSelectionGroup().setEndRes(
2022 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2026 * just extend the last slide command if compatible; but not if in
2027 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2029 boolean appendHistoryItem = false;
2030 Deque<CommandI> historyList = viewport.getHistoryList();
2031 boolean inSplitFrame = getSplitViewContainer() != null;
2032 if (!inSplitFrame && historyList != null && historyList.size() > 0
2033 && historyList.peek() instanceof SlideSequencesCommand)
2035 appendHistoryItem = ssc.appendSlideCommand(
2036 (SlideSequencesCommand) historyList.peek());
2039 if (!appendHistoryItem)
2041 addHistoryItem(ssc);
2054 protected void copy_actionPerformed()
2056 if (viewport.getSelectionGroup() == null)
2060 // TODO: preserve the ordering of displayed alignment annotation in any
2061 // internal paste (particularly sequence associated annotation)
2062 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2063 String[] omitHidden = null;
2065 if (viewport.hasHiddenColumns())
2067 omitHidden = viewport.getViewAsString(true);
2070 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2071 seqs, omitHidden, null);
2073 StringSelection ss = new StringSelection(output);
2077 jalview.gui.Desktop.internalCopy = true;
2078 // Its really worth setting the clipboard contents
2079 // to empty before setting the large StringSelection!!
2080 Toolkit.getDefaultToolkit().getSystemClipboard()
2081 .setContents(new StringSelection(""), null);
2083 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2085 } catch (OutOfMemoryError er)
2087 new OOMWarning("copying region", er);
2091 HiddenColumns hiddenColumns = null;
2092 if (viewport.hasHiddenColumns())
2094 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2095 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2097 // create new HiddenColumns object with copy of hidden regions
2098 // between startRes and endRes, offset by startRes
2099 hiddenColumns = new HiddenColumns(
2100 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2101 hiddenCutoff, hiddenOffset);
2104 Desktop.jalviewClipboard = new Object[] { seqs,
2105 viewport.getAlignment().getDataset(), hiddenColumns };
2106 setStatus(MessageManager.formatMessage(
2107 "label.copied_sequences_to_clipboard", new Object[]
2108 { Integer.valueOf(seqs.length).toString() }));
2118 protected void pasteNew_actionPerformed(ActionEvent e)
2130 protected void pasteThis_actionPerformed(ActionEvent e)
2136 * Paste contents of Jalview clipboard
2138 * @param newAlignment
2139 * true to paste to a new alignment, otherwise add to this.
2141 void paste(boolean newAlignment)
2143 boolean externalPaste = true;
2146 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2147 Transferable contents = c.getContents(this);
2149 if (contents == null)
2158 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2159 if (str.length() < 1)
2164 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2166 } catch (OutOfMemoryError er)
2168 new OOMWarning("Out of memory pasting sequences!!", er);
2172 SequenceI[] sequences;
2173 boolean annotationAdded = false;
2174 AlignmentI alignment = null;
2176 if (Desktop.jalviewClipboard != null)
2178 // The clipboard was filled from within Jalview, we must use the
2180 // And dataset from the copied alignment
2181 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2182 // be doubly sure that we create *new* sequence objects.
2183 sequences = new SequenceI[newseq.length];
2184 for (int i = 0; i < newseq.length; i++)
2186 sequences[i] = new Sequence(newseq[i]);
2188 alignment = new Alignment(sequences);
2189 externalPaste = false;
2193 // parse the clipboard as an alignment.
2194 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2196 sequences = alignment.getSequencesArray();
2200 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2206 if (Desktop.jalviewClipboard != null)
2208 // dataset is inherited
2209 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2213 // new dataset is constructed
2214 alignment.setDataset(null);
2216 alwidth = alignment.getWidth() + 1;
2220 AlignmentI pastedal = alignment; // preserve pasted alignment object
2221 // Add pasted sequences and dataset into existing alignment.
2222 alignment = viewport.getAlignment();
2223 alwidth = alignment.getWidth() + 1;
2224 // decide if we need to import sequences from an existing dataset
2225 boolean importDs = Desktop.jalviewClipboard != null
2226 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2227 // importDs==true instructs us to copy over new dataset sequences from
2228 // an existing alignment
2229 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2231 // minimum dataset set
2233 for (int i = 0; i < sequences.length; i++)
2237 newDs.addElement(null);
2239 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2241 if (importDs && ds != null)
2243 if (!newDs.contains(ds))
2245 newDs.setElementAt(ds, i);
2246 ds = new Sequence(ds);
2247 // update with new dataset sequence
2248 sequences[i].setDatasetSequence(ds);
2252 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2257 // copy and derive new dataset sequence
2258 sequences[i] = sequences[i].deriveSequence();
2259 alignment.getDataset()
2260 .addSequence(sequences[i].getDatasetSequence());
2261 // TODO: avoid creation of duplicate dataset sequences with a
2262 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2264 alignment.addSequence(sequences[i]); // merges dataset
2268 newDs.clear(); // tidy up
2270 if (alignment.getAlignmentAnnotation() != null)
2272 for (AlignmentAnnotation alan : alignment
2273 .getAlignmentAnnotation())
2275 if (alan.graphGroup > fgroup)
2277 fgroup = alan.graphGroup;
2281 if (pastedal.getAlignmentAnnotation() != null)
2283 // Add any annotation attached to alignment.
2284 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2285 for (int i = 0; i < alann.length; i++)
2287 annotationAdded = true;
2288 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2290 AlignmentAnnotation newann = new AlignmentAnnotation(
2292 if (newann.graphGroup > -1)
2294 if (newGraphGroups.size() <= newann.graphGroup
2295 || newGraphGroups.get(newann.graphGroup) == null)
2297 for (int q = newGraphGroups
2298 .size(); q <= newann.graphGroup; q++)
2300 newGraphGroups.add(q, null);
2302 newGraphGroups.set(newann.graphGroup,
2303 Integer.valueOf(++fgroup));
2305 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2309 newann.padAnnotation(alwidth);
2310 alignment.addAnnotation(newann);
2320 addHistoryItem(new EditCommand(
2321 MessageManager.getString("label.add_sequences"),
2322 Action.PASTE, sequences, 0, alignment.getWidth(),
2325 // Add any annotations attached to sequences
2326 for (int i = 0; i < sequences.length; i++)
2328 if (sequences[i].getAnnotation() != null)
2330 AlignmentAnnotation newann;
2331 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2333 annotationAdded = true;
2334 newann = sequences[i].getAnnotation()[a];
2335 newann.adjustForAlignment();
2336 newann.padAnnotation(alwidth);
2337 if (newann.graphGroup > -1)
2339 if (newann.graphGroup > -1)
2341 if (newGraphGroups.size() <= newann.graphGroup
2342 || newGraphGroups.get(newann.graphGroup) == null)
2344 for (int q = newGraphGroups
2345 .size(); q <= newann.graphGroup; q++)
2347 newGraphGroups.add(q, null);
2349 newGraphGroups.set(newann.graphGroup,
2350 Integer.valueOf(++fgroup));
2352 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2356 // annotation was duplicated earlier
2357 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2358 // take care of contact matrix too
2359 ContactMatrixI cm = sequences[i]
2360 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2363 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2367 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2375 // propagate alignment changed.
2376 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2377 if (annotationAdded)
2379 // Duplicate sequence annotation in all views.
2380 AlignmentI[] alview = this.getViewAlignments();
2381 for (int i = 0; i < sequences.length; i++)
2383 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2388 for (int avnum = 0; avnum < alview.length; avnum++)
2390 if (alview[avnum] != alignment)
2392 // duplicate in a view other than the one with input focus
2393 int avwidth = alview[avnum].getWidth() + 1;
2394 // this relies on sann being preserved after we
2395 // modify the sequence's annotation array for each duplication
2396 for (int a = 0; a < sann.length; a++)
2398 AlignmentAnnotation newann = new AlignmentAnnotation(
2400 sequences[i].addAlignmentAnnotation(newann);
2401 newann.padAnnotation(avwidth);
2402 alview[avnum].addAnnotation(newann); // annotation was
2403 // duplicated earlier
2404 // TODO JAL-1145 graphGroups are not updated for sequence
2405 // annotation added to several views. This may cause
2407 alview[avnum].setAnnotationIndex(newann, a);
2412 buildSortByAnnotationScoresMenu();
2414 viewport.firePropertyChange("alignment", null,
2415 alignment.getSequences());
2416 if (alignPanels != null)
2418 for (AlignmentPanel ap : alignPanels)
2420 ap.validateAnnotationDimensions(false);
2425 alignPanel.validateAnnotationDimensions(false);
2431 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2433 String newtitle = new String("Copied sequences");
2435 if (Desktop.jalviewClipboard != null
2436 && Desktop.jalviewClipboard[2] != null)
2438 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2439 af.viewport.setHiddenColumns(hc);
2442 // >>>This is a fix for the moment, until a better solution is
2444 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2445 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2446 .getFeatureRenderer());
2448 // TODO: maintain provenance of an alignment, rather than just make the
2449 // title a concatenation of operations.
2452 if (title.startsWith("Copied sequences"))
2458 newtitle = newtitle.concat("- from " + title);
2463 newtitle = new String("Pasted sequences");
2466 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2471 } catch (Exception ex)
2473 ex.printStackTrace();
2474 System.out.println("Exception whilst pasting: " + ex);
2475 // could be anything being pasted in here
2481 protected void expand_newalign(ActionEvent e)
2485 AlignmentI alignment = AlignmentUtils
2486 .expandContext(getViewport().getAlignment(), -1);
2487 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2489 String newtitle = new String("Flanking alignment");
2491 if (Desktop.jalviewClipboard != null
2492 && Desktop.jalviewClipboard[2] != null)
2494 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2495 af.viewport.setHiddenColumns(hc);
2498 // >>>This is a fix for the moment, until a better solution is
2500 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2501 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2502 .getFeatureRenderer());
2504 // TODO: maintain provenance of an alignment, rather than just make the
2505 // title a concatenation of operations.
2507 if (title.startsWith("Copied sequences"))
2513 newtitle = newtitle.concat("- from " + title);
2517 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2519 } catch (Exception ex)
2521 ex.printStackTrace();
2522 System.out.println("Exception whilst pasting: " + ex);
2523 // could be anything being pasted in here
2524 } catch (OutOfMemoryError oom)
2526 new OOMWarning("Viewing flanking region of alignment", oom);
2531 * Action Cut (delete and copy) the selected region
2534 protected void cut_actionPerformed()
2536 copy_actionPerformed();
2537 delete_actionPerformed();
2541 * Performs menu option to Delete the currently selected region
2544 protected void delete_actionPerformed()
2547 SequenceGroup sg = viewport.getSelectionGroup();
2553 Runnable okAction = () -> {
2554 SequenceI[] cut = sg.getSequences()
2555 .toArray(new SequenceI[sg.getSize()]);
2557 addHistoryItem(new EditCommand(
2558 MessageManager.getString("label.cut_sequences"), Action.CUT,
2559 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2560 viewport.getAlignment()));
2562 viewport.setSelectionGroup(null);
2563 viewport.sendSelection();
2564 viewport.getAlignment().deleteGroup(sg);
2566 viewport.firePropertyChange("alignment", null,
2567 viewport.getAlignment().getSequences());
2568 if (viewport.getAlignment().getHeight() < 1)
2572 AlignFrame.this.setClosed(true);
2573 } catch (Exception ex)
2580 * If the cut affects all sequences, prompt for confirmation
2582 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2584 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2585 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2586 if (wholeHeight && wholeWidth)
2588 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2589 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2590 Object[] options = new Object[] {
2591 MessageManager.getString("action.ok"),
2592 MessageManager.getString("action.cancel") };
2593 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2594 MessageManager.getString("label.delete_all"),
2595 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2596 options, options[0]);
2603 } catch (Exception e)
2605 e.printStackTrace();
2617 protected void deleteGroups_actionPerformed(ActionEvent e)
2619 if (avc.deleteGroups())
2621 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2622 alignPanel.updateAnnotation();
2623 alignPanel.paintAlignment(true, true);
2634 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2636 SequenceGroup sg = new SequenceGroup(
2637 viewport.getAlignment().getSequences());
2639 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2640 viewport.setSelectionGroup(sg);
2641 viewport.isSelectionGroupChanged(true);
2642 viewport.sendSelection();
2643 // JAL-2034 - should delegate to
2644 // alignPanel to decide if overview needs
2646 alignPanel.paintAlignment(false, false);
2647 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2657 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2659 if (viewport.cursorMode)
2661 alignPanel.getSeqPanel().keyboardNo1 = null;
2662 alignPanel.getSeqPanel().keyboardNo2 = null;
2664 viewport.setSelectionGroup(null);
2665 viewport.getColumnSelection().clear();
2666 viewport.setSearchResults(null);
2667 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2668 // JAL-2034 - should delegate to
2669 // alignPanel to decide if overview needs
2671 alignPanel.paintAlignment(false, false);
2672 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2673 viewport.sendSelection();
2683 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2685 SequenceGroup sg = viewport.getSelectionGroup();
2689 selectAllSequenceMenuItem_actionPerformed(null);
2694 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2696 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2698 // JAL-2034 - should delegate to
2699 // alignPanel to decide if overview needs
2702 alignPanel.paintAlignment(true, false);
2703 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2704 viewport.sendSelection();
2708 public void invertColSel_actionPerformed(ActionEvent e)
2710 viewport.invertColumnSelection();
2711 alignPanel.paintAlignment(true, false);
2712 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2713 viewport.sendSelection();
2723 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2725 trimAlignment(true);
2735 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2737 trimAlignment(false);
2740 void trimAlignment(boolean trimLeft)
2742 ColumnSelection colSel = viewport.getColumnSelection();
2745 if (!colSel.isEmpty())
2749 column = colSel.getMin();
2753 column = colSel.getMax();
2757 if (viewport.getSelectionGroup() != null)
2759 seqs = viewport.getSelectionGroup()
2760 .getSequencesAsArray(viewport.getHiddenRepSequences());
2764 seqs = viewport.getAlignment().getSequencesArray();
2767 TrimRegionCommand trimRegion;
2770 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2771 column, viewport.getAlignment());
2772 viewport.getRanges().setStartRes(0);
2776 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2777 column, viewport.getAlignment());
2780 setStatus(MessageManager.formatMessage("label.removed_columns",
2782 { Integer.valueOf(trimRegion.getSize()).toString() }));
2784 addHistoryItem(trimRegion);
2786 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2788 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2789 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2791 viewport.getAlignment().deleteGroup(sg);
2795 viewport.firePropertyChange("alignment", null,
2796 viewport.getAlignment().getSequences());
2807 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2809 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2812 if (viewport.getSelectionGroup() != null)
2814 seqs = viewport.getSelectionGroup()
2815 .getSequencesAsArray(viewport.getHiddenRepSequences());
2816 start = viewport.getSelectionGroup().getStartRes();
2817 end = viewport.getSelectionGroup().getEndRes();
2821 seqs = viewport.getAlignment().getSequencesArray();
2824 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2825 "Remove Gapped Columns", seqs, start, end,
2826 viewport.getAlignment());
2828 addHistoryItem(removeGapCols);
2830 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2832 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2834 // This is to maintain viewport position on first residue
2835 // of first sequence
2836 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2837 ViewportRanges ranges = viewport.getRanges();
2838 int startRes = seq.findPosition(ranges.getStartRes());
2839 // ShiftList shifts;
2840 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2841 // edit.alColumnChanges=shifts.getInverse();
2842 // if (viewport.hasHiddenColumns)
2843 // viewport.getColumnSelection().compensateForEdits(shifts);
2844 ranges.setStartRes(seq.findIndex(startRes) - 1);
2845 viewport.firePropertyChange("alignment", null,
2846 viewport.getAlignment().getSequences());
2857 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2859 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2862 if (viewport.getSelectionGroup() != null)
2864 seqs = viewport.getSelectionGroup()
2865 .getSequencesAsArray(viewport.getHiddenRepSequences());
2866 start = viewport.getSelectionGroup().getStartRes();
2867 end = viewport.getSelectionGroup().getEndRes();
2871 seqs = viewport.getAlignment().getSequencesArray();
2874 // This is to maintain viewport position on first residue
2875 // of first sequence
2876 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2877 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2879 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2880 viewport.getAlignment()));
2882 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2884 viewport.firePropertyChange("alignment", null,
2885 viewport.getAlignment().getSequences());
2896 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2898 viewport.setPadGaps(padGapsMenuitem.isSelected());
2899 viewport.firePropertyChange("alignment", null,
2900 viewport.getAlignment().getSequences());
2904 * Opens a Finder dialog
2909 public void findMenuItem_actionPerformed(ActionEvent e)
2911 new Finder(alignPanel, false, null);
2915 * Create a new view of the current alignment.
2918 public void newView_actionPerformed(ActionEvent e)
2920 newView(null, true);
2924 * Creates and shows a new view of the current alignment.
2927 * title of newly created view; if null, one will be generated
2928 * @param copyAnnotation
2929 * if true then duplicate all annnotation, groups and settings
2930 * @return new alignment panel, already displayed.
2932 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2935 * Create a new AlignmentPanel (with its own, new Viewport)
2937 AlignmentPanel newap = new jalview.project.Jalview2XML()
2938 .copyAlignPanel(alignPanel);
2939 if (!copyAnnotation)
2942 * remove all groups and annotation except for the automatic stuff
2944 newap.av.getAlignment().deleteAllGroups();
2945 newap.av.getAlignment().deleteAllAnnotations(false);
2948 newap.av.setGatherViewsHere(false);
2950 if (viewport.getViewName() == null)
2952 viewport.setViewName(
2953 MessageManager.getString("label.view_name_original"));
2957 * Views share the same edits undo and redo stacks
2959 newap.av.setHistoryList(viewport.getHistoryList());
2960 newap.av.setRedoList(viewport.getRedoList());
2963 * copy any visualisation settings that are not saved in the project
2965 newap.av.setColourAppliesToAllGroups(
2966 viewport.getColourAppliesToAllGroups());
2969 * Views share the same mappings; need to deregister any new mappings
2970 * created by copyAlignPanel, and register the new reference to the shared
2973 newap.av.replaceMappings(viewport.getAlignment());
2976 * start up cDNA consensus (if applicable) now mappings are in place
2978 if (newap.av.initComplementConsensus())
2980 newap.refresh(true); // adjust layout of annotations
2983 newap.av.setViewName(getNewViewName(viewTitle));
2985 addAlignmentPanel(newap, true);
2986 newap.alignmentChanged();
2988 if (alignPanels.size() == 2)
2990 viewport.setGatherViewsHere(true);
2992 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2998 * Make a new name for the view, ensuring it is unique within the current
2999 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3000 * these now use viewId. Unique view names are still desirable for usability.)
3005 protected String getNewViewName(String viewTitle)
3007 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3008 boolean addFirstIndex = false;
3009 if (viewTitle == null || viewTitle.trim().length() == 0)
3011 viewTitle = MessageManager.getString("action.view");
3012 addFirstIndex = true;
3016 index = 1;// we count from 1 if given a specific name
3018 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3020 List<Component> comps = PaintRefresher.components
3021 .get(viewport.getSequenceSetId());
3023 List<String> existingNames = getExistingViewNames(comps);
3025 while (existingNames.contains(newViewName))
3027 newViewName = viewTitle + " " + (++index);
3033 * Returns a list of distinct view names found in the given list of
3034 * components. View names are held on the viewport of an AlignmentPanel.
3039 protected List<String> getExistingViewNames(List<Component> comps)
3041 List<String> existingNames = new ArrayList<>();
3042 for (Component comp : comps)
3044 if (comp instanceof AlignmentPanel)
3046 AlignmentPanel ap = (AlignmentPanel) comp;
3047 if (!existingNames.contains(ap.av.getViewName()))
3049 existingNames.add(ap.av.getViewName());
3053 return existingNames;
3057 * Explode tabbed views into separate windows.
3060 public void expandViews_actionPerformed(ActionEvent e)
3062 Desktop.explodeViews(this);
3066 * Gather views in separate windows back into a tabbed presentation.
3069 public void gatherViews_actionPerformed(ActionEvent e)
3071 Desktop.instance.gatherViews(this);
3081 public void font_actionPerformed(ActionEvent e)
3083 new FontChooser(alignPanel);
3093 protected void seqLimit_actionPerformed(ActionEvent e)
3095 viewport.setShowJVSuffix(seqLimits.isSelected());
3097 alignPanel.getIdPanel().getIdCanvas()
3098 .setPreferredSize(alignPanel.calculateIdWidth());
3099 alignPanel.paintAlignment(true, false);
3103 public void idRightAlign_actionPerformed(ActionEvent e)
3105 viewport.setRightAlignIds(idRightAlign.isSelected());
3106 alignPanel.paintAlignment(false, false);
3110 public void centreColumnLabels_actionPerformed(ActionEvent e)
3112 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3113 alignPanel.paintAlignment(false, false);
3119 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3122 protected void followHighlight_actionPerformed()
3125 * Set the 'follow' flag on the Viewport (and scroll to position if now
3128 final boolean state = this.followHighlightMenuItem.getState();
3129 viewport.setFollowHighlight(state);
3132 alignPanel.scrollToPosition(viewport.getSearchResults());
3143 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3145 viewport.setColourText(colourTextMenuItem.isSelected());
3146 alignPanel.paintAlignment(false, false);
3156 public void wrapMenuItem_actionPerformed(ActionEvent e)
3158 setWrapFormat(wrapMenuItem.isSelected(), false);
3161 public void setWrapFormat(boolean b, boolean setMenuItem)
3163 scaleAbove.setVisible(b);
3164 scaleLeft.setVisible(b);
3165 scaleRight.setVisible(b);
3166 viewport.setWrapAlignment(b);
3167 alignPanel.updateLayout();
3170 wrapMenuItem.setSelected(b);
3175 public void showAllSeqs_actionPerformed(ActionEvent e)
3177 viewport.showAllHiddenSeqs();
3181 public void showAllColumns_actionPerformed(ActionEvent e)
3183 viewport.showAllHiddenColumns();
3184 alignPanel.paintAlignment(true, true);
3185 viewport.sendSelection();
3189 public void hideSelSequences_actionPerformed(ActionEvent e)
3191 viewport.hideAllSelectedSeqs();
3195 * called by key handler and the hide all/show all menu items
3200 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3203 boolean hide = false;
3204 SequenceGroup sg = viewport.getSelectionGroup();
3205 if (!toggleSeqs && !toggleCols)
3207 // Hide everything by the current selection - this is a hack - we do the
3208 // invert and then hide
3209 // first check that there will be visible columns after the invert.
3210 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3211 && sg.getStartRes() <= sg.getEndRes()))
3213 // now invert the sequence set, if required - empty selection implies
3214 // that no hiding is required.
3217 invertSequenceMenuItem_actionPerformed(null);
3218 sg = viewport.getSelectionGroup();
3222 viewport.expandColSelection(sg, true);
3223 // finally invert the column selection and get the new sequence
3225 invertColSel_actionPerformed(null);
3232 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3234 hideSelSequences_actionPerformed(null);
3237 else if (!(toggleCols && viewport.hasSelectedColumns()))
3239 showAllSeqs_actionPerformed(null);
3245 if (viewport.hasSelectedColumns())
3247 hideSelColumns_actionPerformed(null);
3250 viewport.setSelectionGroup(sg);
3255 showAllColumns_actionPerformed(null);
3264 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3265 * event.ActionEvent)
3268 public void hideAllButSelection_actionPerformed(ActionEvent e)
3270 toggleHiddenRegions(false, false);
3271 viewport.sendSelection();
3278 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3282 public void hideAllSelection_actionPerformed(ActionEvent e)
3284 SequenceGroup sg = viewport.getSelectionGroup();
3285 viewport.expandColSelection(sg, false);
3286 viewport.hideAllSelectedSeqs();
3287 viewport.hideSelectedColumns();
3288 alignPanel.updateLayout();
3289 alignPanel.paintAlignment(true, true);
3290 viewport.sendSelection();
3297 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3301 public void showAllhidden_actionPerformed(ActionEvent e)
3303 viewport.showAllHiddenColumns();
3304 viewport.showAllHiddenSeqs();
3305 alignPanel.paintAlignment(true, true);
3306 viewport.sendSelection();
3310 public void hideSelColumns_actionPerformed(ActionEvent e)
3312 viewport.hideSelectedColumns();
3313 alignPanel.updateLayout();
3314 alignPanel.paintAlignment(true, true);
3315 viewport.sendSelection();
3319 public void hiddenMarkers_actionPerformed(ActionEvent e)
3321 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3332 protected void scaleAbove_actionPerformed(ActionEvent e)
3334 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3335 alignPanel.updateLayout();
3336 alignPanel.paintAlignment(true, false);
3346 protected void scaleLeft_actionPerformed(ActionEvent e)
3348 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3349 alignPanel.updateLayout();
3350 alignPanel.paintAlignment(true, false);
3360 protected void scaleRight_actionPerformed(ActionEvent e)
3362 viewport.setScaleRightWrapped(scaleRight.isSelected());
3363 alignPanel.updateLayout();
3364 alignPanel.paintAlignment(true, false);
3374 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3376 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3377 alignPanel.paintAlignment(false, false);
3387 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3389 viewport.setShowText(viewTextMenuItem.isSelected());
3390 alignPanel.paintAlignment(false, false);
3400 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3402 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3403 alignPanel.paintAlignment(false, false);
3406 public FeatureSettings featureSettings;
3409 public FeatureSettingsControllerI getFeatureSettingsUI()
3411 return featureSettings;
3415 public void featureSettings_actionPerformed(ActionEvent e)
3417 showFeatureSettingsUI();
3421 public FeatureSettingsControllerI showFeatureSettingsUI()
3423 if (featureSettings != null)
3425 featureSettings.closeOldSettings();
3426 featureSettings = null;
3428 if (!showSeqFeatures.isSelected())
3430 // make sure features are actually displayed
3431 showSeqFeatures.setSelected(true);
3432 showSeqFeatures_actionPerformed(null);
3434 featureSettings = new FeatureSettings(this);
3435 return featureSettings;
3439 * Set or clear 'Show Sequence Features'
3445 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3447 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3448 alignPanel.paintAlignment(true, true);
3452 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3453 * the annotations panel as a whole.
3455 * The options to show/hide all annotations should be enabled when the panel
3456 * is shown, and disabled when the panel is hidden.
3461 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3463 final boolean setVisible = annotationPanelMenuItem.isSelected();
3464 viewport.setShowAnnotation(setVisible);
3465 this.showAllSeqAnnotations.setEnabled(setVisible);
3466 this.hideAllSeqAnnotations.setEnabled(setVisible);
3467 this.showAllAlAnnotations.setEnabled(setVisible);
3468 this.hideAllAlAnnotations.setEnabled(setVisible);
3469 alignPanel.updateLayout();
3473 public void alignmentProperties()
3476 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3479 String content = MessageManager.formatMessage("label.html_content",
3481 { contents.toString() });
3484 if (Platform.isJS())
3486 JLabel textLabel = new JLabel();
3487 textLabel.setText(content);
3488 textLabel.setBackground(Color.WHITE);
3490 pane = new JPanel(new BorderLayout());
3491 ((JPanel) pane).setOpaque(true);
3492 pane.setBackground(Color.WHITE);
3493 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3502 JEditorPane editPane = new JEditorPane("text/html", "");
3503 editPane.setEditable(false);
3504 editPane.setText(content);
3508 JInternalFrame frame = new JInternalFrame();
3510 frame.getContentPane().add(new JScrollPane(pane));
3512 Desktop.addInternalFrame(frame, MessageManager
3513 .formatMessage("label.alignment_properties", new Object[]
3514 { getTitle() }), 500, 400);
3518 * Opens an Overview panel for the alignment, unless one is open already
3523 public void overviewMenuItem_actionPerformed(ActionEvent e)
3525 boolean showHiddenRegions = Cache
3526 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3527 openOverviewPanel(showHiddenRegions);
3530 public OverviewPanel openOverviewPanel(boolean showHidden)
3532 if (alignPanel.overviewPanel != null)
3534 return alignPanel.overviewPanel;
3536 JInternalFrame frame = new JInternalFrame();
3537 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3539 frame.setContentPane(overview);
3540 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3541 frame.getHeight(), true, true);
3542 frame.setFrameIcon(null);
3544 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3545 final AlignmentPanel thePanel = this.alignPanel;
3546 frame.addInternalFrameListener(
3547 new javax.swing.event.InternalFrameAdapter()
3550 public void internalFrameClosed(
3551 javax.swing.event.InternalFrameEvent evt)
3554 thePanel.setOverviewPanel(null);
3557 if (getKeyListeners().length > 0)
3559 frame.addKeyListener(getKeyListeners()[0]);
3562 alignPanel.setOverviewPanel(overview);
3563 alignPanel.setOverviewTitle(this);
3569 public void textColour_actionPerformed()
3571 new TextColourChooser().chooseColour(alignPanel, null);
3575 * public void covariationColour_actionPerformed() {
3577 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3581 public void annotationColour_actionPerformed()
3583 new AnnotationColourChooser(viewport, alignPanel);
3587 public void annotationColumn_actionPerformed(ActionEvent e)
3589 new AnnotationColumnChooser(viewport, alignPanel);
3593 * Action on the user checking or unchecking the option to apply the selected
3594 * colour scheme to all groups. If unchecked, groups may have their own
3595 * independent colour schemes.
3600 public void applyToAllGroups_actionPerformed(boolean selected)
3602 viewport.setColourAppliesToAllGroups(selected);
3606 * Action on user selecting a colour from the colour menu
3609 * the name (not the menu item label!) of the colour scheme
3612 public void changeColour_actionPerformed(String name)
3615 * 'User Defined' opens a panel to configure or load a
3616 * user-defined colour scheme
3618 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3620 new UserDefinedColours(alignPanel);
3625 * otherwise set the chosen colour scheme (or null for 'None')
3627 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3628 viewport, viewport.getAlignment(),
3629 viewport.getHiddenRepSequences());
3634 * Actions on setting or changing the alignment colour scheme
3639 public void changeColour(ColourSchemeI cs)
3641 // TODO: pull up to controller method
3642 ColourMenuHelper.setColourSelected(colourMenu, cs);
3644 viewport.setGlobalColourScheme(cs);
3646 alignPanel.paintAlignment(true, true);
3650 * Show the PID threshold slider panel
3653 protected void modifyPID_actionPerformed()
3655 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3656 alignPanel.getViewName());
3657 SliderPanel.showPIDSlider();
3661 * Show the Conservation slider panel
3664 protected void modifyConservation_actionPerformed()
3666 SliderPanel.setConservationSlider(alignPanel,
3667 viewport.getResidueShading(), alignPanel.getViewName());
3668 SliderPanel.showConservationSlider();
3672 * Action on selecting or deselecting (Colour) By Conservation
3675 public void conservationMenuItem_actionPerformed(boolean selected)
3677 modifyConservation.setEnabled(selected);
3678 viewport.setConservationSelected(selected);
3679 viewport.getResidueShading().setConservationApplied(selected);
3681 changeColour(viewport.getGlobalColourScheme());
3684 modifyConservation_actionPerformed();
3688 SliderPanel.hideConservationSlider();
3693 * Action on selecting or deselecting (Colour) Above PID Threshold
3696 public void abovePIDThreshold_actionPerformed(boolean selected)
3698 modifyPID.setEnabled(selected);
3699 viewport.setAbovePIDThreshold(selected);
3702 viewport.getResidueShading().setThreshold(0,
3703 viewport.isIgnoreGapsConsensus());
3706 changeColour(viewport.getGlobalColourScheme());
3709 modifyPID_actionPerformed();
3713 SliderPanel.hidePIDSlider();
3724 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3726 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3727 AlignmentSorter.sortByPID(viewport.getAlignment(),
3728 viewport.getAlignment().getSequenceAt(0));
3729 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3730 viewport.getAlignment()));
3731 alignPanel.paintAlignment(true, false);
3741 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3743 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3744 AlignmentSorter.sortByID(viewport.getAlignment());
3746 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3747 alignPanel.paintAlignment(true, false);
3757 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3759 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3760 AlignmentSorter.sortByLength(viewport.getAlignment());
3761 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3762 viewport.getAlignment()));
3763 alignPanel.paintAlignment(true, false);
3773 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3775 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3776 AlignmentSorter.sortByGroup(viewport.getAlignment());
3777 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3778 viewport.getAlignment()));
3780 alignPanel.paintAlignment(true, false);
3790 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3792 new RedundancyPanel(alignPanel, this);
3802 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3804 if ((viewport.getSelectionGroup() == null)
3805 || (viewport.getSelectionGroup().getSize() < 2))
3807 JvOptionPane.showInternalMessageDialog(this,
3808 MessageManager.getString(
3809 "label.you_must_select_least_two_sequences"),
3810 MessageManager.getString("label.invalid_selection"),
3811 JvOptionPane.WARNING_MESSAGE);
3815 JInternalFrame frame = new JInternalFrame();
3816 frame.setContentPane(new PairwiseAlignPanel(viewport));
3817 Desktop.addInternalFrame(frame,
3818 MessageManager.getString("action.pairwise_alignment"), 600,
3824 public void autoCalculate_actionPerformed(ActionEvent e)
3826 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3827 if (viewport.autoCalculateConsensus)
3829 viewport.firePropertyChange("alignment", null,
3830 viewport.getAlignment().getSequences());
3835 public void sortByTreeOption_actionPerformed(ActionEvent e)
3837 viewport.sortByTree = sortByTree.isSelected();
3841 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3843 viewport.followSelection = listenToViewSelections.isSelected();
3847 * Constructs a tree panel and adds it to the desktop
3850 * tree type (NJ or AV)
3852 * name of score model used to compute the tree
3854 * parameters for the distance or similarity calculation
3856 void newTreePanel(String type, String modelName,
3857 SimilarityParamsI options)
3859 String frameTitle = "";
3862 boolean onSelection = false;
3863 if (viewport.getSelectionGroup() != null
3864 && viewport.getSelectionGroup().getSize() > 0)
3866 SequenceGroup sg = viewport.getSelectionGroup();
3868 /* Decide if the selection is a column region */
3869 for (SequenceI _s : sg.getSequences())
3871 if (_s.getLength() < sg.getEndRes())
3873 JvOptionPane.showMessageDialog(Desktop.desktop,
3874 MessageManager.getString(
3875 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3876 MessageManager.getString(
3877 "label.sequences_selection_not_aligned"),
3878 JvOptionPane.WARNING_MESSAGE);
3887 if (viewport.getAlignment().getHeight() < 2)
3893 tp = new TreePanel(alignPanel, type, modelName, options);
3894 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3896 frameTitle += " from ";
3898 if (viewport.getViewName() != null)
3900 frameTitle += viewport.getViewName() + " of ";
3903 frameTitle += this.title;
3905 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3916 public void addSortByOrderMenuItem(String title,
3917 final AlignmentOrder order)
3919 final JMenuItem item = new JMenuItem(MessageManager
3920 .formatMessage("action.by_title_param", new Object[]
3923 item.addActionListener(new java.awt.event.ActionListener()
3926 public void actionPerformed(ActionEvent e)
3928 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3930 // TODO: JBPNote - have to map order entries to curent SequenceI
3932 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3934 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3935 viewport.getAlignment()));
3937 alignPanel.paintAlignment(true, false);
3943 * Add a new sort by annotation score menu item
3946 * the menu to add the option to
3948 * the label used to retrieve scores for each sequence on the
3951 public void addSortByAnnotScoreMenuItem(JMenu sort,
3952 final String scoreLabel)
3954 final JMenuItem item = new JMenuItem(scoreLabel);
3956 item.addActionListener(new java.awt.event.ActionListener()
3959 public void actionPerformed(ActionEvent e)
3961 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3962 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3963 viewport.getAlignment());// ,viewport.getSelectionGroup());
3964 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3965 viewport.getAlignment()));
3966 alignPanel.paintAlignment(true, false);
3972 * last hash for alignment's annotation array - used to minimise cost of
3975 protected int _annotationScoreVectorHash;
3978 * search the alignment and rebuild the sort by annotation score submenu the
3979 * last alignment annotation vector hash is stored to minimize cost of
3980 * rebuilding in subsequence calls.
3984 public void buildSortByAnnotationScoresMenu()
3986 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3991 if (viewport.getAlignment().getAlignmentAnnotation()
3992 .hashCode() != _annotationScoreVectorHash)
3994 sortByAnnotScore.removeAll();
3995 // almost certainly a quicker way to do this - but we keep it simple
3996 Hashtable<String, String> scoreSorts = new Hashtable<>();
3997 AlignmentAnnotation aann[];
3998 for (SequenceI sqa : viewport.getAlignment().getSequences())
4000 aann = sqa.getAnnotation();
4001 for (int i = 0; aann != null && i < aann.length; i++)
4003 if (aann[i].hasScore() && aann[i].sequenceRef != null)
4005 scoreSorts.put(aann[i].label, aann[i].label);
4009 Enumeration<String> labels = scoreSorts.keys();
4010 while (labels.hasMoreElements())
4012 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4014 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4017 _annotationScoreVectorHash = viewport.getAlignment()
4018 .getAlignmentAnnotation().hashCode();
4023 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4024 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4025 * call. Listeners are added to remove the menu item when the treePanel is
4026 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4030 public void buildTreeSortMenu()
4032 sortByTreeMenu.removeAll();
4034 List<Component> comps = PaintRefresher.components
4035 .get(viewport.getSequenceSetId());
4036 List<TreePanel> treePanels = new ArrayList<>();
4037 for (Component comp : comps)
4039 if (comp instanceof TreePanel)
4041 treePanels.add((TreePanel) comp);
4045 if (treePanels.size() < 1)
4047 sortByTreeMenu.setVisible(false);
4051 sortByTreeMenu.setVisible(true);
4053 for (final TreePanel tp : treePanels)
4055 final JMenuItem item = new JMenuItem(tp.getTitle());
4056 item.addActionListener(new java.awt.event.ActionListener()
4059 public void actionPerformed(ActionEvent e)
4061 tp.sortByTree_actionPerformed();
4062 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4067 sortByTreeMenu.add(item);
4071 public boolean sortBy(AlignmentOrder alorder, String undoname)
4073 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4074 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4075 if (undoname != null)
4077 addHistoryItem(new OrderCommand(undoname, oldOrder,
4078 viewport.getAlignment()));
4080 alignPanel.paintAlignment(true, false);
4085 * Work out whether the whole set of sequences or just the selected set will
4086 * be submitted for multiple alignment.
4089 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4091 // Now, check we have enough sequences
4092 AlignmentView msa = null;
4094 if ((viewport.getSelectionGroup() != null)
4095 && (viewport.getSelectionGroup().getSize() > 1))
4097 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4098 // some common interface!
4100 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4101 * SequenceI[sz = seqs.getSize(false)];
4103 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4104 * seqs.getSequenceAt(i); }
4106 msa = viewport.getAlignmentView(true);
4108 else if (viewport.getSelectionGroup() != null
4109 && viewport.getSelectionGroup().getSize() == 1)
4111 int option = JvOptionPane.showConfirmDialog(this,
4112 MessageManager.getString("warn.oneseq_msainput_selection"),
4113 MessageManager.getString("label.invalid_selection"),
4114 JvOptionPane.OK_CANCEL_OPTION);
4115 if (option == JvOptionPane.OK_OPTION)
4117 msa = viewport.getAlignmentView(false);
4122 msa = viewport.getAlignmentView(false);
4128 * Decides what is submitted to a secondary structure prediction service: the
4129 * first sequence in the alignment, or in the current selection, or, if the
4130 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4131 * region or the whole alignment. (where the first sequence in the set is the
4132 * one that the prediction will be for).
4134 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4136 AlignmentView seqs = null;
4138 if ((viewport.getSelectionGroup() != null)
4139 && (viewport.getSelectionGroup().getSize() > 0))
4141 seqs = viewport.getAlignmentView(true);
4145 seqs = viewport.getAlignmentView(false);
4147 // limit sequences - JBPNote in future - could spawn multiple prediction
4149 // TODO: viewport.getAlignment().isAligned is a global state - the local
4150 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4151 if (!viewport.getAlignment().isAligned(false))
4153 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4154 // TODO: if seqs.getSequences().length>1 then should really have warned
4168 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4170 // Pick the tree file
4171 JalviewFileChooser chooser = new JalviewFileChooser(
4172 Cache.getProperty("LAST_DIRECTORY"));
4173 chooser.setFileView(new JalviewFileView());
4174 chooser.setDialogTitle(
4175 MessageManager.getString("label.select_newick_like_tree_file"));
4176 chooser.setToolTipText(
4177 MessageManager.getString("label.load_tree_file"));
4179 chooser.setResponseHandler(0, () -> {
4180 String filePath = chooser.getSelectedFile().getPath();
4181 Cache.setProperty("LAST_DIRECTORY", filePath);
4182 NewickFile fin = null;
4185 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4186 DataSourceType.FILE));
4187 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4188 } catch (Exception ex)
4190 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4191 MessageManager.getString("label.problem_reading_tree_file"),
4192 JvOptionPane.WARNING_MESSAGE);
4193 ex.printStackTrace();
4195 if (fin != null && fin.hasWarningMessage())
4197 JvOptionPane.showMessageDialog(Desktop.desktop,
4198 fin.getWarningMessage(),
4200 .getString("label.possible_problem_with_tree_file"),
4201 JvOptionPane.WARNING_MESSAGE);
4204 chooser.showOpenDialog(this);
4207 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4209 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4212 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4213 int h, int x, int y)
4215 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4219 * Add a treeviewer for the tree extracted from a Newick file object to the
4220 * current alignment view
4227 * Associated alignment input data (or null)
4236 * @return TreePanel handle
4238 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4239 AlignmentView input, int w, int h, int x, int y)
4241 TreePanel tp = null;
4247 if (nf.getTree() != null)
4249 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4255 tp.setLocation(x, y);
4258 Desktop.addInternalFrame(tp, treeTitle, w, h);
4260 } catch (Exception ex)
4262 ex.printStackTrace();
4268 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4271 int w = 400, h = 500;
4275 NewickFile fin = new NewickFile(
4276 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4277 String title = aa.label + " " + cm.getTreeMethod() + " tree"
4278 + (aa.sequenceRef != null
4279 ? (" for " + aa.sequenceRef.getDisplayId(false))
4282 showColumnWiseTree(fin, aa, title, w, h, x, y);
4283 } catch (Throwable xx)
4285 Console.error("Unexpected exception showing tree for contact matrix",
4290 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4291 String treeTitle, int w, int h, int x, int y)
4296 if (nf.getTree() == null)
4300 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4306 tp.setLocation(x, y);
4309 Desktop.addInternalFrame(tp, treeTitle, w, h);
4311 } catch (Throwable xx)
4313 Console.error("Unexpected exception showing tree for contact matrix",
4319 private boolean buildingMenu = false;
4322 * Generates menu items and listener event actions for web service clients
4325 public void BuildWebServiceMenu()
4327 while (buildingMenu)
4331 System.err.println("Waiting for building menu to finish.");
4333 } catch (Exception e)
4337 final AlignFrame me = this;
4338 buildingMenu = true;
4339 new Thread(new Runnable()
4344 final List<JMenuItem> legacyItems = new ArrayList<>();
4347 // System.err.println("Building ws menu again "
4348 // + Thread.currentThread());
4349 // TODO: add support for context dependent disabling of services based
4351 // alignment and current selection
4352 // TODO: add additional serviceHandle parameter to specify abstract
4354 // class independently of AbstractName
4355 // TODO: add in rediscovery GUI function to restart discoverer
4356 // TODO: group services by location as well as function and/or
4358 // object broker mechanism.
4359 final Vector<JMenu> wsmenu = new Vector<>();
4360 final IProgressIndicator af = me;
4363 * do not i18n these strings - they are hard-coded in class
4364 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4365 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4367 final JMenu msawsmenu = new JMenu("Alignment");
4368 final JMenu secstrmenu = new JMenu(
4369 "Secondary Structure Prediction");
4370 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4371 final JMenu analymenu = new JMenu("Analysis");
4372 final JMenu dismenu = new JMenu("Protein Disorder");
4373 // JAL-940 - only show secondary structure prediction services from
4374 // the legacy server
4375 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4377 Discoverer.services != null && (Discoverer.services.size() > 0))
4379 // TODO: refactor to allow list of AbstractName/Handler bindings to
4381 // stored or retrieved from elsewhere
4382 // No MSAWS used any more:
4383 // Vector msaws = null; // (Vector)
4384 // Discoverer.services.get("MsaWS");
4385 Vector<ServiceHandle> secstrpr = Discoverer.services
4387 if (secstrpr != null)
4389 // Add any secondary structure prediction services
4390 for (int i = 0, j = secstrpr.size(); i < j; i++)
4392 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4393 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4394 .getServiceClient(sh);
4395 int p = secstrmenu.getItemCount();
4396 impl.attachWSMenuEntry(secstrmenu, me);
4397 int q = secstrmenu.getItemCount();
4398 for (int litm = p; litm < q; litm++)
4400 legacyItems.add(secstrmenu.getItem(litm));
4406 // Add all submenus in the order they should appear on the web
4408 wsmenu.add(msawsmenu);
4409 wsmenu.add(secstrmenu);
4410 wsmenu.add(dismenu);
4411 wsmenu.add(analymenu);
4412 // No search services yet
4413 // wsmenu.add(seqsrchmenu);
4415 javax.swing.SwingUtilities.invokeLater(new Runnable()
4422 webService.removeAll();
4423 // first, add discovered services onto the webservices menu
4424 if (wsmenu.size() > 0)
4426 for (int i = 0, j = wsmenu.size(); i < j; i++)
4428 webService.add(wsmenu.get(i));
4433 webService.add(me.webServiceNoServices);
4435 // TODO: move into separate menu builder class.
4437 // logic for 2.11.1.4 is
4438 // always look to see if there is a discover. if there isn't
4439 // we can't show any Jws2 services
4440 // if there are services available, show them - regardless of
4441 // the 'show JWS2 preference'
4442 // if the discoverer is running then say so
4443 // otherwise offer to trigger discovery if 'show JWS2' is not
4445 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4446 if (jws2servs != null)
4448 if (jws2servs.hasServices())
4450 jws2servs.attachWSMenuEntry(webService, me);
4451 for (Jws2Instance sv : jws2servs.getServices())
4453 if (sv.description.toLowerCase(Locale.ROOT)
4456 for (JMenuItem jmi : legacyItems)
4458 jmi.setVisible(false);
4464 if (jws2servs.isRunning())
4466 JMenuItem tm = new JMenuItem(
4467 "Still discovering JABA Services");
4468 tm.setEnabled(false);
4471 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4473 JMenuItem enableJws2 = new JMenuItem(
4474 "Discover Web Services");
4475 enableJws2.setToolTipText(
4476 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4477 enableJws2.setEnabled(true);
4478 enableJws2.addActionListener(new ActionListener()
4482 public void actionPerformed(ActionEvent e)
4484 // start service discoverer, but ignore preference
4485 Desktop.instance.startServiceDiscovery(false,
4489 webService.add(enableJws2);
4493 build_urlServiceMenu(me.webService);
4494 build_fetchdbmenu(webService);
4495 for (JMenu item : wsmenu)
4497 if (item.getItemCount() == 0)
4499 item.setEnabled(false);
4503 item.setEnabled(true);
4506 } catch (Exception e)
4509 "Exception during web service menu building process.",
4514 } catch (Exception e)
4517 buildingMenu = false;
4524 * construct any groupURL type service menu entries.
4528 protected void build_urlServiceMenu(JMenu webService)
4530 // TODO: remove this code when 2.7 is released
4531 // DEBUG - alignmentView
4533 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4534 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4536 * @Override public void actionPerformed(ActionEvent e) {
4537 * jalview.datamodel.AlignmentView
4538 * .testSelectionViews(af.viewport.getAlignment(),
4539 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4541 * }); webService.add(testAlView);
4543 // TODO: refactor to RestClient discoverer and merge menu entries for
4544 // rest-style services with other types of analysis/calculation service
4545 // SHmmr test client - still being implemented.
4546 // DEBUG - alignmentView
4548 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4551 client.attachWSMenuEntry(
4552 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4558 * Searches the alignment sequences for xRefs and builds the Show
4559 * Cross-References menu (formerly called Show Products), with database
4560 * sources for which cross-references are found (protein sources for a
4561 * nucleotide alignment and vice versa)
4563 * @return true if Show Cross-references menu should be enabled
4565 public boolean canShowProducts()
4567 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4568 AlignmentI dataset = viewport.getAlignment().getDataset();
4570 showProducts.removeAll();
4571 final boolean dna = viewport.getAlignment().isNucleotide();
4573 if (seqs == null || seqs.length == 0)
4575 // nothing to see here.
4579 boolean showp = false;
4582 List<String> ptypes = new CrossRef(seqs, dataset)
4583 .findXrefSourcesForSequences(dna);
4585 for (final String source : ptypes)
4588 final AlignFrame af = this;
4589 JMenuItem xtype = new JMenuItem(source);
4590 xtype.addActionListener(new ActionListener()
4593 public void actionPerformed(ActionEvent e)
4595 showProductsFor(af.viewport.getSequenceSelection(), dna,
4599 showProducts.add(xtype);
4601 showProducts.setVisible(showp);
4602 showProducts.setEnabled(showp);
4603 } catch (Exception e)
4606 "canShowProducts threw an exception - please report to help@jalview.org",
4614 * Finds and displays cross-references for the selected sequences (protein
4615 * products for nucleotide sequences, dna coding sequences for peptides).
4618 * the sequences to show cross-references for
4620 * true if from a nucleotide alignment (so showing proteins)
4622 * the database to show cross-references for
4624 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4625 final String source)
4627 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4632 * Construct and display a new frame containing the translation of this
4633 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4636 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4638 AlignmentI al = null;
4641 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4643 al = dna.translateCdna(codeTable);
4644 } catch (Exception ex)
4646 Console.error("Exception during translation. Please report this !",
4648 final String msg = MessageManager.getString(
4649 "label.error_when_translating_sequences_submit_bug_report");
4650 final String errorTitle = MessageManager
4651 .getString("label.implementation_error")
4652 + MessageManager.getString("label.translation_failed");
4653 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4654 JvOptionPane.ERROR_MESSAGE);
4657 if (al == null || al.getHeight() == 0)
4659 final String msg = MessageManager.getString(
4660 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4661 final String errorTitle = MessageManager
4662 .getString("label.translation_failed");
4663 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4664 JvOptionPane.WARNING_MESSAGE);
4668 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4669 af.setFileFormat(this.currentFileFormat);
4670 final String newTitle = MessageManager
4671 .formatMessage("label.translation_of_params", new Object[]
4672 { this.getTitle(), codeTable.getId() });
4673 af.setTitle(newTitle);
4674 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4676 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4677 viewport.openSplitFrame(af, new Alignment(seqs));
4681 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4688 * Set the file format
4692 public void setFileFormat(FileFormatI format)
4694 this.currentFileFormat = format;
4698 * Try to load a features file onto the alignment.
4701 * contents or path to retrieve file or a File object
4703 * access mode of file (see jalview.io.AlignFile)
4704 * @return true if features file was parsed correctly.
4706 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4709 return avc.parseFeaturesFile(file, sourceType,
4710 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4715 public void refreshFeatureUI(boolean enableIfNecessary)
4717 // note - currently this is only still here rather than in the controller
4718 // because of the featureSettings hard reference that is yet to be
4720 if (enableIfNecessary)
4722 viewport.setShowSequenceFeatures(true);
4723 showSeqFeatures.setSelected(true);
4729 public void dragEnter(DropTargetDragEvent evt)
4734 public void dragExit(DropTargetEvent evt)
4739 public void dragOver(DropTargetDragEvent evt)
4744 public void dropActionChanged(DropTargetDragEvent evt)
4749 public void drop(DropTargetDropEvent evt)
4751 // JAL-1552 - acceptDrop required before getTransferable call for
4752 // Java's Transferable for native dnd
4753 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4754 Transferable t = evt.getTransferable();
4756 final AlignFrame thisaf = this;
4757 final List<Object> files = new ArrayList<>();
4758 List<DataSourceType> protocols = new ArrayList<>();
4762 Desktop.transferFromDropTarget(files, protocols, evt, t);
4763 } catch (Exception e)
4765 e.printStackTrace();
4769 new Thread(new Runnable()
4776 // check to see if any of these files have names matching sequences
4779 SequenceIdMatcher idm = new SequenceIdMatcher(
4780 viewport.getAlignment().getSequencesArray());
4782 * Object[] { String,SequenceI}
4784 ArrayList<Object[]> filesmatched = new ArrayList<>();
4785 ArrayList<Object> filesnotmatched = new ArrayList<>();
4786 for (int i = 0; i < files.size(); i++)
4789 Object file = files.get(i);
4790 String fileName = file.toString();
4792 DataSourceType protocol = (file instanceof File
4793 ? DataSourceType.FILE
4794 : FormatAdapter.checkProtocol(fileName));
4795 if (protocol == DataSourceType.FILE)
4798 if (file instanceof File)
4801 Platform.cacheFileData(fl);
4805 fl = new File(fileName);
4807 pdbfn = fl.getName();
4809 else if (protocol == DataSourceType.URL)
4811 URL url = new URL(fileName);
4812 pdbfn = url.getFile();
4814 if (pdbfn.length() > 0)
4816 // attempt to find a match in the alignment
4817 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4818 int l = 0, c = pdbfn.indexOf(".");
4819 while (mtch == null && c != -1)
4824 } while ((c = pdbfn.indexOf(".", l)) > l);
4827 pdbfn = pdbfn.substring(0, l);
4829 mtch = idm.findAllIdMatches(pdbfn);
4836 type = new IdentifyFile().identify(file, protocol);
4837 } catch (Exception ex)
4841 if (type != null && type.isStructureFile())
4843 filesmatched.add(new Object[] { file, protocol, mtch });
4847 // File wasn't named like one of the sequences or wasn't a PDB
4849 filesnotmatched.add(file);
4853 if (filesmatched.size() > 0)
4855 boolean autoAssociate = Cache
4856 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4859 String msg = MessageManager.formatMessage(
4860 "label.automatically_associate_structure_files_with_sequences_same_name",
4862 { Integer.valueOf(filesmatched.size())
4864 String ttl = MessageManager.getString(
4865 "label.automatically_associate_structure_files_by_name");
4866 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4867 ttl, JvOptionPane.YES_NO_OPTION);
4868 autoAssociate = choice == JvOptionPane.YES_OPTION;
4872 for (Object[] fm : filesmatched)
4874 // try and associate
4875 // TODO: may want to set a standard ID naming formalism for
4876 // associating PDB files which have no IDs.
4877 for (SequenceI toassoc : (SequenceI[]) fm[2])
4879 PDBEntry pe = new AssociatePdbFileWithSeq()
4880 .associatePdbWithSeq(fm[0].toString(),
4881 (DataSourceType) fm[1], toassoc, false,
4885 System.err.println("Associated file : "
4886 + (fm[0].toString()) + " with "
4887 + toassoc.getDisplayId(true));
4891 // TODO: do we need to update overview ? only if features are
4893 alignPanel.paintAlignment(true, false);
4899 * add declined structures as sequences
4901 for (Object[] o : filesmatched)
4903 filesnotmatched.add(o[0]);
4907 if (filesnotmatched.size() > 0)
4909 if (assocfiles > 0 && (Cache.getDefault(
4910 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4911 || JvOptionPane.showConfirmDialog(thisaf,
4912 "<html>" + MessageManager.formatMessage(
4913 "label.ignore_unmatched_dropped_files_info",
4916 filesnotmatched.size())
4919 MessageManager.getString(
4920 "label.ignore_unmatched_dropped_files"),
4921 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4925 for (Object fn : filesnotmatched)
4927 loadJalviewDataFile(fn, null, null, null);
4931 } catch (Exception ex)
4933 ex.printStackTrace();
4941 * Attempt to load a "dropped" file or URL string, by testing in turn for
4943 * <li>an Annotation file</li>
4944 * <li>a JNet file</li>
4945 * <li>a features file</li>
4946 * <li>else try to interpret as an alignment file</li>
4950 * either a filename or a URL string.
4952 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4953 FileFormatI format, SequenceI assocSeq)
4955 // BH 2018 was String file
4958 if (sourceType == null)
4960 sourceType = FormatAdapter.checkProtocol(file);
4962 // if the file isn't identified, or not positively identified as some
4963 // other filetype (PFAM is default unidentified alignment file type) then
4964 // try to parse as annotation.
4965 boolean isAnnotation = (format == null
4966 || FileFormat.Pfam.equals(format))
4967 ? new AnnotationFile().annotateAlignmentView(viewport,
4973 // first see if its a T-COFFEE score file
4974 TCoffeeScoreFile tcf = null;
4977 tcf = new TCoffeeScoreFile(file, sourceType);
4980 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4984 new TCoffeeColourScheme(viewport.getAlignment()));
4985 isAnnotation = true;
4986 setStatus(MessageManager.getString(
4987 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4991 // some problem - if no warning its probable that the ID matching
4992 // process didn't work
4993 JvOptionPane.showMessageDialog(Desktop.desktop,
4994 tcf.getWarningMessage() == null
4995 ? MessageManager.getString(
4996 "label.check_file_matches_sequence_ids_alignment")
4997 : tcf.getWarningMessage(),
4998 MessageManager.getString(
4999 "label.problem_reading_tcoffee_score_file"),
5000 JvOptionPane.WARNING_MESSAGE);
5007 } catch (Exception x)
5010 "Exception when processing data source as T-COFFEE score file",
5016 // try to see if its a JNet 'concise' style annotation file *before*
5018 // try to parse it as a features file
5021 format = new IdentifyFile().identify(file, sourceType);
5023 if (FileFormat.ScoreMatrix == format)
5025 ScoreMatrixFile sm = new ScoreMatrixFile(
5026 new FileParse(file, sourceType));
5028 // todo: i18n this message
5029 setStatus(MessageManager.formatMessage(
5030 "label.successfully_loaded_matrix",
5031 sm.getMatrixName()));
5033 else if (FileFormat.Jnet.equals(format))
5035 JPredFile predictions = new JPredFile(file, sourceType);
5036 new JnetAnnotationMaker();
5037 JnetAnnotationMaker.add_annotation(predictions,
5038 viewport.getAlignment(), 0, false);
5039 viewport.getAlignment().setupJPredAlignment();
5040 isAnnotation = true;
5042 // else if (IdentifyFile.FeaturesFile.equals(format))
5043 else if (FileFormat.Features.equals(format))
5045 if (parseFeaturesFile(file, sourceType))
5047 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5048 if (splitFrame != null)
5050 splitFrame.repaint();
5054 alignPanel.paintAlignment(true, true);
5060 new FileLoader().LoadFile(viewport, file, sourceType, format);
5067 alignPanel.adjustAnnotationHeight();
5068 viewport.updateSequenceIdColours();
5069 buildSortByAnnotationScoresMenu();
5070 alignPanel.paintAlignment(true, true);
5072 } catch (Exception ex)
5074 ex.printStackTrace();
5075 } catch (OutOfMemoryError oom)
5080 } catch (Exception x)
5085 + (sourceType != null
5086 ? (sourceType == DataSourceType.PASTE
5088 : "using " + sourceType + " from "
5092 ? "(parsing as '" + format + "' file)"
5094 oom, Desktop.desktop);
5099 * Method invoked by the ChangeListener on the tabbed pane, in other words
5100 * when a different tabbed pane is selected by the user or programmatically.
5103 public void tabSelectionChanged(int index)
5108 * update current Overview window title (if there is one)
5109 * to add view name "Original" if necessary
5111 alignPanel.setOverviewTitle(this);
5114 * switch panels and set Overview title (if there is one
5115 * because it was opened automatically)
5117 alignPanel = alignPanels.get(index);
5118 alignPanel.setOverviewTitle(this);
5120 viewport = alignPanel.av;
5121 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5122 setMenusFromViewport(viewport);
5123 if (featureSettings != null && featureSettings.isOpen()
5124 && featureSettings.fr.getViewport() != viewport)
5126 if (viewport.isShowSequenceFeatures())
5128 // refresh the featureSettings to reflect UI change
5129 showFeatureSettingsUI();
5133 // close feature settings for this view.
5134 featureSettings.close();
5141 * 'focus' any colour slider that is open to the selected viewport
5143 if (viewport.getConservationSelected())
5145 SliderPanel.setConservationSlider(alignPanel,
5146 viewport.getResidueShading(), alignPanel.getViewName());
5150 SliderPanel.hideConservationSlider();
5152 if (viewport.getAbovePIDThreshold())
5154 SliderPanel.setPIDSliderSource(alignPanel,
5155 viewport.getResidueShading(), alignPanel.getViewName());
5159 SliderPanel.hidePIDSlider();
5163 * If there is a frame linked to this one in a SplitPane, switch it to the
5164 * same view tab index. No infinite recursion of calls should happen, since
5165 * tabSelectionChanged() should not get invoked on setting the selected
5166 * index to an unchanged value. Guard against setting an invalid index
5167 * before the new view peer tab has been created.
5169 final AlignViewportI peer = viewport.getCodingComplement();
5172 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5173 .getAlignPanel().alignFrame;
5174 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5176 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5182 * On right mouse click on view tab, prompt for and set new view name.
5185 public void tabbedPane_mousePressed(MouseEvent e)
5187 if (e.isPopupTrigger())
5189 String msg = MessageManager.getString("label.enter_view_name");
5190 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5191 String reply = JvOptionPane.showInputDialog(msg, ttl);
5195 viewport.setViewName(reply);
5196 // TODO warn if reply is in getExistingViewNames()?
5197 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5202 public AlignViewport getCurrentView()
5208 * Open the dialog for regex description parsing.
5211 protected void extractScores_actionPerformed(ActionEvent e)
5213 ParseProperties pp = new jalview.analysis.ParseProperties(
5214 viewport.getAlignment());
5215 // TODO: verify regex and introduce GUI dialog for version 2.5
5216 // if (pp.getScoresFromDescription("col", "score column ",
5217 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5219 if (pp.getScoresFromDescription("description column",
5220 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5222 buildSortByAnnotationScoresMenu();
5230 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5234 protected void showDbRefs_actionPerformed(ActionEvent e)
5236 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5242 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5246 protected void showNpFeats_actionPerformed(ActionEvent e)
5248 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5252 * find the viewport amongst the tabs in this alignment frame and close that
5257 public boolean closeView(AlignViewportI av)
5261 this.closeMenuItem_actionPerformed(false);
5264 Component[] comp = tabbedPane.getComponents();
5265 for (int i = 0; comp != null && i < comp.length; i++)
5267 if (comp[i] instanceof AlignmentPanel)
5269 if (((AlignmentPanel) comp[i]).av == av)
5272 closeView((AlignmentPanel) comp[i]);
5280 protected void build_fetchdbmenu(JMenu webService)
5282 // Temporary hack - DBRef Fetcher always top level ws entry.
5283 // TODO We probably want to store a sequence database checklist in
5284 // preferences and have checkboxes.. rather than individual sources selected
5286 final JMenu rfetch = new JMenu(
5287 MessageManager.getString("action.fetch_db_references"));
5288 rfetch.setToolTipText(MessageManager.getString(
5289 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5290 webService.add(rfetch);
5292 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5293 MessageManager.getString("option.trim_retrieved_seqs"));
5294 trimrs.setToolTipText(
5295 MessageManager.getString("label.trim_retrieved_sequences"));
5297 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5298 trimrs.addActionListener(new ActionListener()
5301 public void actionPerformed(ActionEvent e)
5303 trimrs.setSelected(trimrs.isSelected());
5304 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5305 Boolean.valueOf(trimrs.isSelected()).toString());
5309 JMenuItem fetchr = new JMenuItem(
5310 MessageManager.getString("label.standard_databases"));
5311 fetchr.setToolTipText(
5312 MessageManager.getString("label.fetch_embl_uniprot"));
5313 fetchr.addActionListener(new ActionListener()
5317 public void actionPerformed(ActionEvent e)
5319 new Thread(new Runnable()
5324 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5325 .getAlignment().isNucleotide();
5326 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5327 alignPanel.av.getSequenceSelection(),
5328 alignPanel.alignFrame, null,
5329 alignPanel.alignFrame.featureSettings, isNucleotide);
5330 dbRefFetcher.addListener(new FetchFinishedListenerI()
5333 public void finished()
5336 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5337 .getFeatureSettingsModels())
5340 alignPanel.av.mergeFeaturesStyle(srcSettings);
5342 AlignFrame.this.setMenusForViewport();
5345 dbRefFetcher.fetchDBRefs(false);
5353 new Thread(new Runnable()
5358 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5359 .getSequenceFetcherSingleton();
5360 javax.swing.SwingUtilities.invokeLater(new Runnable()
5365 String[] dbclasses = sf.getNonAlignmentSources();
5366 List<DbSourceProxy> otherdb;
5367 JMenu dfetch = new JMenu();
5368 JMenu ifetch = new JMenu();
5369 JMenuItem fetchr = null;
5370 int comp = 0, icomp = 0, mcomp = 15;
5371 String mname = null;
5373 for (String dbclass : dbclasses)
5375 otherdb = sf.getSourceProxy(dbclass);
5376 // add a single entry for this class, or submenu allowing 'fetch
5378 if (otherdb == null || otherdb.size() < 1)
5384 mname = "From " + dbclass;
5386 if (otherdb.size() == 1)
5388 final DbSourceProxy[] dassource = otherdb
5389 .toArray(new DbSourceProxy[0]);
5390 DbSourceProxy src = otherdb.get(0);
5391 fetchr = new JMenuItem(src.getDbSource());
5392 fetchr.addActionListener(new ActionListener()
5396 public void actionPerformed(ActionEvent e)
5398 new Thread(new Runnable()
5404 boolean isNucleotide = alignPanel.alignFrame
5405 .getViewport().getAlignment()
5407 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5408 alignPanel.av.getSequenceSelection(),
5409 alignPanel.alignFrame, dassource,
5410 alignPanel.alignFrame.featureSettings,
5413 .addListener(new FetchFinishedListenerI()
5416 public void finished()
5418 FeatureSettingsModelI srcSettings = dassource[0]
5419 .getFeatureColourScheme();
5420 alignPanel.av.mergeFeaturesStyle(
5422 AlignFrame.this.setMenusForViewport();
5425 dbRefFetcher.fetchDBRefs(false);
5431 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5432 MessageManager.formatMessage(
5433 "label.fetch_retrieve_from", new Object[]
5434 { src.getDbName() })));
5440 final DbSourceProxy[] dassource = otherdb
5441 .toArray(new DbSourceProxy[0]);
5443 DbSourceProxy src = otherdb.get(0);
5444 fetchr = new JMenuItem(MessageManager
5445 .formatMessage("label.fetch_all_param", new Object[]
5446 { src.getDbSource() }));
5447 fetchr.addActionListener(new ActionListener()
5450 public void actionPerformed(ActionEvent e)
5452 new Thread(new Runnable()
5458 boolean isNucleotide = alignPanel.alignFrame
5459 .getViewport().getAlignment()
5461 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5462 alignPanel.av.getSequenceSelection(),
5463 alignPanel.alignFrame, dassource,
5464 alignPanel.alignFrame.featureSettings,
5467 .addListener(new FetchFinishedListenerI()
5470 public void finished()
5472 AlignFrame.this.setMenusForViewport();
5475 dbRefFetcher.fetchDBRefs(false);
5481 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5482 MessageManager.formatMessage(
5483 "label.fetch_retrieve_from_all_sources",
5485 { Integer.valueOf(otherdb.size())
5487 src.getDbSource(), src.getDbName() })));
5490 // and then build the rest of the individual menus
5491 ifetch = new JMenu(MessageManager.formatMessage(
5492 "label.source_from_db_source", new Object[]
5493 { src.getDbSource() }));
5495 String imname = null;
5497 for (DbSourceProxy sproxy : otherdb)
5499 String dbname = sproxy.getDbName();
5500 String sname = dbname.length() > 5
5501 ? dbname.substring(0, 5) + "..."
5503 String msname = dbname.length() > 10
5504 ? dbname.substring(0, 10) + "..."
5508 imname = MessageManager
5509 .formatMessage("label.from_msname", new Object[]
5512 fetchr = new JMenuItem(msname);
5513 final DbSourceProxy[] dassrc = { sproxy };
5514 fetchr.addActionListener(new ActionListener()
5518 public void actionPerformed(ActionEvent e)
5520 new Thread(new Runnable()
5526 boolean isNucleotide = alignPanel.alignFrame
5527 .getViewport().getAlignment()
5529 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5530 alignPanel.av.getSequenceSelection(),
5531 alignPanel.alignFrame, dassrc,
5532 alignPanel.alignFrame.featureSettings,
5535 .addListener(new FetchFinishedListenerI()
5538 public void finished()
5540 AlignFrame.this.setMenusForViewport();
5543 dbRefFetcher.fetchDBRefs(false);
5549 fetchr.setToolTipText(
5550 "<html>" + MessageManager.formatMessage(
5551 "label.fetch_retrieve_from", new Object[]
5555 if (++icomp >= mcomp || i == (otherdb.size()))
5557 ifetch.setText(MessageManager.formatMessage(
5558 "label.source_to_target", imname, sname));
5560 ifetch = new JMenu();
5568 if (comp >= mcomp || dbi >= (dbclasses.length))
5570 dfetch.setText(MessageManager.formatMessage(
5571 "label.source_to_target", mname, dbclass));
5573 dfetch = new JMenu();
5586 * Left justify the whole alignment.
5589 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5591 AlignmentI al = viewport.getAlignment();
5593 viewport.firePropertyChange("alignment", null, al);
5597 * Right justify the whole alignment.
5600 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5602 AlignmentI al = viewport.getAlignment();
5604 viewport.firePropertyChange("alignment", null, al);
5608 public void setShowSeqFeatures(boolean b)
5610 showSeqFeatures.setSelected(b);
5611 viewport.setShowSequenceFeatures(b);
5618 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5619 * awt.event.ActionEvent)
5622 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5624 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5625 alignPanel.paintAlignment(false, false);
5632 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5636 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5638 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5639 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5647 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5648 * .event.ActionEvent)
5651 protected void showGroupConservation_actionPerformed(ActionEvent e)
5653 viewport.setShowGroupConservation(showGroupConservation.getState());
5654 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5661 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5662 * .event.ActionEvent)
5665 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5667 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5668 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5675 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5676 * .event.ActionEvent)
5679 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5681 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5682 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5686 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5688 showSequenceLogo.setState(true);
5689 viewport.setShowSequenceLogo(true);
5690 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5691 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5695 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5697 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5704 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5705 * .event.ActionEvent)
5708 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5710 if (avc.makeGroupsFromSelection())
5712 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5713 alignPanel.updateAnnotation();
5714 alignPanel.paintAlignment(true,
5715 viewport.needToUpdateStructureViews());
5719 public void clearAlignmentSeqRep()
5721 // TODO refactor alignmentseqrep to controller
5722 if (viewport.getAlignment().hasSeqrep())
5724 viewport.getAlignment().setSeqrep(null);
5725 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5726 alignPanel.updateAnnotation();
5727 alignPanel.paintAlignment(true, true);
5732 protected void createGroup_actionPerformed(ActionEvent e)
5734 if (avc.createGroup())
5736 if (applyAutoAnnotationSettings.isSelected())
5738 alignPanel.updateAnnotation(true, false);
5740 alignPanel.alignmentChanged();
5745 protected void unGroup_actionPerformed(ActionEvent e)
5749 alignPanel.alignmentChanged();
5754 * make the given alignmentPanel the currently selected tab
5756 * @param alignmentPanel
5758 public void setDisplayedView(AlignmentPanel alignmentPanel)
5760 if (!viewport.getSequenceSetId()
5761 .equals(alignmentPanel.av.getSequenceSetId()))
5763 throw new Error(MessageManager.getString(
5764 "error.implementation_error_cannot_show_view_alignment_frame"));
5766 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5767 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5769 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5774 * Action on selection of menu options to Show or Hide annotations.
5777 * @param forSequences
5778 * update sequence-related annotations
5779 * @param forAlignment
5780 * update non-sequence-related annotations
5783 public void setAnnotationsVisibility(boolean visible,
5784 boolean forSequences, boolean forAlignment)
5786 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5787 .getAlignmentAnnotation();
5792 for (AlignmentAnnotation aa : anns)
5795 * don't display non-positional annotations on an alignment
5797 if (aa.annotations == null)
5801 boolean apply = (aa.sequenceRef == null && forAlignment)
5802 || (aa.sequenceRef != null && forSequences);
5805 aa.visible = visible;
5808 alignPanel.validateAnnotationDimensions(true);
5809 alignPanel.alignmentChanged();
5813 * Store selected annotation sort order for the view and repaint.
5816 protected void sortAnnotations_actionPerformed()
5818 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5820 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5821 alignPanel.paintAlignment(false, false);
5826 * @return alignment panels in this alignment frame
5828 public List<? extends AlignmentViewPanel> getAlignPanels()
5830 // alignPanels is never null
5831 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5836 * Open a new alignment window, with the cDNA associated with this (protein)
5837 * alignment, aligned as is the protein.
5839 protected void viewAsCdna_actionPerformed()
5841 // TODO no longer a menu action - refactor as required
5842 final AlignmentI alignment = getViewport().getAlignment();
5843 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5844 if (mappings == null)
5848 List<SequenceI> cdnaSeqs = new ArrayList<>();
5849 for (SequenceI aaSeq : alignment.getSequences())
5851 for (AlignedCodonFrame acf : mappings)
5853 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5857 * There is a cDNA mapping for this protein sequence - add to new
5858 * alignment. It will share the same dataset sequence as other mapped
5859 * cDNA (no new mappings need to be created).
5861 final Sequence newSeq = new Sequence(dnaSeq);
5862 newSeq.setDatasetSequence(dnaSeq);
5863 cdnaSeqs.add(newSeq);
5867 if (cdnaSeqs.size() == 0)
5869 // show a warning dialog no mapped cDNA
5872 AlignmentI cdna = new Alignment(
5873 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5874 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5875 AlignFrame.DEFAULT_HEIGHT);
5876 cdna.alignAs(alignment);
5877 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5879 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5880 AlignFrame.DEFAULT_HEIGHT);
5884 * Set visibility of dna/protein complement view (available when shown in a
5890 protected void showComplement_actionPerformed(boolean show)
5892 SplitContainerI sf = getSplitViewContainer();
5895 sf.setComplementVisible(this, show);
5900 * Generate the reverse (optionally complemented) of the selected sequences,
5901 * and add them to the alignment
5904 protected void showReverse_actionPerformed(boolean complement)
5906 AlignmentI al = null;
5909 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5910 al = dna.reverseCdna(complement);
5911 viewport.addAlignment(al, "");
5912 addHistoryItem(new EditCommand(
5913 MessageManager.getString("label.add_sequences"), Action.PASTE,
5914 al.getSequencesArray(), 0, al.getWidth(),
5915 viewport.getAlignment()));
5916 } catch (Exception ex)
5918 System.err.println(ex.getMessage());
5924 * Try to run a script in the Groovy console, having first ensured that this
5925 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5926 * be targeted at this alignment.
5929 protected void runGroovy_actionPerformed()
5931 Jalview.setCurrentAlignFrame(this);
5932 groovy.ui.Console console = Desktop.getGroovyConsole();
5933 if (console != null)
5937 console.runScript();
5938 } catch (Exception ex)
5940 System.err.println((ex.toString()));
5941 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5942 MessageManager.getString("label.couldnt_run_groovy_script"),
5943 MessageManager.getString("label.groovy_support_failed"),
5944 JvOptionPane.ERROR_MESSAGE);
5949 System.err.println("Can't run Groovy script as console not found");
5954 * Hides columns containing (or not containing) a specified feature, provided
5955 * that would not leave all columns hidden
5957 * @param featureType
5958 * @param columnsContaining
5961 public boolean hideFeatureColumns(String featureType,
5962 boolean columnsContaining)
5964 boolean notForHiding = avc.markColumnsContainingFeatures(
5965 columnsContaining, false, false, featureType);
5968 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5969 false, featureType))
5971 getViewport().hideSelectedColumns();
5979 protected void selectHighlightedColumns_actionPerformed(
5980 ActionEvent actionEvent)
5982 // include key modifier check in case user selects from menu
5983 avc.markHighlightedColumns(
5984 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5985 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5986 | ActionEvent.CTRL_MASK)) != 0);
5990 protected void copyHighlightedColumns_actionPerformed(
5991 ActionEvent actionEvent)
5993 avc.copyHighlightedRegionsToClipboard();
5997 * Rebuilds the Colour menu, including any user-defined colours which have
5998 * been loaded either on startup or during the session
6000 public void buildColourMenu()
6002 colourMenu.removeAll();
6004 colourMenu.add(applyToAllGroups);
6005 colourMenu.add(textColour);
6006 colourMenu.addSeparator();
6008 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6009 viewport.getAlignment(), false);
6011 colourMenu.add(annotationColour);
6012 bg.add(annotationColour);
6013 colourMenu.addSeparator();
6014 colourMenu.add(conservationMenuItem);
6015 colourMenu.add(modifyConservation);
6016 colourMenu.add(abovePIDThreshold);
6017 colourMenu.add(modifyPID);
6019 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6020 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6024 * Open a dialog (if not already open) that allows the user to select and
6025 * calculate PCA or Tree analysis
6027 protected void openTreePcaDialog()
6029 if (alignPanel.getCalculationDialog() == null)
6031 new CalculationChooser(AlignFrame.this);
6036 protected void loadVcf_actionPerformed()
6038 JalviewFileChooser chooser = new JalviewFileChooser(
6039 Cache.getProperty("LAST_DIRECTORY"));
6040 chooser.setFileView(new JalviewFileView());
6041 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6042 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6043 final AlignFrame us = this;
6044 chooser.setResponseHandler(0, () -> {
6045 String choice = chooser.getSelectedFile().getPath();
6046 Cache.setProperty("LAST_DIRECTORY", choice);
6047 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6048 new VCFLoader(choice).loadVCF(seqs, us);
6050 chooser.showOpenDialog(null);
6054 private Rectangle lastFeatureSettingsBounds = null;
6057 public void setFeatureSettingsGeometry(Rectangle bounds)
6059 lastFeatureSettingsBounds = bounds;
6063 public Rectangle getFeatureSettingsGeometry()
6065 return lastFeatureSettingsBounds;
6070 class PrintThread extends Thread
6074 public PrintThread(AlignmentPanel ap)
6079 static PageFormat pf;
6084 PrinterJob printJob = PrinterJob.getPrinterJob();
6088 printJob.setPrintable(ap, pf);
6092 printJob.setPrintable(ap);
6095 if (printJob.printDialog())
6100 } catch (Exception PrintException)
6102 PrintException.printStackTrace();