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;
1644 Desktop.closeModal(this);
1648 if (alignPanels != null)
1652 if (this.isClosed())
1654 // really close all the windows - otherwise wait till
1655 // setClosed(true) is called
1656 for (int i = 0; i < alignPanels.size(); i++)
1658 AlignmentPanel ap = alignPanels.get(i);
1665 closeView(alignPanel);
1670 if (featureSettings != null && featureSettings.isOpen())
1672 featureSettings.close();
1673 featureSettings = null;
1677 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1678 * be called recursively, with the frame now in 'closed' state
1680 this.setClosed(true);
1682 } catch (Exception ex)
1684 ex.printStackTrace();
1689 * Close the specified panel and close up tabs appropriately.
1691 * @param panelToClose
1693 public void closeView(AlignmentPanel panelToClose)
1695 int index = tabbedPane.getSelectedIndex();
1696 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1697 alignPanels.remove(panelToClose);
1698 panelToClose.closePanel();
1699 panelToClose = null;
1701 tabbedPane.removeTabAt(closedindex);
1702 tabbedPane.validate();
1704 if (index > closedindex || index == tabbedPane.getTabCount())
1706 // modify currently selected tab index if necessary.
1710 this.tabSelectionChanged(index);
1716 void updateEditMenuBar()
1719 if (viewport.getHistoryList().size() > 0)
1721 undoMenuItem.setEnabled(true);
1722 CommandI command = viewport.getHistoryList().peek();
1723 undoMenuItem.setText(MessageManager
1724 .formatMessage("label.undo_command", new Object[]
1725 { command.getDescription() }));
1729 undoMenuItem.setEnabled(false);
1730 undoMenuItem.setText(MessageManager.getString("action.undo"));
1733 if (viewport.getRedoList().size() > 0)
1735 redoMenuItem.setEnabled(true);
1737 CommandI command = viewport.getRedoList().peek();
1738 redoMenuItem.setText(MessageManager
1739 .formatMessage("label.redo_command", new Object[]
1740 { command.getDescription() }));
1744 redoMenuItem.setEnabled(false);
1745 redoMenuItem.setText(MessageManager.getString("action.redo"));
1750 public void addHistoryItem(CommandI command)
1752 if (command.getSize() > 0)
1754 viewport.addToHistoryList(command);
1755 viewport.clearRedoList();
1756 updateEditMenuBar();
1757 viewport.updateHiddenColumns();
1758 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1759 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1760 // viewport.getColumnSelection()
1761 // .getHiddenColumns().size() > 0);
1767 * @return alignment objects for all views
1769 AlignmentI[] getViewAlignments()
1771 if (alignPanels != null)
1773 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1775 for (AlignmentPanel ap : alignPanels)
1777 als[i++] = ap.av.getAlignment();
1781 if (viewport != null)
1783 return new AlignmentI[] { viewport.getAlignment() };
1795 protected void undoMenuItem_actionPerformed(ActionEvent e)
1797 if (viewport.getHistoryList().isEmpty())
1801 CommandI command = viewport.getHistoryList().pop();
1802 viewport.addToRedoList(command);
1803 command.undoCommand(getViewAlignments());
1805 AlignmentViewport originalSource = getOriginatingSource(command);
1806 updateEditMenuBar();
1808 if (originalSource != null)
1810 if (originalSource != viewport)
1813 "Implementation worry: mismatch of viewport origin for undo");
1815 originalSource.updateHiddenColumns();
1816 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1818 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1819 // viewport.getColumnSelection()
1820 // .getHiddenColumns().size() > 0);
1821 originalSource.firePropertyChange("alignment", null,
1822 originalSource.getAlignment().getSequences());
1833 protected void redoMenuItem_actionPerformed(ActionEvent e)
1835 if (viewport.getRedoList().size() < 1)
1840 CommandI command = viewport.getRedoList().pop();
1841 viewport.addToHistoryList(command);
1842 command.doCommand(getViewAlignments());
1844 AlignmentViewport originalSource = getOriginatingSource(command);
1845 updateEditMenuBar();
1847 if (originalSource != null)
1850 if (originalSource != viewport)
1853 "Implementation worry: mismatch of viewport origin for redo");
1855 originalSource.updateHiddenColumns();
1856 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1858 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1859 // viewport.getColumnSelection()
1860 // .getHiddenColumns().size() > 0);
1861 originalSource.firePropertyChange("alignment", null,
1862 originalSource.getAlignment().getSequences());
1866 AlignmentViewport getOriginatingSource(CommandI command)
1868 AlignmentViewport originalSource = null;
1869 // For sequence removal and addition, we need to fire
1870 // the property change event FROM the viewport where the
1871 // original alignment was altered
1872 AlignmentI al = null;
1873 if (command instanceof EditCommand)
1875 EditCommand editCommand = (EditCommand) command;
1876 al = editCommand.getAlignment();
1877 List<Component> comps = PaintRefresher.components
1878 .get(viewport.getSequenceSetId());
1880 for (Component comp : comps)
1882 if (comp instanceof AlignmentPanel)
1884 if (al == ((AlignmentPanel) comp).av.getAlignment())
1886 originalSource = ((AlignmentPanel) comp).av;
1893 if (originalSource == null)
1895 // The original view is closed, we must validate
1896 // the current view against the closed view first
1899 PaintRefresher.validateSequences(al, viewport.getAlignment());
1902 originalSource = viewport;
1905 return originalSource;
1909 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1910 * or the sequence under cursor in keyboard mode
1915 public void moveSelectedSequences(boolean up)
1917 SequenceGroup sg = viewport.getSelectionGroup();
1921 if (viewport.cursorMode)
1923 sg = new SequenceGroup();
1924 sg.addSequence(viewport.getAlignment().getSequenceAt(
1925 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1933 if (sg.getSize() < 1)
1938 // TODO: JAL-3733 - add an event to the undo buffer for this !
1940 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1941 viewport.getHiddenRepSequences(), up);
1942 alignPanel.paintAlignment(true, false);
1945 synchronized void slideSequences(boolean right, int size)
1947 List<SequenceI> sg = new ArrayList<>();
1948 if (viewport.cursorMode)
1950 sg.add(viewport.getAlignment()
1951 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1953 else if (viewport.getSelectionGroup() != null
1954 && viewport.getSelectionGroup().getSize() != viewport
1955 .getAlignment().getHeight())
1957 sg = viewport.getSelectionGroup()
1958 .getSequences(viewport.getHiddenRepSequences());
1966 List<SequenceI> invertGroup = new ArrayList<>();
1968 for (SequenceI seq : viewport.getAlignment().getSequences())
1970 if (!sg.contains(seq))
1972 invertGroup.add(seq);
1976 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1978 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1979 for (int i = 0; i < invertGroup.size(); i++)
1981 seqs2[i] = invertGroup.get(i);
1984 SlideSequencesCommand ssc;
1987 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1988 viewport.getGapCharacter());
1992 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1993 viewport.getGapCharacter());
1996 int groupAdjustment = 0;
1997 if (ssc.getGapsInsertedBegin() && right)
1999 if (viewport.cursorMode)
2001 alignPanel.getSeqPanel().moveCursor(size, 0);
2005 groupAdjustment = size;
2008 else if (!ssc.getGapsInsertedBegin() && !right)
2010 if (viewport.cursorMode)
2012 alignPanel.getSeqPanel().moveCursor(-size, 0);
2016 groupAdjustment = -size;
2020 if (groupAdjustment != 0)
2022 viewport.getSelectionGroup().setStartRes(
2023 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2024 viewport.getSelectionGroup().setEndRes(
2025 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2029 * just extend the last slide command if compatible; but not if in
2030 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2032 boolean appendHistoryItem = false;
2033 Deque<CommandI> historyList = viewport.getHistoryList();
2034 boolean inSplitFrame = getSplitViewContainer() != null;
2035 if (!inSplitFrame && historyList != null && historyList.size() > 0
2036 && historyList.peek() instanceof SlideSequencesCommand)
2038 appendHistoryItem = ssc.appendSlideCommand(
2039 (SlideSequencesCommand) historyList.peek());
2042 if (!appendHistoryItem)
2044 addHistoryItem(ssc);
2057 protected void copy_actionPerformed()
2059 if (viewport.getSelectionGroup() == null)
2063 // TODO: preserve the ordering of displayed alignment annotation in any
2064 // internal paste (particularly sequence associated annotation)
2065 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2066 String[] omitHidden = null;
2068 if (viewport.hasHiddenColumns())
2070 omitHidden = viewport.getViewAsString(true);
2073 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2074 seqs, omitHidden, null);
2076 StringSelection ss = new StringSelection(output);
2080 jalview.gui.Desktop.internalCopy = true;
2081 // Its really worth setting the clipboard contents
2082 // to empty before setting the large StringSelection!!
2083 Toolkit.getDefaultToolkit().getSystemClipboard()
2084 .setContents(new StringSelection(""), null);
2086 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2088 } catch (OutOfMemoryError er)
2090 new OOMWarning("copying region", er);
2094 HiddenColumns hiddenColumns = null;
2095 if (viewport.hasHiddenColumns())
2097 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2098 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2100 // create new HiddenColumns object with copy of hidden regions
2101 // between startRes and endRes, offset by startRes
2102 hiddenColumns = new HiddenColumns(
2103 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2104 hiddenCutoff, hiddenOffset);
2107 Desktop.jalviewClipboard = new Object[] { seqs,
2108 viewport.getAlignment().getDataset(), hiddenColumns };
2109 setStatus(MessageManager.formatMessage(
2110 "label.copied_sequences_to_clipboard", new Object[]
2111 { Integer.valueOf(seqs.length).toString() }));
2121 protected void pasteNew_actionPerformed(ActionEvent e)
2133 protected void pasteThis_actionPerformed(ActionEvent e)
2139 * Paste contents of Jalview clipboard
2141 * @param newAlignment
2142 * true to paste to a new alignment, otherwise add to this.
2144 void paste(boolean newAlignment)
2146 boolean externalPaste = true;
2149 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2150 Transferable contents = c.getContents(this);
2152 if (contents == null)
2161 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2162 if (str.length() < 1)
2167 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2169 } catch (OutOfMemoryError er)
2171 new OOMWarning("Out of memory pasting sequences!!", er);
2175 SequenceI[] sequences;
2176 boolean annotationAdded = false;
2177 AlignmentI alignment = null;
2179 if (Desktop.jalviewClipboard != null)
2181 // The clipboard was filled from within Jalview, we must use the
2183 // And dataset from the copied alignment
2184 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2185 // be doubly sure that we create *new* sequence objects.
2186 sequences = new SequenceI[newseq.length];
2187 for (int i = 0; i < newseq.length; i++)
2189 sequences[i] = new Sequence(newseq[i]);
2191 alignment = new Alignment(sequences);
2192 externalPaste = false;
2196 // parse the clipboard as an alignment.
2197 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2199 sequences = alignment.getSequencesArray();
2203 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2209 if (Desktop.jalviewClipboard != null)
2211 // dataset is inherited
2212 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2216 // new dataset is constructed
2217 alignment.setDataset(null);
2219 alwidth = alignment.getWidth() + 1;
2223 AlignmentI pastedal = alignment; // preserve pasted alignment object
2224 // Add pasted sequences and dataset into existing alignment.
2225 alignment = viewport.getAlignment();
2226 alwidth = alignment.getWidth() + 1;
2227 // decide if we need to import sequences from an existing dataset
2228 boolean importDs = Desktop.jalviewClipboard != null
2229 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2230 // importDs==true instructs us to copy over new dataset sequences from
2231 // an existing alignment
2232 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2234 // minimum dataset set
2236 for (int i = 0; i < sequences.length; i++)
2240 newDs.addElement(null);
2242 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2244 if (importDs && ds != null)
2246 if (!newDs.contains(ds))
2248 newDs.setElementAt(ds, i);
2249 ds = new Sequence(ds);
2250 // update with new dataset sequence
2251 sequences[i].setDatasetSequence(ds);
2255 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2260 // copy and derive new dataset sequence
2261 sequences[i] = sequences[i].deriveSequence();
2262 alignment.getDataset()
2263 .addSequence(sequences[i].getDatasetSequence());
2264 // TODO: avoid creation of duplicate dataset sequences with a
2265 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2267 alignment.addSequence(sequences[i]); // merges dataset
2271 newDs.clear(); // tidy up
2273 if (alignment.getAlignmentAnnotation() != null)
2275 for (AlignmentAnnotation alan : alignment
2276 .getAlignmentAnnotation())
2278 if (alan.graphGroup > fgroup)
2280 fgroup = alan.graphGroup;
2284 if (pastedal.getAlignmentAnnotation() != null)
2286 // Add any annotation attached to alignment.
2287 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2288 for (int i = 0; i < alann.length; i++)
2290 annotationAdded = true;
2291 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2293 AlignmentAnnotation newann = new AlignmentAnnotation(
2295 if (newann.graphGroup > -1)
2297 if (newGraphGroups.size() <= newann.graphGroup
2298 || newGraphGroups.get(newann.graphGroup) == null)
2300 for (int q = newGraphGroups
2301 .size(); q <= newann.graphGroup; q++)
2303 newGraphGroups.add(q, null);
2305 newGraphGroups.set(newann.graphGroup,
2306 Integer.valueOf(++fgroup));
2308 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2312 newann.padAnnotation(alwidth);
2313 alignment.addAnnotation(newann);
2323 addHistoryItem(new EditCommand(
2324 MessageManager.getString("label.add_sequences"),
2325 Action.PASTE, sequences, 0, alignment.getWidth(),
2328 // Add any annotations attached to sequences
2329 for (int i = 0; i < sequences.length; i++)
2331 if (sequences[i].getAnnotation() != null)
2333 AlignmentAnnotation newann;
2334 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2336 annotationAdded = true;
2337 newann = sequences[i].getAnnotation()[a];
2338 newann.adjustForAlignment();
2339 newann.padAnnotation(alwidth);
2340 if (newann.graphGroup > -1)
2342 if (newann.graphGroup > -1)
2344 if (newGraphGroups.size() <= newann.graphGroup
2345 || newGraphGroups.get(newann.graphGroup) == null)
2347 for (int q = newGraphGroups
2348 .size(); q <= newann.graphGroup; q++)
2350 newGraphGroups.add(q, null);
2352 newGraphGroups.set(newann.graphGroup,
2353 Integer.valueOf(++fgroup));
2355 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2359 // annotation was duplicated earlier
2360 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2361 // take care of contact matrix too
2362 ContactMatrixI cm = sequences[i]
2363 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2366 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2370 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2378 // propagate alignment changed.
2379 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2380 if (annotationAdded)
2382 // Duplicate sequence annotation in all views.
2383 AlignmentI[] alview = this.getViewAlignments();
2384 for (int i = 0; i < sequences.length; i++)
2386 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2391 for (int avnum = 0; avnum < alview.length; avnum++)
2393 if (alview[avnum] != alignment)
2395 // duplicate in a view other than the one with input focus
2396 int avwidth = alview[avnum].getWidth() + 1;
2397 // this relies on sann being preserved after we
2398 // modify the sequence's annotation array for each duplication
2399 for (int a = 0; a < sann.length; a++)
2401 AlignmentAnnotation newann = new AlignmentAnnotation(
2403 sequences[i].addAlignmentAnnotation(newann);
2404 newann.padAnnotation(avwidth);
2405 alview[avnum].addAnnotation(newann); // annotation was
2406 // duplicated earlier
2407 // TODO JAL-1145 graphGroups are not updated for sequence
2408 // annotation added to several views. This may cause
2410 alview[avnum].setAnnotationIndex(newann, a);
2415 buildSortByAnnotationScoresMenu();
2417 viewport.firePropertyChange("alignment", null,
2418 alignment.getSequences());
2419 if (alignPanels != null)
2421 for (AlignmentPanel ap : alignPanels)
2423 ap.validateAnnotationDimensions(false);
2428 alignPanel.validateAnnotationDimensions(false);
2434 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2436 String newtitle = new String("Copied sequences");
2438 if (Desktop.jalviewClipboard != null
2439 && Desktop.jalviewClipboard[2] != null)
2441 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2442 af.viewport.setHiddenColumns(hc);
2445 // >>>This is a fix for the moment, until a better solution is
2447 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2448 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2449 .getFeatureRenderer());
2451 // TODO: maintain provenance of an alignment, rather than just make the
2452 // title a concatenation of operations.
2455 if (title.startsWith("Copied sequences"))
2461 newtitle = newtitle.concat("- from " + title);
2466 newtitle = new String("Pasted sequences");
2469 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2474 } catch (Exception ex)
2476 ex.printStackTrace();
2477 System.out.println("Exception whilst pasting: " + ex);
2478 // could be anything being pasted in here
2484 protected void expand_newalign(ActionEvent e)
2488 AlignmentI alignment = AlignmentUtils
2489 .expandContext(getViewport().getAlignment(), -1);
2490 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2492 String newtitle = new String("Flanking alignment");
2494 if (Desktop.jalviewClipboard != null
2495 && Desktop.jalviewClipboard[2] != null)
2497 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2498 af.viewport.setHiddenColumns(hc);
2501 // >>>This is a fix for the moment, until a better solution is
2503 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2504 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2505 .getFeatureRenderer());
2507 // TODO: maintain provenance of an alignment, rather than just make the
2508 // title a concatenation of operations.
2510 if (title.startsWith("Copied sequences"))
2516 newtitle = newtitle.concat("- from " + title);
2520 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2522 } catch (Exception ex)
2524 ex.printStackTrace();
2525 System.out.println("Exception whilst pasting: " + ex);
2526 // could be anything being pasted in here
2527 } catch (OutOfMemoryError oom)
2529 new OOMWarning("Viewing flanking region of alignment", oom);
2534 * Action Cut (delete and copy) the selected region
2537 protected void cut_actionPerformed()
2539 copy_actionPerformed();
2540 delete_actionPerformed();
2544 * Performs menu option to Delete the currently selected region
2547 protected void delete_actionPerformed()
2550 SequenceGroup sg = viewport.getSelectionGroup();
2556 Runnable okAction = () -> {
2557 SequenceI[] cut = sg.getSequences()
2558 .toArray(new SequenceI[sg.getSize()]);
2560 addHistoryItem(new EditCommand(
2561 MessageManager.getString("label.cut_sequences"), Action.CUT,
2562 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2563 viewport.getAlignment()));
2565 viewport.setSelectionGroup(null);
2566 viewport.sendSelection();
2567 viewport.getAlignment().deleteGroup(sg);
2569 viewport.firePropertyChange("alignment", null,
2570 viewport.getAlignment().getSequences());
2571 if (viewport.getAlignment().getHeight() < 1)
2575 AlignFrame.this.setClosed(true);
2576 } catch (Exception ex)
2583 * If the cut affects all sequences, prompt for confirmation
2585 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2587 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2588 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2589 if (wholeHeight && wholeWidth)
2591 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2592 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2593 Object[] options = new Object[] {
2594 MessageManager.getString("action.ok"),
2595 MessageManager.getString("action.cancel") };
2596 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2597 MessageManager.getString("label.delete_all"),
2598 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2599 options, options[0]);
2606 } catch (Exception e)
2608 e.printStackTrace();
2620 protected void deleteGroups_actionPerformed(ActionEvent e)
2622 if (avc.deleteGroups())
2624 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2625 alignPanel.updateAnnotation();
2626 alignPanel.paintAlignment(true, true);
2637 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2639 SequenceGroup sg = new SequenceGroup(
2640 viewport.getAlignment().getSequences());
2642 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2643 viewport.setSelectionGroup(sg);
2644 viewport.isSelectionGroupChanged(true);
2645 viewport.sendSelection();
2646 // JAL-2034 - should delegate to
2647 // alignPanel to decide if overview needs
2649 alignPanel.paintAlignment(false, false);
2650 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2660 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2662 if (viewport.cursorMode)
2664 alignPanel.getSeqPanel().keyboardNo1 = null;
2665 alignPanel.getSeqPanel().keyboardNo2 = null;
2667 viewport.setSelectionGroup(null);
2668 viewport.getColumnSelection().clear();
2669 viewport.setSearchResults(null);
2670 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2671 // JAL-2034 - should delegate to
2672 // alignPanel to decide if overview needs
2674 alignPanel.paintAlignment(false, false);
2675 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2676 viewport.sendSelection();
2686 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2688 SequenceGroup sg = viewport.getSelectionGroup();
2692 selectAllSequenceMenuItem_actionPerformed(null);
2697 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2699 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2701 // JAL-2034 - should delegate to
2702 // alignPanel to decide if overview needs
2705 alignPanel.paintAlignment(true, false);
2706 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2707 viewport.sendSelection();
2711 public void invertColSel_actionPerformed(ActionEvent e)
2713 viewport.invertColumnSelection();
2714 alignPanel.paintAlignment(true, false);
2715 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2716 viewport.sendSelection();
2726 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2728 trimAlignment(true);
2738 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2740 trimAlignment(false);
2743 void trimAlignment(boolean trimLeft)
2745 ColumnSelection colSel = viewport.getColumnSelection();
2748 if (!colSel.isEmpty())
2752 column = colSel.getMin();
2756 column = colSel.getMax();
2760 if (viewport.getSelectionGroup() != null)
2762 seqs = viewport.getSelectionGroup()
2763 .getSequencesAsArray(viewport.getHiddenRepSequences());
2767 seqs = viewport.getAlignment().getSequencesArray();
2770 TrimRegionCommand trimRegion;
2773 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2774 column, viewport.getAlignment());
2775 viewport.getRanges().setStartRes(0);
2779 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2780 column, viewport.getAlignment());
2783 setStatus(MessageManager.formatMessage("label.removed_columns",
2785 { Integer.valueOf(trimRegion.getSize()).toString() }));
2787 addHistoryItem(trimRegion);
2789 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2791 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2792 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2794 viewport.getAlignment().deleteGroup(sg);
2798 viewport.firePropertyChange("alignment", null,
2799 viewport.getAlignment().getSequences());
2810 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2812 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2815 if (viewport.getSelectionGroup() != null)
2817 seqs = viewport.getSelectionGroup()
2818 .getSequencesAsArray(viewport.getHiddenRepSequences());
2819 start = viewport.getSelectionGroup().getStartRes();
2820 end = viewport.getSelectionGroup().getEndRes();
2824 seqs = viewport.getAlignment().getSequencesArray();
2827 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2828 "Remove Gapped Columns", seqs, start, end,
2829 viewport.getAlignment());
2831 addHistoryItem(removeGapCols);
2833 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2835 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2837 // This is to maintain viewport position on first residue
2838 // of first sequence
2839 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2840 ViewportRanges ranges = viewport.getRanges();
2841 int startRes = seq.findPosition(ranges.getStartRes());
2842 // ShiftList shifts;
2843 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2844 // edit.alColumnChanges=shifts.getInverse();
2845 // if (viewport.hasHiddenColumns)
2846 // viewport.getColumnSelection().compensateForEdits(shifts);
2847 ranges.setStartRes(seq.findIndex(startRes) - 1);
2848 viewport.firePropertyChange("alignment", null,
2849 viewport.getAlignment().getSequences());
2860 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2862 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2865 if (viewport.getSelectionGroup() != null)
2867 seqs = viewport.getSelectionGroup()
2868 .getSequencesAsArray(viewport.getHiddenRepSequences());
2869 start = viewport.getSelectionGroup().getStartRes();
2870 end = viewport.getSelectionGroup().getEndRes();
2874 seqs = viewport.getAlignment().getSequencesArray();
2877 // This is to maintain viewport position on first residue
2878 // of first sequence
2879 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2880 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2882 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2883 viewport.getAlignment()));
2885 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2887 viewport.firePropertyChange("alignment", null,
2888 viewport.getAlignment().getSequences());
2899 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2901 viewport.setPadGaps(padGapsMenuitem.isSelected());
2902 viewport.firePropertyChange("alignment", null,
2903 viewport.getAlignment().getSequences());
2907 * Opens a Finder dialog
2912 public void findMenuItem_actionPerformed(ActionEvent e)
2914 new Finder(alignPanel, false, null);
2918 * Create a new view of the current alignment.
2921 public void newView_actionPerformed(ActionEvent e)
2923 newView(null, true);
2927 * Creates and shows a new view of the current alignment.
2930 * title of newly created view; if null, one will be generated
2931 * @param copyAnnotation
2932 * if true then duplicate all annnotation, groups and settings
2933 * @return new alignment panel, already displayed.
2935 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2938 * Create a new AlignmentPanel (with its own, new Viewport)
2940 AlignmentPanel newap = new jalview.project.Jalview2XML()
2941 .copyAlignPanel(alignPanel);
2942 if (!copyAnnotation)
2945 * remove all groups and annotation except for the automatic stuff
2947 newap.av.getAlignment().deleteAllGroups();
2948 newap.av.getAlignment().deleteAllAnnotations(false);
2951 newap.av.setGatherViewsHere(false);
2953 if (viewport.getViewName() == null)
2955 viewport.setViewName(
2956 MessageManager.getString("label.view_name_original"));
2960 * Views share the same edits undo and redo stacks
2962 newap.av.setHistoryList(viewport.getHistoryList());
2963 newap.av.setRedoList(viewport.getRedoList());
2966 * copy any visualisation settings that are not saved in the project
2968 newap.av.setColourAppliesToAllGroups(
2969 viewport.getColourAppliesToAllGroups());
2972 * Views share the same mappings; need to deregister any new mappings
2973 * created by copyAlignPanel, and register the new reference to the shared
2976 newap.av.replaceMappings(viewport.getAlignment());
2979 * start up cDNA consensus (if applicable) now mappings are in place
2981 if (newap.av.initComplementConsensus())
2983 newap.refresh(true); // adjust layout of annotations
2986 newap.av.setViewName(getNewViewName(viewTitle));
2988 addAlignmentPanel(newap, true);
2989 newap.alignmentChanged();
2991 if (alignPanels.size() == 2)
2993 viewport.setGatherViewsHere(true);
2995 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
3001 * Make a new name for the view, ensuring it is unique within the current
3002 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3003 * these now use viewId. Unique view names are still desirable for usability.)
3008 protected String getNewViewName(String viewTitle)
3010 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3011 boolean addFirstIndex = false;
3012 if (viewTitle == null || viewTitle.trim().length() == 0)
3014 viewTitle = MessageManager.getString("action.view");
3015 addFirstIndex = true;
3019 index = 1;// we count from 1 if given a specific name
3021 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3023 List<Component> comps = PaintRefresher.components
3024 .get(viewport.getSequenceSetId());
3026 List<String> existingNames = getExistingViewNames(comps);
3028 while (existingNames.contains(newViewName))
3030 newViewName = viewTitle + " " + (++index);
3036 * Returns a list of distinct view names found in the given list of
3037 * components. View names are held on the viewport of an AlignmentPanel.
3042 protected List<String> getExistingViewNames(List<Component> comps)
3044 List<String> existingNames = new ArrayList<>();
3045 for (Component comp : comps)
3047 if (comp instanceof AlignmentPanel)
3049 AlignmentPanel ap = (AlignmentPanel) comp;
3050 if (!existingNames.contains(ap.av.getViewName()))
3052 existingNames.add(ap.av.getViewName());
3056 return existingNames;
3060 * Explode tabbed views into separate windows.
3063 public void expandViews_actionPerformed(ActionEvent e)
3065 Desktop.explodeViews(this);
3069 * Gather views in separate windows back into a tabbed presentation.
3072 public void gatherViews_actionPerformed(ActionEvent e)
3074 Desktop.instance.gatherViews(this);
3084 public void font_actionPerformed(ActionEvent e)
3086 new FontChooser(alignPanel);
3096 protected void seqLimit_actionPerformed(ActionEvent e)
3098 viewport.setShowJVSuffix(seqLimits.isSelected());
3100 alignPanel.getIdPanel().getIdCanvas()
3101 .setPreferredSize(alignPanel.calculateIdWidth());
3102 alignPanel.paintAlignment(true, false);
3106 public void idRightAlign_actionPerformed(ActionEvent e)
3108 viewport.setRightAlignIds(idRightAlign.isSelected());
3109 alignPanel.paintAlignment(false, false);
3113 public void centreColumnLabels_actionPerformed(ActionEvent e)
3115 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3116 alignPanel.paintAlignment(false, false);
3122 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3125 protected void followHighlight_actionPerformed()
3128 * Set the 'follow' flag on the Viewport (and scroll to position if now
3131 final boolean state = this.followHighlightMenuItem.getState();
3132 viewport.setFollowHighlight(state);
3135 alignPanel.scrollToPosition(viewport.getSearchResults());
3146 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3148 viewport.setColourText(colourTextMenuItem.isSelected());
3149 alignPanel.paintAlignment(false, false);
3159 public void wrapMenuItem_actionPerformed(ActionEvent e)
3161 scaleAbove.setVisible(wrapMenuItem.isSelected());
3162 scaleLeft.setVisible(wrapMenuItem.isSelected());
3163 scaleRight.setVisible(wrapMenuItem.isSelected());
3164 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3165 alignPanel.updateLayout();
3169 public void showAllSeqs_actionPerformed(ActionEvent e)
3171 viewport.showAllHiddenSeqs();
3175 public void showAllColumns_actionPerformed(ActionEvent e)
3177 viewport.showAllHiddenColumns();
3178 alignPanel.paintAlignment(true, true);
3179 viewport.sendSelection();
3183 public void hideSelSequences_actionPerformed(ActionEvent e)
3185 viewport.hideAllSelectedSeqs();
3189 * called by key handler and the hide all/show all menu items
3194 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3197 boolean hide = false;
3198 SequenceGroup sg = viewport.getSelectionGroup();
3199 if (!toggleSeqs && !toggleCols)
3201 // Hide everything by the current selection - this is a hack - we do the
3202 // invert and then hide
3203 // first check that there will be visible columns after the invert.
3204 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3205 && sg.getStartRes() <= sg.getEndRes()))
3207 // now invert the sequence set, if required - empty selection implies
3208 // that no hiding is required.
3211 invertSequenceMenuItem_actionPerformed(null);
3212 sg = viewport.getSelectionGroup();
3216 viewport.expandColSelection(sg, true);
3217 // finally invert the column selection and get the new sequence
3219 invertColSel_actionPerformed(null);
3226 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3228 hideSelSequences_actionPerformed(null);
3231 else if (!(toggleCols && viewport.hasSelectedColumns()))
3233 showAllSeqs_actionPerformed(null);
3239 if (viewport.hasSelectedColumns())
3241 hideSelColumns_actionPerformed(null);
3244 viewport.setSelectionGroup(sg);
3249 showAllColumns_actionPerformed(null);
3258 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3259 * event.ActionEvent)
3262 public void hideAllButSelection_actionPerformed(ActionEvent e)
3264 toggleHiddenRegions(false, false);
3265 viewport.sendSelection();
3272 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3276 public void hideAllSelection_actionPerformed(ActionEvent e)
3278 SequenceGroup sg = viewport.getSelectionGroup();
3279 viewport.expandColSelection(sg, false);
3280 viewport.hideAllSelectedSeqs();
3281 viewport.hideSelectedColumns();
3282 alignPanel.updateLayout();
3283 alignPanel.paintAlignment(true, true);
3284 viewport.sendSelection();
3291 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3295 public void showAllhidden_actionPerformed(ActionEvent e)
3297 viewport.showAllHiddenColumns();
3298 viewport.showAllHiddenSeqs();
3299 alignPanel.paintAlignment(true, true);
3300 viewport.sendSelection();
3304 public void hideSelColumns_actionPerformed(ActionEvent e)
3306 viewport.hideSelectedColumns();
3307 alignPanel.updateLayout();
3308 alignPanel.paintAlignment(true, true);
3309 viewport.sendSelection();
3313 public void hiddenMarkers_actionPerformed(ActionEvent e)
3315 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3326 protected void scaleAbove_actionPerformed(ActionEvent e)
3328 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3329 alignPanel.updateLayout();
3330 alignPanel.paintAlignment(true, false);
3340 protected void scaleLeft_actionPerformed(ActionEvent e)
3342 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3343 alignPanel.updateLayout();
3344 alignPanel.paintAlignment(true, false);
3354 protected void scaleRight_actionPerformed(ActionEvent e)
3356 viewport.setScaleRightWrapped(scaleRight.isSelected());
3357 alignPanel.updateLayout();
3358 alignPanel.paintAlignment(true, false);
3368 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3370 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3371 alignPanel.paintAlignment(false, false);
3381 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3383 viewport.setShowText(viewTextMenuItem.isSelected());
3384 alignPanel.paintAlignment(false, false);
3394 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3396 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3397 alignPanel.paintAlignment(false, false);
3400 public FeatureSettings featureSettings;
3403 public FeatureSettingsControllerI getFeatureSettingsUI()
3405 return featureSettings;
3409 public void featureSettings_actionPerformed(ActionEvent e)
3411 showFeatureSettingsUI();
3415 public FeatureSettingsControllerI showFeatureSettingsUI()
3417 if (featureSettings != null)
3419 featureSettings.closeOldSettings();
3420 featureSettings = null;
3422 if (!showSeqFeatures.isSelected())
3424 // make sure features are actually displayed
3425 showSeqFeatures.setSelected(true);
3426 showSeqFeatures_actionPerformed(null);
3428 featureSettings = new FeatureSettings(this);
3429 return featureSettings;
3433 * Set or clear 'Show Sequence Features'
3439 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3441 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3442 alignPanel.paintAlignment(true, true);
3446 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3447 * the annotations panel as a whole.
3449 * The options to show/hide all annotations should be enabled when the panel
3450 * is shown, and disabled when the panel is hidden.
3455 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3457 final boolean setVisible = annotationPanelMenuItem.isSelected();
3458 viewport.setShowAnnotation(setVisible);
3459 this.showAllSeqAnnotations.setEnabled(setVisible);
3460 this.hideAllSeqAnnotations.setEnabled(setVisible);
3461 this.showAllAlAnnotations.setEnabled(setVisible);
3462 this.hideAllAlAnnotations.setEnabled(setVisible);
3463 alignPanel.updateLayout();
3467 public void alignmentProperties()
3470 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3473 String content = MessageManager.formatMessage("label.html_content",
3475 { contents.toString() });
3478 if (Platform.isJS())
3480 JLabel textLabel = new JLabel();
3481 textLabel.setText(content);
3482 textLabel.setBackground(Color.WHITE);
3484 pane = new JPanel(new BorderLayout());
3485 ((JPanel) pane).setOpaque(true);
3486 pane.setBackground(Color.WHITE);
3487 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3496 JEditorPane editPane = new JEditorPane("text/html", "");
3497 editPane.setEditable(false);
3498 editPane.setText(content);
3502 JInternalFrame frame = new JInternalFrame();
3504 frame.getContentPane().add(new JScrollPane(pane));
3506 Desktop.addInternalFrame(frame, MessageManager
3507 .formatMessage("label.alignment_properties", new Object[]
3508 { getTitle() }), 500, 400);
3512 * Opens an Overview panel for the alignment, unless one is open already
3517 public void overviewMenuItem_actionPerformed(ActionEvent e)
3519 boolean showHiddenRegions = Cache
3520 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3521 openOverviewPanel(showHiddenRegions);
3524 public OverviewPanel openOverviewPanel(boolean showHidden)
3526 if (alignPanel.overviewPanel != null)
3528 return alignPanel.overviewPanel;
3530 JInternalFrame frame = new JInternalFrame();
3531 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3533 frame.setContentPane(overview);
3534 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3535 frame.getHeight(), true, true);
3536 frame.setFrameIcon(null);
3538 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3539 final AlignmentPanel thePanel = this.alignPanel;
3540 frame.addInternalFrameListener(
3541 new javax.swing.event.InternalFrameAdapter()
3544 public void internalFrameClosed(
3545 javax.swing.event.InternalFrameEvent evt)
3548 thePanel.setOverviewPanel(null);
3551 if (getKeyListeners().length > 0)
3553 frame.addKeyListener(getKeyListeners()[0]);
3556 alignPanel.setOverviewPanel(overview);
3557 alignPanel.setOverviewTitle(this);
3563 public void textColour_actionPerformed()
3565 new TextColourChooser().chooseColour(alignPanel, null);
3569 * public void covariationColour_actionPerformed() {
3571 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3575 public void annotationColour_actionPerformed()
3577 new AnnotationColourChooser(viewport, alignPanel);
3581 public void annotationColumn_actionPerformed(ActionEvent e)
3583 new AnnotationColumnChooser(viewport, alignPanel);
3587 * Action on the user checking or unchecking the option to apply the selected
3588 * colour scheme to all groups. If unchecked, groups may have their own
3589 * independent colour schemes.
3594 public void applyToAllGroups_actionPerformed(boolean selected)
3596 viewport.setColourAppliesToAllGroups(selected);
3600 * Action on user selecting a colour from the colour menu
3603 * the name (not the menu item label!) of the colour scheme
3606 public void changeColour_actionPerformed(String name)
3609 * 'User Defined' opens a panel to configure or load a
3610 * user-defined colour scheme
3612 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3614 new UserDefinedColours(alignPanel);
3619 * otherwise set the chosen colour scheme (or null for 'None')
3621 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3622 viewport, viewport.getAlignment(),
3623 viewport.getHiddenRepSequences());
3628 * Actions on setting or changing the alignment colour scheme
3633 public void changeColour(ColourSchemeI cs)
3635 // TODO: pull up to controller method
3636 ColourMenuHelper.setColourSelected(colourMenu, cs);
3638 viewport.setGlobalColourScheme(cs);
3640 alignPanel.paintAlignment(true, true);
3644 * Show the PID threshold slider panel
3647 protected void modifyPID_actionPerformed()
3649 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3650 alignPanel.getViewName());
3651 SliderPanel.showPIDSlider();
3655 * Show the Conservation slider panel
3658 protected void modifyConservation_actionPerformed()
3660 SliderPanel.setConservationSlider(alignPanel,
3661 viewport.getResidueShading(), alignPanel.getViewName());
3662 SliderPanel.showConservationSlider();
3666 * Action on selecting or deselecting (Colour) By Conservation
3669 public void conservationMenuItem_actionPerformed(boolean selected)
3671 modifyConservation.setEnabled(selected);
3672 viewport.setConservationSelected(selected);
3673 viewport.getResidueShading().setConservationApplied(selected);
3675 changeColour(viewport.getGlobalColourScheme());
3678 modifyConservation_actionPerformed();
3682 SliderPanel.hideConservationSlider();
3687 * Action on selecting or deselecting (Colour) Above PID Threshold
3690 public void abovePIDThreshold_actionPerformed(boolean selected)
3692 modifyPID.setEnabled(selected);
3693 viewport.setAbovePIDThreshold(selected);
3696 viewport.getResidueShading().setThreshold(0,
3697 viewport.isIgnoreGapsConsensus());
3700 changeColour(viewport.getGlobalColourScheme());
3703 modifyPID_actionPerformed();
3707 SliderPanel.hidePIDSlider();
3718 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3720 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3721 AlignmentSorter.sortByPID(viewport.getAlignment(),
3722 viewport.getAlignment().getSequenceAt(0));
3723 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3724 viewport.getAlignment()));
3725 alignPanel.paintAlignment(true, false);
3735 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3737 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3738 AlignmentSorter.sortByID(viewport.getAlignment());
3740 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3741 alignPanel.paintAlignment(true, false);
3751 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3753 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3754 AlignmentSorter.sortByLength(viewport.getAlignment());
3755 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3756 viewport.getAlignment()));
3757 alignPanel.paintAlignment(true, false);
3767 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3769 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3770 AlignmentSorter.sortByGroup(viewport.getAlignment());
3771 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3772 viewport.getAlignment()));
3774 alignPanel.paintAlignment(true, false);
3784 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3786 new RedundancyPanel(alignPanel, this);
3796 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3798 if ((viewport.getSelectionGroup() == null)
3799 || (viewport.getSelectionGroup().getSize() < 2))
3801 JvOptionPane.showInternalMessageDialog(this,
3802 MessageManager.getString(
3803 "label.you_must_select_least_two_sequences"),
3804 MessageManager.getString("label.invalid_selection"),
3805 JvOptionPane.WARNING_MESSAGE);
3809 JInternalFrame frame = new JInternalFrame();
3810 frame.setContentPane(new PairwiseAlignPanel(viewport));
3811 Desktop.addInternalFrame(frame,
3812 MessageManager.getString("action.pairwise_alignment"), 600,
3818 public void autoCalculate_actionPerformed(ActionEvent e)
3820 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3821 if (viewport.autoCalculateConsensus)
3823 viewport.firePropertyChange("alignment", null,
3824 viewport.getAlignment().getSequences());
3829 public void sortByTreeOption_actionPerformed(ActionEvent e)
3831 viewport.sortByTree = sortByTree.isSelected();
3835 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3837 viewport.followSelection = listenToViewSelections.isSelected();
3841 * Constructs a tree panel and adds it to the desktop
3844 * tree type (NJ or AV)
3846 * name of score model used to compute the tree
3848 * parameters for the distance or similarity calculation
3850 void newTreePanel(String type, String modelName,
3851 SimilarityParamsI options)
3853 String frameTitle = "";
3856 boolean onSelection = false;
3857 if (viewport.getSelectionGroup() != null
3858 && viewport.getSelectionGroup().getSize() > 0)
3860 SequenceGroup sg = viewport.getSelectionGroup();
3862 /* Decide if the selection is a column region */
3863 for (SequenceI _s : sg.getSequences())
3865 if (_s.getLength() < sg.getEndRes())
3867 JvOptionPane.showMessageDialog(Desktop.desktop,
3868 MessageManager.getString(
3869 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3870 MessageManager.getString(
3871 "label.sequences_selection_not_aligned"),
3872 JvOptionPane.WARNING_MESSAGE);
3881 if (viewport.getAlignment().getHeight() < 2)
3887 tp = new TreePanel(alignPanel, type, modelName, options);
3888 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3890 frameTitle += " from ";
3892 if (viewport.getViewName() != null)
3894 frameTitle += viewport.getViewName() + " of ";
3897 frameTitle += this.title;
3899 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3910 public void addSortByOrderMenuItem(String title,
3911 final AlignmentOrder order)
3913 final JMenuItem item = new JMenuItem(MessageManager
3914 .formatMessage("action.by_title_param", new Object[]
3917 item.addActionListener(new java.awt.event.ActionListener()
3920 public void actionPerformed(ActionEvent e)
3922 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3924 // TODO: JBPNote - have to map order entries to curent SequenceI
3926 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3928 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3929 viewport.getAlignment()));
3931 alignPanel.paintAlignment(true, false);
3937 * Add a new sort by annotation score menu item
3940 * the menu to add the option to
3942 * the label used to retrieve scores for each sequence on the
3945 public void addSortByAnnotScoreMenuItem(JMenu sort,
3946 final String scoreLabel)
3948 final JMenuItem item = new JMenuItem(scoreLabel);
3950 item.addActionListener(new java.awt.event.ActionListener()
3953 public void actionPerformed(ActionEvent e)
3955 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3956 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3957 viewport.getAlignment());// ,viewport.getSelectionGroup());
3958 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3959 viewport.getAlignment()));
3960 alignPanel.paintAlignment(true, false);
3966 * last hash for alignment's annotation array - used to minimise cost of
3969 protected int _annotationScoreVectorHash;
3972 * search the alignment and rebuild the sort by annotation score submenu the
3973 * last alignment annotation vector hash is stored to minimize cost of
3974 * rebuilding in subsequence calls.
3978 public void buildSortByAnnotationScoresMenu()
3980 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3985 if (viewport.getAlignment().getAlignmentAnnotation()
3986 .hashCode() != _annotationScoreVectorHash)
3988 sortByAnnotScore.removeAll();
3989 // almost certainly a quicker way to do this - but we keep it simple
3990 Hashtable<String, String> scoreSorts = new Hashtable<>();
3991 AlignmentAnnotation aann[];
3992 for (SequenceI sqa : viewport.getAlignment().getSequences())
3994 aann = sqa.getAnnotation();
3995 for (int i = 0; aann != null && i < aann.length; i++)
3997 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3999 scoreSorts.put(aann[i].label, aann[i].label);
4003 Enumeration<String> labels = scoreSorts.keys();
4004 while (labels.hasMoreElements())
4006 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4008 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4011 _annotationScoreVectorHash = viewport.getAlignment()
4012 .getAlignmentAnnotation().hashCode();
4017 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4018 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4019 * call. Listeners are added to remove the menu item when the treePanel is
4020 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4024 public void buildTreeSortMenu()
4026 sortByTreeMenu.removeAll();
4028 List<Component> comps = PaintRefresher.components
4029 .get(viewport.getSequenceSetId());
4030 List<TreePanel> treePanels = new ArrayList<>();
4031 for (Component comp : comps)
4033 if (comp instanceof TreePanel)
4035 treePanels.add((TreePanel) comp);
4039 if (treePanels.size() < 1)
4041 sortByTreeMenu.setVisible(false);
4045 sortByTreeMenu.setVisible(true);
4047 for (final TreePanel tp : treePanels)
4049 final JMenuItem item = new JMenuItem(tp.getTitle());
4050 item.addActionListener(new java.awt.event.ActionListener()
4053 public void actionPerformed(ActionEvent e)
4055 tp.sortByTree_actionPerformed();
4056 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4061 sortByTreeMenu.add(item);
4065 public boolean sortBy(AlignmentOrder alorder, String undoname)
4067 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4068 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4069 if (undoname != null)
4071 addHistoryItem(new OrderCommand(undoname, oldOrder,
4072 viewport.getAlignment()));
4074 alignPanel.paintAlignment(true, false);
4079 * Work out whether the whole set of sequences or just the selected set will
4080 * be submitted for multiple alignment.
4083 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4085 // Now, check we have enough sequences
4086 AlignmentView msa = null;
4088 if ((viewport.getSelectionGroup() != null)
4089 && (viewport.getSelectionGroup().getSize() > 1))
4091 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4092 // some common interface!
4094 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4095 * SequenceI[sz = seqs.getSize(false)];
4097 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4098 * seqs.getSequenceAt(i); }
4100 msa = viewport.getAlignmentView(true);
4102 else if (viewport.getSelectionGroup() != null
4103 && viewport.getSelectionGroup().getSize() == 1)
4105 int option = JvOptionPane.showConfirmDialog(this,
4106 MessageManager.getString("warn.oneseq_msainput_selection"),
4107 MessageManager.getString("label.invalid_selection"),
4108 JvOptionPane.OK_CANCEL_OPTION);
4109 if (option == JvOptionPane.OK_OPTION)
4111 msa = viewport.getAlignmentView(false);
4116 msa = viewport.getAlignmentView(false);
4122 * Decides what is submitted to a secondary structure prediction service: the
4123 * first sequence in the alignment, or in the current selection, or, if the
4124 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4125 * region or the whole alignment. (where the first sequence in the set is the
4126 * one that the prediction will be for).
4128 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4130 AlignmentView seqs = null;
4132 if ((viewport.getSelectionGroup() != null)
4133 && (viewport.getSelectionGroup().getSize() > 0))
4135 seqs = viewport.getAlignmentView(true);
4139 seqs = viewport.getAlignmentView(false);
4141 // limit sequences - JBPNote in future - could spawn multiple prediction
4143 // TODO: viewport.getAlignment().isAligned is a global state - the local
4144 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4145 if (!viewport.getAlignment().isAligned(false))
4147 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4148 // TODO: if seqs.getSequences().length>1 then should really have warned
4162 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4164 // Pick the tree file
4165 JalviewFileChooser chooser = new JalviewFileChooser(
4166 Cache.getProperty("LAST_DIRECTORY"));
4167 chooser.setFileView(new JalviewFileView());
4168 chooser.setDialogTitle(
4169 MessageManager.getString("label.select_newick_like_tree_file"));
4170 chooser.setToolTipText(
4171 MessageManager.getString("label.load_tree_file"));
4173 chooser.setResponseHandler(0, () -> {
4174 String filePath = chooser.getSelectedFile().getPath();
4175 Cache.setProperty("LAST_DIRECTORY", filePath);
4176 NewickFile fin = null;
4179 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4180 DataSourceType.FILE));
4181 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4182 } catch (Exception ex)
4184 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4185 MessageManager.getString("label.problem_reading_tree_file"),
4186 JvOptionPane.WARNING_MESSAGE);
4187 ex.printStackTrace();
4189 if (fin != null && fin.hasWarningMessage())
4191 JvOptionPane.showMessageDialog(Desktop.desktop,
4192 fin.getWarningMessage(),
4194 .getString("label.possible_problem_with_tree_file"),
4195 JvOptionPane.WARNING_MESSAGE);
4198 chooser.showOpenDialog(this);
4201 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4203 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4206 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4207 int h, int x, int y)
4209 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4213 * Add a treeviewer for the tree extracted from a Newick file object to the
4214 * current alignment view
4221 * Associated alignment input data (or null)
4230 * @return TreePanel handle
4232 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4233 AlignmentView input, int w, int h, int x, int y)
4235 TreePanel tp = null;
4241 if (nf.getTree() != null)
4243 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4249 tp.setLocation(x, y);
4252 Desktop.addInternalFrame(tp, treeTitle, w, h);
4254 } catch (Exception ex)
4256 ex.printStackTrace();
4262 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4265 int w = 400, h = 500;
4269 NewickFile fin = new NewickFile(
4270 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4271 String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree"
4272 + aa.sequenceRef != null
4273 ? (" for " + aa.sequenceRef.getDisplayId(false))
4276 showColumnWiseTree(fin, aa, title, w, h, x, y);
4277 } catch (Throwable xx)
4279 Console.error("Unexpected exception showing tree for contact matrix",
4284 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4285 String treeTitle, int w, int h, int x, int y)
4290 if (nf.getTree() == null)
4294 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4300 tp.setLocation(x, y);
4303 Desktop.addInternalFrame(tp, title, w, h);
4305 } catch (Throwable xx)
4307 Console.error("Unexpected exception showing tree for contact matrix",
4313 private boolean buildingMenu = false;
4316 * Generates menu items and listener event actions for web service clients
4319 public void BuildWebServiceMenu()
4321 while (buildingMenu)
4325 System.err.println("Waiting for building menu to finish.");
4327 } catch (Exception e)
4331 final AlignFrame me = this;
4332 buildingMenu = true;
4333 new Thread(new Runnable()
4338 final List<JMenuItem> legacyItems = new ArrayList<>();
4341 // System.err.println("Building ws menu again "
4342 // + Thread.currentThread());
4343 // TODO: add support for context dependent disabling of services based
4345 // alignment and current selection
4346 // TODO: add additional serviceHandle parameter to specify abstract
4348 // class independently of AbstractName
4349 // TODO: add in rediscovery GUI function to restart discoverer
4350 // TODO: group services by location as well as function and/or
4352 // object broker mechanism.
4353 final Vector<JMenu> wsmenu = new Vector<>();
4354 final IProgressIndicator af = me;
4357 * do not i18n these strings - they are hard-coded in class
4358 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4359 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4361 final JMenu msawsmenu = new JMenu("Alignment");
4362 final JMenu secstrmenu = new JMenu(
4363 "Secondary Structure Prediction");
4364 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4365 final JMenu analymenu = new JMenu("Analysis");
4366 final JMenu dismenu = new JMenu("Protein Disorder");
4367 // JAL-940 - only show secondary structure prediction services from
4368 // the legacy server
4369 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4371 Discoverer.services != null && (Discoverer.services.size() > 0))
4373 // TODO: refactor to allow list of AbstractName/Handler bindings to
4375 // stored or retrieved from elsewhere
4376 // No MSAWS used any more:
4377 // Vector msaws = null; // (Vector)
4378 // Discoverer.services.get("MsaWS");
4379 Vector<ServiceHandle> secstrpr = Discoverer.services
4381 if (secstrpr != null)
4383 // Add any secondary structure prediction services
4384 for (int i = 0, j = secstrpr.size(); i < j; i++)
4386 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4387 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4388 .getServiceClient(sh);
4389 int p = secstrmenu.getItemCount();
4390 impl.attachWSMenuEntry(secstrmenu, me);
4391 int q = secstrmenu.getItemCount();
4392 for (int litm = p; litm < q; litm++)
4394 legacyItems.add(secstrmenu.getItem(litm));
4400 // Add all submenus in the order they should appear on the web
4402 wsmenu.add(msawsmenu);
4403 wsmenu.add(secstrmenu);
4404 wsmenu.add(dismenu);
4405 wsmenu.add(analymenu);
4406 // No search services yet
4407 // wsmenu.add(seqsrchmenu);
4409 javax.swing.SwingUtilities.invokeLater(new Runnable()
4416 webService.removeAll();
4417 // first, add discovered services onto the webservices menu
4418 if (wsmenu.size() > 0)
4420 for (int i = 0, j = wsmenu.size(); i < j; i++)
4422 webService.add(wsmenu.get(i));
4427 webService.add(me.webServiceNoServices);
4429 // TODO: move into separate menu builder class.
4431 // logic for 2.11.1.4 is
4432 // always look to see if there is a discover. if there isn't
4433 // we can't show any Jws2 services
4434 // if there are services available, show them - regardless of
4435 // the 'show JWS2 preference'
4436 // if the discoverer is running then say so
4437 // otherwise offer to trigger discovery if 'show JWS2' is not
4439 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4440 if (jws2servs != null)
4442 if (jws2servs.hasServices())
4444 jws2servs.attachWSMenuEntry(webService, me);
4445 for (Jws2Instance sv : jws2servs.getServices())
4447 if (sv.description.toLowerCase(Locale.ROOT)
4450 for (JMenuItem jmi : legacyItems)
4452 jmi.setVisible(false);
4458 if (jws2servs.isRunning())
4460 JMenuItem tm = new JMenuItem(
4461 "Still discovering JABA Services");
4462 tm.setEnabled(false);
4465 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4467 JMenuItem enableJws2 = new JMenuItem(
4468 "Discover Web Services");
4469 enableJws2.setToolTipText(
4470 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4471 enableJws2.setEnabled(true);
4472 enableJws2.addActionListener(new ActionListener()
4476 public void actionPerformed(ActionEvent e)
4478 // start service discoverer, but ignore preference
4479 Desktop.instance.startServiceDiscovery(false,
4483 webService.add(enableJws2);
4487 build_urlServiceMenu(me.webService);
4488 build_fetchdbmenu(webService);
4489 for (JMenu item : wsmenu)
4491 if (item.getItemCount() == 0)
4493 item.setEnabled(false);
4497 item.setEnabled(true);
4500 } catch (Exception e)
4503 "Exception during web service menu building process.",
4508 } catch (Exception e)
4511 buildingMenu = false;
4518 * construct any groupURL type service menu entries.
4522 protected void build_urlServiceMenu(JMenu webService)
4524 // TODO: remove this code when 2.7 is released
4525 // DEBUG - alignmentView
4527 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4528 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4530 * @Override public void actionPerformed(ActionEvent e) {
4531 * jalview.datamodel.AlignmentView
4532 * .testSelectionViews(af.viewport.getAlignment(),
4533 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4535 * }); webService.add(testAlView);
4537 // TODO: refactor to RestClient discoverer and merge menu entries for
4538 // rest-style services with other types of analysis/calculation service
4539 // SHmmr test client - still being implemented.
4540 // DEBUG - alignmentView
4542 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4545 client.attachWSMenuEntry(
4546 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4552 * Searches the alignment sequences for xRefs and builds the Show
4553 * Cross-References menu (formerly called Show Products), with database
4554 * sources for which cross-references are found (protein sources for a
4555 * nucleotide alignment and vice versa)
4557 * @return true if Show Cross-references menu should be enabled
4559 public boolean canShowProducts()
4561 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4562 AlignmentI dataset = viewport.getAlignment().getDataset();
4564 showProducts.removeAll();
4565 final boolean dna = viewport.getAlignment().isNucleotide();
4567 if (seqs == null || seqs.length == 0)
4569 // nothing to see here.
4573 boolean showp = false;
4576 List<String> ptypes = new CrossRef(seqs, dataset)
4577 .findXrefSourcesForSequences(dna);
4579 for (final String source : ptypes)
4582 final AlignFrame af = this;
4583 JMenuItem xtype = new JMenuItem(source);
4584 xtype.addActionListener(new ActionListener()
4587 public void actionPerformed(ActionEvent e)
4589 showProductsFor(af.viewport.getSequenceSelection(), dna,
4593 showProducts.add(xtype);
4595 showProducts.setVisible(showp);
4596 showProducts.setEnabled(showp);
4597 } catch (Exception e)
4600 "canShowProducts threw an exception - please report to help@jalview.org",
4608 * Finds and displays cross-references for the selected sequences (protein
4609 * products for nucleotide sequences, dna coding sequences for peptides).
4612 * the sequences to show cross-references for
4614 * true if from a nucleotide alignment (so showing proteins)
4616 * the database to show cross-references for
4618 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4619 final String source)
4621 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4626 * Construct and display a new frame containing the translation of this
4627 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4630 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4632 AlignmentI al = null;
4635 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4637 al = dna.translateCdna(codeTable);
4638 } catch (Exception ex)
4640 Console.error("Exception during translation. Please report this !",
4642 final String msg = MessageManager.getString(
4643 "label.error_when_translating_sequences_submit_bug_report");
4644 final String errorTitle = MessageManager
4645 .getString("label.implementation_error")
4646 + MessageManager.getString("label.translation_failed");
4647 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4648 JvOptionPane.ERROR_MESSAGE);
4651 if (al == null || al.getHeight() == 0)
4653 final String msg = MessageManager.getString(
4654 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4655 final String errorTitle = MessageManager
4656 .getString("label.translation_failed");
4657 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4658 JvOptionPane.WARNING_MESSAGE);
4662 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4663 af.setFileFormat(this.currentFileFormat);
4664 final String newTitle = MessageManager
4665 .formatMessage("label.translation_of_params", new Object[]
4666 { this.getTitle(), codeTable.getId() });
4667 af.setTitle(newTitle);
4668 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4670 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4671 viewport.openSplitFrame(af, new Alignment(seqs));
4675 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4682 * Set the file format
4686 public void setFileFormat(FileFormatI format)
4688 this.currentFileFormat = format;
4692 * Try to load a features file onto the alignment.
4695 * contents or path to retrieve file or a File object
4697 * access mode of file (see jalview.io.AlignFile)
4698 * @return true if features file was parsed correctly.
4700 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4703 return avc.parseFeaturesFile(file, sourceType,
4704 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4709 public void refreshFeatureUI(boolean enableIfNecessary)
4711 // note - currently this is only still here rather than in the controller
4712 // because of the featureSettings hard reference that is yet to be
4714 if (enableIfNecessary)
4716 viewport.setShowSequenceFeatures(true);
4717 showSeqFeatures.setSelected(true);
4723 public void dragEnter(DropTargetDragEvent evt)
4728 public void dragExit(DropTargetEvent evt)
4733 public void dragOver(DropTargetDragEvent evt)
4738 public void dropActionChanged(DropTargetDragEvent evt)
4743 public void drop(DropTargetDropEvent evt)
4745 // JAL-1552 - acceptDrop required before getTransferable call for
4746 // Java's Transferable for native dnd
4747 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4748 Transferable t = evt.getTransferable();
4750 final AlignFrame thisaf = this;
4751 final List<Object> files = new ArrayList<>();
4752 List<DataSourceType> protocols = new ArrayList<>();
4756 Desktop.transferFromDropTarget(files, protocols, evt, t);
4757 } catch (Exception e)
4759 e.printStackTrace();
4763 new Thread(new Runnable()
4770 // check to see if any of these files have names matching sequences
4773 SequenceIdMatcher idm = new SequenceIdMatcher(
4774 viewport.getAlignment().getSequencesArray());
4776 * Object[] { String,SequenceI}
4778 ArrayList<Object[]> filesmatched = new ArrayList<>();
4779 ArrayList<Object> filesnotmatched = new ArrayList<>();
4780 for (int i = 0; i < files.size(); i++)
4783 Object file = files.get(i);
4784 String fileName = file.toString();
4786 DataSourceType protocol = (file instanceof File
4787 ? DataSourceType.FILE
4788 : FormatAdapter.checkProtocol(fileName));
4789 if (protocol == DataSourceType.FILE)
4792 if (file instanceof File)
4795 Platform.cacheFileData(fl);
4799 fl = new File(fileName);
4801 pdbfn = fl.getName();
4803 else if (protocol == DataSourceType.URL)
4805 URL url = new URL(fileName);
4806 pdbfn = url.getFile();
4808 if (pdbfn.length() > 0)
4810 // attempt to find a match in the alignment
4811 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4812 int l = 0, c = pdbfn.indexOf(".");
4813 while (mtch == null && c != -1)
4818 } while ((c = pdbfn.indexOf(".", l)) > l);
4821 pdbfn = pdbfn.substring(0, l);
4823 mtch = idm.findAllIdMatches(pdbfn);
4830 type = new IdentifyFile().identify(file, protocol);
4831 } catch (Exception ex)
4835 if (type != null && type.isStructureFile())
4837 filesmatched.add(new Object[] { file, protocol, mtch });
4841 // File wasn't named like one of the sequences or wasn't a PDB
4843 filesnotmatched.add(file);
4847 if (filesmatched.size() > 0)
4849 boolean autoAssociate = Cache
4850 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4853 String msg = MessageManager.formatMessage(
4854 "label.automatically_associate_structure_files_with_sequences_same_name",
4856 { Integer.valueOf(filesmatched.size())
4858 String ttl = MessageManager.getString(
4859 "label.automatically_associate_structure_files_by_name");
4860 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4861 ttl, JvOptionPane.YES_NO_OPTION);
4862 autoAssociate = choice == JvOptionPane.YES_OPTION;
4866 for (Object[] fm : filesmatched)
4868 // try and associate
4869 // TODO: may want to set a standard ID naming formalism for
4870 // associating PDB files which have no IDs.
4871 for (SequenceI toassoc : (SequenceI[]) fm[2])
4873 PDBEntry pe = new AssociatePdbFileWithSeq()
4874 .associatePdbWithSeq(fm[0].toString(),
4875 (DataSourceType) fm[1], toassoc, false,
4879 System.err.println("Associated file : "
4880 + (fm[0].toString()) + " with "
4881 + toassoc.getDisplayId(true));
4885 // TODO: do we need to update overview ? only if features are
4887 alignPanel.paintAlignment(true, false);
4893 * add declined structures as sequences
4895 for (Object[] o : filesmatched)
4897 filesnotmatched.add(o[0]);
4901 if (filesnotmatched.size() > 0)
4903 if (assocfiles > 0 && (Cache.getDefault(
4904 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4905 || JvOptionPane.showConfirmDialog(thisaf,
4906 "<html>" + MessageManager.formatMessage(
4907 "label.ignore_unmatched_dropped_files_info",
4910 filesnotmatched.size())
4913 MessageManager.getString(
4914 "label.ignore_unmatched_dropped_files"),
4915 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4919 for (Object fn : filesnotmatched)
4921 loadJalviewDataFile(fn, null, null, null);
4925 } catch (Exception ex)
4927 ex.printStackTrace();
4935 * Attempt to load a "dropped" file or URL string, by testing in turn for
4937 * <li>an Annotation file</li>
4938 * <li>a JNet file</li>
4939 * <li>a features file</li>
4940 * <li>else try to interpret as an alignment file</li>
4944 * either a filename or a URL string.
4946 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4947 FileFormatI format, SequenceI assocSeq)
4949 // BH 2018 was String file
4952 if (sourceType == null)
4954 sourceType = FormatAdapter.checkProtocol(file);
4956 // if the file isn't identified, or not positively identified as some
4957 // other filetype (PFAM is default unidentified alignment file type) then
4958 // try to parse as annotation.
4959 boolean isAnnotation = (format == null
4960 || FileFormat.Pfam.equals(format))
4961 ? new AnnotationFile().annotateAlignmentView(viewport,
4967 // first see if its a T-COFFEE score file
4968 TCoffeeScoreFile tcf = null;
4971 tcf = new TCoffeeScoreFile(file, sourceType);
4974 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4978 new TCoffeeColourScheme(viewport.getAlignment()));
4979 isAnnotation = true;
4980 setStatus(MessageManager.getString(
4981 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4985 // some problem - if no warning its probable that the ID matching
4986 // process didn't work
4987 JvOptionPane.showMessageDialog(Desktop.desktop,
4988 tcf.getWarningMessage() == null
4989 ? MessageManager.getString(
4990 "label.check_file_matches_sequence_ids_alignment")
4991 : tcf.getWarningMessage(),
4992 MessageManager.getString(
4993 "label.problem_reading_tcoffee_score_file"),
4994 JvOptionPane.WARNING_MESSAGE);
5001 } catch (Exception x)
5004 "Exception when processing data source as T-COFFEE score file",
5010 // try to see if its a JNet 'concise' style annotation file *before*
5012 // try to parse it as a features file
5015 format = new IdentifyFile().identify(file, sourceType);
5017 if (FileFormat.ScoreMatrix == format)
5019 ScoreMatrixFile sm = new ScoreMatrixFile(
5020 new FileParse(file, sourceType));
5022 // todo: i18n this message
5023 setStatus(MessageManager.formatMessage(
5024 "label.successfully_loaded_matrix",
5025 sm.getMatrixName()));
5027 else if (FileFormat.Jnet.equals(format))
5029 JPredFile predictions = new JPredFile(file, sourceType);
5030 new JnetAnnotationMaker();
5031 JnetAnnotationMaker.add_annotation(predictions,
5032 viewport.getAlignment(), 0, false);
5033 viewport.getAlignment().setupJPredAlignment();
5034 isAnnotation = true;
5036 // else if (IdentifyFile.FeaturesFile.equals(format))
5037 else if (FileFormat.Features.equals(format))
5039 if (parseFeaturesFile(file, sourceType))
5041 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5042 if (splitFrame != null)
5044 splitFrame.repaint();
5048 alignPanel.paintAlignment(true, true);
5054 new FileLoader().LoadFile(viewport, file, sourceType, format);
5061 alignPanel.adjustAnnotationHeight();
5062 viewport.updateSequenceIdColours();
5063 buildSortByAnnotationScoresMenu();
5064 alignPanel.paintAlignment(true, true);
5066 } catch (Exception ex)
5068 ex.printStackTrace();
5069 } catch (OutOfMemoryError oom)
5074 } catch (Exception x)
5079 + (sourceType != null
5080 ? (sourceType == DataSourceType.PASTE
5082 : "using " + sourceType + " from "
5086 ? "(parsing as '" + format + "' file)"
5088 oom, Desktop.desktop);
5093 * Method invoked by the ChangeListener on the tabbed pane, in other words
5094 * when a different tabbed pane is selected by the user or programmatically.
5097 public void tabSelectionChanged(int index)
5102 * update current Overview window title (if there is one)
5103 * to add view name "Original" if necessary
5105 alignPanel.setOverviewTitle(this);
5108 * switch panels and set Overview title (if there is one
5109 * because it was opened automatically)
5111 alignPanel = alignPanels.get(index);
5112 alignPanel.setOverviewTitle(this);
5114 viewport = alignPanel.av;
5115 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5116 setMenusFromViewport(viewport);
5117 if (featureSettings != null && featureSettings.isOpen()
5118 && featureSettings.fr.getViewport() != viewport)
5120 if (viewport.isShowSequenceFeatures())
5122 // refresh the featureSettings to reflect UI change
5123 showFeatureSettingsUI();
5127 // close feature settings for this view.
5128 featureSettings.close();
5135 * 'focus' any colour slider that is open to the selected viewport
5137 if (viewport.getConservationSelected())
5139 SliderPanel.setConservationSlider(alignPanel,
5140 viewport.getResidueShading(), alignPanel.getViewName());
5144 SliderPanel.hideConservationSlider();
5146 if (viewport.getAbovePIDThreshold())
5148 SliderPanel.setPIDSliderSource(alignPanel,
5149 viewport.getResidueShading(), alignPanel.getViewName());
5153 SliderPanel.hidePIDSlider();
5157 * If there is a frame linked to this one in a SplitPane, switch it to the
5158 * same view tab index. No infinite recursion of calls should happen, since
5159 * tabSelectionChanged() should not get invoked on setting the selected
5160 * index to an unchanged value. Guard against setting an invalid index
5161 * before the new view peer tab has been created.
5163 final AlignViewportI peer = viewport.getCodingComplement();
5166 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5167 .getAlignPanel().alignFrame;
5168 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5170 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5176 * On right mouse click on view tab, prompt for and set new view name.
5179 public void tabbedPane_mousePressed(MouseEvent e)
5181 if (e.isPopupTrigger())
5183 String msg = MessageManager.getString("label.enter_view_name");
5184 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5185 String reply = JvOptionPane.showInputDialog(msg, ttl);
5189 viewport.setViewName(reply);
5190 // TODO warn if reply is in getExistingViewNames()?
5191 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5196 public AlignViewport getCurrentView()
5202 * Open the dialog for regex description parsing.
5205 protected void extractScores_actionPerformed(ActionEvent e)
5207 ParseProperties pp = new jalview.analysis.ParseProperties(
5208 viewport.getAlignment());
5209 // TODO: verify regex and introduce GUI dialog for version 2.5
5210 // if (pp.getScoresFromDescription("col", "score column ",
5211 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5213 if (pp.getScoresFromDescription("description column",
5214 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5216 buildSortByAnnotationScoresMenu();
5224 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5228 protected void showDbRefs_actionPerformed(ActionEvent e)
5230 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5236 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5240 protected void showNpFeats_actionPerformed(ActionEvent e)
5242 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5246 * find the viewport amongst the tabs in this alignment frame and close that
5251 public boolean closeView(AlignViewportI av)
5255 this.closeMenuItem_actionPerformed(false);
5258 Component[] comp = tabbedPane.getComponents();
5259 for (int i = 0; comp != null && i < comp.length; i++)
5261 if (comp[i] instanceof AlignmentPanel)
5263 if (((AlignmentPanel) comp[i]).av == av)
5266 closeView((AlignmentPanel) comp[i]);
5274 protected void build_fetchdbmenu(JMenu webService)
5276 // Temporary hack - DBRef Fetcher always top level ws entry.
5277 // TODO We probably want to store a sequence database checklist in
5278 // preferences and have checkboxes.. rather than individual sources selected
5280 final JMenu rfetch = new JMenu(
5281 MessageManager.getString("action.fetch_db_references"));
5282 rfetch.setToolTipText(MessageManager.getString(
5283 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5284 webService.add(rfetch);
5286 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5287 MessageManager.getString("option.trim_retrieved_seqs"));
5288 trimrs.setToolTipText(
5289 MessageManager.getString("label.trim_retrieved_sequences"));
5291 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5292 trimrs.addActionListener(new ActionListener()
5295 public void actionPerformed(ActionEvent e)
5297 trimrs.setSelected(trimrs.isSelected());
5298 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5299 Boolean.valueOf(trimrs.isSelected()).toString());
5303 JMenuItem fetchr = new JMenuItem(
5304 MessageManager.getString("label.standard_databases"));
5305 fetchr.setToolTipText(
5306 MessageManager.getString("label.fetch_embl_uniprot"));
5307 fetchr.addActionListener(new ActionListener()
5311 public void actionPerformed(ActionEvent e)
5313 new Thread(new Runnable()
5318 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5319 .getAlignment().isNucleotide();
5320 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5321 alignPanel.av.getSequenceSelection(),
5322 alignPanel.alignFrame, null,
5323 alignPanel.alignFrame.featureSettings, isNucleotide);
5324 dbRefFetcher.addListener(new FetchFinishedListenerI()
5327 public void finished()
5330 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5331 .getFeatureSettingsModels())
5334 alignPanel.av.mergeFeaturesStyle(srcSettings);
5336 AlignFrame.this.setMenusForViewport();
5339 dbRefFetcher.fetchDBRefs(false);
5347 new Thread(new Runnable()
5352 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5353 .getSequenceFetcherSingleton();
5354 javax.swing.SwingUtilities.invokeLater(new Runnable()
5359 String[] dbclasses = sf.getNonAlignmentSources();
5360 List<DbSourceProxy> otherdb;
5361 JMenu dfetch = new JMenu();
5362 JMenu ifetch = new JMenu();
5363 JMenuItem fetchr = null;
5364 int comp = 0, icomp = 0, mcomp = 15;
5365 String mname = null;
5367 for (String dbclass : dbclasses)
5369 otherdb = sf.getSourceProxy(dbclass);
5370 // add a single entry for this class, or submenu allowing 'fetch
5372 if (otherdb == null || otherdb.size() < 1)
5378 mname = "From " + dbclass;
5380 if (otherdb.size() == 1)
5382 final DbSourceProxy[] dassource = otherdb
5383 .toArray(new DbSourceProxy[0]);
5384 DbSourceProxy src = otherdb.get(0);
5385 fetchr = new JMenuItem(src.getDbSource());
5386 fetchr.addActionListener(new ActionListener()
5390 public void actionPerformed(ActionEvent e)
5392 new Thread(new Runnable()
5398 boolean isNucleotide = alignPanel.alignFrame
5399 .getViewport().getAlignment()
5401 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5402 alignPanel.av.getSequenceSelection(),
5403 alignPanel.alignFrame, dassource,
5404 alignPanel.alignFrame.featureSettings,
5407 .addListener(new FetchFinishedListenerI()
5410 public void finished()
5412 FeatureSettingsModelI srcSettings = dassource[0]
5413 .getFeatureColourScheme();
5414 alignPanel.av.mergeFeaturesStyle(
5416 AlignFrame.this.setMenusForViewport();
5419 dbRefFetcher.fetchDBRefs(false);
5425 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5426 MessageManager.formatMessage(
5427 "label.fetch_retrieve_from", new Object[]
5428 { src.getDbName() })));
5434 final DbSourceProxy[] dassource = otherdb
5435 .toArray(new DbSourceProxy[0]);
5437 DbSourceProxy src = otherdb.get(0);
5438 fetchr = new JMenuItem(MessageManager
5439 .formatMessage("label.fetch_all_param", new Object[]
5440 { src.getDbSource() }));
5441 fetchr.addActionListener(new ActionListener()
5444 public void actionPerformed(ActionEvent e)
5446 new Thread(new Runnable()
5452 boolean isNucleotide = alignPanel.alignFrame
5453 .getViewport().getAlignment()
5455 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5456 alignPanel.av.getSequenceSelection(),
5457 alignPanel.alignFrame, dassource,
5458 alignPanel.alignFrame.featureSettings,
5461 .addListener(new FetchFinishedListenerI()
5464 public void finished()
5466 AlignFrame.this.setMenusForViewport();
5469 dbRefFetcher.fetchDBRefs(false);
5475 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5476 MessageManager.formatMessage(
5477 "label.fetch_retrieve_from_all_sources",
5479 { Integer.valueOf(otherdb.size())
5481 src.getDbSource(), src.getDbName() })));
5484 // and then build the rest of the individual menus
5485 ifetch = new JMenu(MessageManager.formatMessage(
5486 "label.source_from_db_source", new Object[]
5487 { src.getDbSource() }));
5489 String imname = null;
5491 for (DbSourceProxy sproxy : otherdb)
5493 String dbname = sproxy.getDbName();
5494 String sname = dbname.length() > 5
5495 ? dbname.substring(0, 5) + "..."
5497 String msname = dbname.length() > 10
5498 ? dbname.substring(0, 10) + "..."
5502 imname = MessageManager
5503 .formatMessage("label.from_msname", new Object[]
5506 fetchr = new JMenuItem(msname);
5507 final DbSourceProxy[] dassrc = { sproxy };
5508 fetchr.addActionListener(new ActionListener()
5512 public void actionPerformed(ActionEvent e)
5514 new Thread(new Runnable()
5520 boolean isNucleotide = alignPanel.alignFrame
5521 .getViewport().getAlignment()
5523 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5524 alignPanel.av.getSequenceSelection(),
5525 alignPanel.alignFrame, dassrc,
5526 alignPanel.alignFrame.featureSettings,
5529 .addListener(new FetchFinishedListenerI()
5532 public void finished()
5534 AlignFrame.this.setMenusForViewport();
5537 dbRefFetcher.fetchDBRefs(false);
5543 fetchr.setToolTipText(
5544 "<html>" + MessageManager.formatMessage(
5545 "label.fetch_retrieve_from", new Object[]
5549 if (++icomp >= mcomp || i == (otherdb.size()))
5551 ifetch.setText(MessageManager.formatMessage(
5552 "label.source_to_target", imname, sname));
5554 ifetch = new JMenu();
5562 if (comp >= mcomp || dbi >= (dbclasses.length))
5564 dfetch.setText(MessageManager.formatMessage(
5565 "label.source_to_target", mname, dbclass));
5567 dfetch = new JMenu();
5580 * Left justify the whole alignment.
5583 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5585 AlignmentI al = viewport.getAlignment();
5587 viewport.firePropertyChange("alignment", null, al);
5591 * Right justify the whole alignment.
5594 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5596 AlignmentI al = viewport.getAlignment();
5598 viewport.firePropertyChange("alignment", null, al);
5602 public void setShowSeqFeatures(boolean b)
5604 showSeqFeatures.setSelected(b);
5605 viewport.setShowSequenceFeatures(b);
5612 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5613 * awt.event.ActionEvent)
5616 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5618 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5619 alignPanel.paintAlignment(false, false);
5626 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5630 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5632 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5633 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5641 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5642 * .event.ActionEvent)
5645 protected void showGroupConservation_actionPerformed(ActionEvent e)
5647 viewport.setShowGroupConservation(showGroupConservation.getState());
5648 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5655 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5656 * .event.ActionEvent)
5659 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5661 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5662 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5669 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5670 * .event.ActionEvent)
5673 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5675 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5676 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5680 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5682 showSequenceLogo.setState(true);
5683 viewport.setShowSequenceLogo(true);
5684 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5685 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5689 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5691 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5698 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5699 * .event.ActionEvent)
5702 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5704 if (avc.makeGroupsFromSelection())
5706 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5707 alignPanel.updateAnnotation();
5708 alignPanel.paintAlignment(true,
5709 viewport.needToUpdateStructureViews());
5713 public void clearAlignmentSeqRep()
5715 // TODO refactor alignmentseqrep to controller
5716 if (viewport.getAlignment().hasSeqrep())
5718 viewport.getAlignment().setSeqrep(null);
5719 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5720 alignPanel.updateAnnotation();
5721 alignPanel.paintAlignment(true, true);
5726 protected void createGroup_actionPerformed(ActionEvent e)
5728 if (avc.createGroup())
5730 if (applyAutoAnnotationSettings.isSelected())
5732 alignPanel.updateAnnotation(true, false);
5734 alignPanel.alignmentChanged();
5739 protected void unGroup_actionPerformed(ActionEvent e)
5743 alignPanel.alignmentChanged();
5748 * make the given alignmentPanel the currently selected tab
5750 * @param alignmentPanel
5752 public void setDisplayedView(AlignmentPanel alignmentPanel)
5754 if (!viewport.getSequenceSetId()
5755 .equals(alignmentPanel.av.getSequenceSetId()))
5757 throw new Error(MessageManager.getString(
5758 "error.implementation_error_cannot_show_view_alignment_frame"));
5760 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5761 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5763 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5768 * Action on selection of menu options to Show or Hide annotations.
5771 * @param forSequences
5772 * update sequence-related annotations
5773 * @param forAlignment
5774 * update non-sequence-related annotations
5777 public void setAnnotationsVisibility(boolean visible,
5778 boolean forSequences, boolean forAlignment)
5780 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5781 .getAlignmentAnnotation();
5786 for (AlignmentAnnotation aa : anns)
5789 * don't display non-positional annotations on an alignment
5791 if (aa.annotations == null)
5795 boolean apply = (aa.sequenceRef == null && forAlignment)
5796 || (aa.sequenceRef != null && forSequences);
5799 aa.visible = visible;
5802 alignPanel.validateAnnotationDimensions(true);
5803 alignPanel.alignmentChanged();
5807 * Store selected annotation sort order for the view and repaint.
5810 protected void sortAnnotations_actionPerformed()
5812 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5814 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5815 alignPanel.paintAlignment(false, false);
5820 * @return alignment panels in this alignment frame
5822 public List<? extends AlignmentViewPanel> getAlignPanels()
5824 // alignPanels is never null
5825 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5830 * Open a new alignment window, with the cDNA associated with this (protein)
5831 * alignment, aligned as is the protein.
5833 protected void viewAsCdna_actionPerformed()
5835 // TODO no longer a menu action - refactor as required
5836 final AlignmentI alignment = getViewport().getAlignment();
5837 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5838 if (mappings == null)
5842 List<SequenceI> cdnaSeqs = new ArrayList<>();
5843 for (SequenceI aaSeq : alignment.getSequences())
5845 for (AlignedCodonFrame acf : mappings)
5847 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5851 * There is a cDNA mapping for this protein sequence - add to new
5852 * alignment. It will share the same dataset sequence as other mapped
5853 * cDNA (no new mappings need to be created).
5855 final Sequence newSeq = new Sequence(dnaSeq);
5856 newSeq.setDatasetSequence(dnaSeq);
5857 cdnaSeqs.add(newSeq);
5861 if (cdnaSeqs.size() == 0)
5863 // show a warning dialog no mapped cDNA
5866 AlignmentI cdna = new Alignment(
5867 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5868 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5869 AlignFrame.DEFAULT_HEIGHT);
5870 cdna.alignAs(alignment);
5871 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5873 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5874 AlignFrame.DEFAULT_HEIGHT);
5878 * Set visibility of dna/protein complement view (available when shown in a
5884 protected void showComplement_actionPerformed(boolean show)
5886 SplitContainerI sf = getSplitViewContainer();
5889 sf.setComplementVisible(this, show);
5894 * Generate the reverse (optionally complemented) of the selected sequences,
5895 * and add them to the alignment
5898 protected void showReverse_actionPerformed(boolean complement)
5900 AlignmentI al = null;
5903 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5904 al = dna.reverseCdna(complement);
5905 viewport.addAlignment(al, "");
5906 addHistoryItem(new EditCommand(
5907 MessageManager.getString("label.add_sequences"), Action.PASTE,
5908 al.getSequencesArray(), 0, al.getWidth(),
5909 viewport.getAlignment()));
5910 } catch (Exception ex)
5912 System.err.println(ex.getMessage());
5918 * Try to run a script in the Groovy console, having first ensured that this
5919 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5920 * be targeted at this alignment.
5923 protected void runGroovy_actionPerformed()
5925 Jalview.setCurrentAlignFrame(this);
5926 groovy.ui.Console console = Desktop.getGroovyConsole();
5927 if (console != null)
5931 console.runScript();
5932 } catch (Exception ex)
5934 System.err.println((ex.toString()));
5935 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5936 MessageManager.getString("label.couldnt_run_groovy_script"),
5937 MessageManager.getString("label.groovy_support_failed"),
5938 JvOptionPane.ERROR_MESSAGE);
5943 System.err.println("Can't run Groovy script as console not found");
5948 * Hides columns containing (or not containing) a specified feature, provided
5949 * that would not leave all columns hidden
5951 * @param featureType
5952 * @param columnsContaining
5955 public boolean hideFeatureColumns(String featureType,
5956 boolean columnsContaining)
5958 boolean notForHiding = avc.markColumnsContainingFeatures(
5959 columnsContaining, false, false, featureType);
5962 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5963 false, featureType))
5965 getViewport().hideSelectedColumns();
5973 protected void selectHighlightedColumns_actionPerformed(
5974 ActionEvent actionEvent)
5976 // include key modifier check in case user selects from menu
5977 avc.markHighlightedColumns(
5978 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5979 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5980 | ActionEvent.CTRL_MASK)) != 0);
5984 protected void copyHighlightedColumns_actionPerformed(
5985 ActionEvent actionEvent)
5987 avc.copyHighlightedRegionsToClipboard();
5991 * Rebuilds the Colour menu, including any user-defined colours which have
5992 * been loaded either on startup or during the session
5994 public void buildColourMenu()
5996 colourMenu.removeAll();
5998 colourMenu.add(applyToAllGroups);
5999 colourMenu.add(textColour);
6000 colourMenu.addSeparator();
6002 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6003 viewport.getAlignment(), false);
6005 colourMenu.add(annotationColour);
6006 bg.add(annotationColour);
6007 colourMenu.addSeparator();
6008 colourMenu.add(conservationMenuItem);
6009 colourMenu.add(modifyConservation);
6010 colourMenu.add(abovePIDThreshold);
6011 colourMenu.add(modifyPID);
6013 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6014 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6018 * Open a dialog (if not already open) that allows the user to select and
6019 * calculate PCA or Tree analysis
6021 protected void openTreePcaDialog()
6023 if (alignPanel.getCalculationDialog() == null)
6025 new CalculationChooser(AlignFrame.this);
6030 protected void loadVcf_actionPerformed()
6032 JalviewFileChooser chooser = new JalviewFileChooser(
6033 Cache.getProperty("LAST_DIRECTORY"));
6034 chooser.setFileView(new JalviewFileView());
6035 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6036 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6037 final AlignFrame us = this;
6038 chooser.setResponseHandler(0, () -> {
6039 String choice = chooser.getSelectedFile().getPath();
6040 Cache.setProperty("LAST_DIRECTORY", choice);
6041 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6042 new VCFLoader(choice).loadVCF(seqs, us);
6044 chooser.showOpenDialog(null);
6048 private Rectangle lastFeatureSettingsBounds = null;
6051 public void setFeatureSettingsGeometry(Rectangle bounds)
6053 lastFeatureSettingsBounds = bounds;
6057 public Rectangle getFeatureSettingsGeometry()
6059 return lastFeatureSettingsBounds;
6064 class PrintThread extends Thread
6068 public PrintThread(AlignmentPanel ap)
6073 static PageFormat pf;
6078 PrinterJob printJob = PrinterJob.getPrinterJob();
6082 printJob.setPrintable(ap, pf);
6086 printJob.setPrintable(ap);
6089 if (printJob.printDialog())
6094 } catch (Exception PrintException)
6096 PrintException.printStackTrace();