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.OutputStreamWriter;
53 import java.io.PrintWriter;
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.Deque;
58 import java.util.Enumeration;
59 import java.util.Hashtable;
60 import java.util.List;
61 import java.util.Locale;
62 import java.util.Vector;
64 import javax.swing.ButtonGroup;
65 import javax.swing.JCheckBoxMenuItem;
66 import javax.swing.JComponent;
67 import javax.swing.JEditorPane;
68 import javax.swing.JInternalFrame;
69 import javax.swing.JLabel;
70 import javax.swing.JLayeredPane;
71 import javax.swing.JMenu;
72 import javax.swing.JMenuItem;
73 import javax.swing.JPanel;
74 import javax.swing.JScrollPane;
75 import javax.swing.SwingUtilities;
77 import ext.vamsas.ServiceHandle;
78 import jalview.analysis.AlignmentSorter;
79 import jalview.analysis.AlignmentUtils;
80 import jalview.analysis.CrossRef;
81 import jalview.analysis.Dna;
82 import jalview.analysis.GeneticCodeI;
83 import jalview.analysis.ParseProperties;
84 import jalview.analysis.SequenceIdMatcher;
85 import jalview.api.AlignExportSettingsI;
86 import jalview.api.AlignViewControllerGuiI;
87 import jalview.api.AlignViewControllerI;
88 import jalview.api.AlignViewportI;
89 import jalview.api.AlignmentViewPanel;
90 import jalview.api.FeatureSettingsControllerI;
91 import jalview.api.FeatureSettingsModelI;
92 import jalview.api.SplitContainerI;
93 import jalview.api.ViewStyleI;
94 import jalview.api.analysis.SimilarityParamsI;
95 import jalview.bin.Cache;
96 import jalview.bin.Console;
97 import jalview.bin.Jalview;
98 import jalview.commands.CommandI;
99 import jalview.commands.EditCommand;
100 import jalview.commands.EditCommand.Action;
101 import jalview.commands.OrderCommand;
102 import jalview.commands.RemoveGapColCommand;
103 import jalview.commands.RemoveGapsCommand;
104 import jalview.commands.SlideSequencesCommand;
105 import jalview.commands.TrimRegionCommand;
106 import jalview.datamodel.AlignExportSettingsAdapter;
107 import jalview.datamodel.AlignedCodonFrame;
108 import jalview.datamodel.Alignment;
109 import jalview.datamodel.AlignmentAnnotation;
110 import jalview.datamodel.AlignmentExportData;
111 import jalview.datamodel.AlignmentI;
112 import jalview.datamodel.AlignmentOrder;
113 import jalview.datamodel.AlignmentView;
114 import jalview.datamodel.ColumnSelection;
115 import jalview.datamodel.ContactMatrixI;
116 import jalview.datamodel.HiddenColumns;
117 import jalview.datamodel.PDBEntry;
118 import jalview.datamodel.SeqCigar;
119 import jalview.datamodel.Sequence;
120 import jalview.datamodel.SequenceGroup;
121 import jalview.datamodel.SequenceI;
122 import jalview.gui.ColourMenuHelper.ColourChangeListener;
123 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
124 import jalview.io.AlignmentProperties;
125 import jalview.io.AnnotationFile;
126 import jalview.io.BackupFiles;
127 import jalview.io.BioJsHTMLOutput;
128 import jalview.io.DataSourceType;
129 import jalview.io.FileFormat;
130 import jalview.io.FileFormatI;
131 import jalview.io.FileFormats;
132 import jalview.io.FileLoader;
133 import jalview.io.FileParse;
134 import jalview.io.FormatAdapter;
135 import jalview.io.HtmlSvgOutput;
136 import jalview.io.IdentifyFile;
137 import jalview.io.JPredFile;
138 import jalview.io.JalviewFileChooser;
139 import jalview.io.JalviewFileView;
140 import jalview.io.JnetAnnotationMaker;
141 import jalview.io.NewickFile;
142 import jalview.io.ScoreMatrixFile;
143 import jalview.io.TCoffeeScoreFile;
144 import jalview.io.exceptions.ImageOutputException;
145 import jalview.io.vcf.VCFLoader;
146 import jalview.jbgui.GAlignFrame;
147 import jalview.project.Jalview2XML;
148 import jalview.schemes.ColourSchemeI;
149 import jalview.schemes.ColourSchemes;
150 import jalview.schemes.ResidueColourScheme;
151 import jalview.schemes.TCoffeeColourScheme;
152 import jalview.util.HttpUtils;
153 import jalview.util.ImageMaker.TYPE;
154 import jalview.util.MessageManager;
155 import jalview.util.Platform;
156 import jalview.util.imagemaker.BitmapImageSizing;
157 import jalview.viewmodel.AlignmentViewport;
158 import jalview.viewmodel.ViewportRanges;
159 import jalview.ws.DBRefFetcher;
160 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
161 import jalview.ws.jws1.Discoverer;
162 import jalview.ws.jws2.Jws2Discoverer;
163 import jalview.ws.jws2.jabaws2.Jws2Instance;
164 import jalview.ws.seqfetcher.DbSourceProxy;
170 * @version $Revision$
172 @SuppressWarnings("serial")
173 public class AlignFrame extends GAlignFrame implements DropTargetListener,
174 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
177 public static final int DEFAULT_WIDTH = 700;
179 public static final int DEFAULT_HEIGHT = 500;
182 * The currently displayed panel (selected tabbed view if more than one)
184 public AlignmentPanel alignPanel;
186 AlignViewport viewport;
188 public AlignViewControllerI avc;
190 List<AlignmentPanel> alignPanels = new ArrayList<>();
193 * Last format used to load or save alignments in this window
195 FileFormatI currentFileFormat = null;
198 * Current filename for this alignment
200 String fileName = null;
205 * Creates a new AlignFrame object with specific width and height.
211 public AlignFrame(AlignmentI al, int width, int height)
213 this(al, null, width, height);
217 * Creates a new AlignFrame object with specific width, height and
223 * @param sequenceSetId
225 public AlignFrame(AlignmentI al, int width, int height,
226 String sequenceSetId)
228 this(al, null, width, height, sequenceSetId);
232 * Creates a new AlignFrame object with specific width, height and
238 * @param sequenceSetId
241 public AlignFrame(AlignmentI al, int width, int height,
242 String sequenceSetId, String viewId)
244 this(al, null, width, height, sequenceSetId, viewId);
248 * new alignment window with hidden columns
252 * @param hiddenColumns
253 * ColumnSelection or null
255 * Width of alignment frame
259 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
262 this(al, hiddenColumns, width, height, null);
266 * Create alignment frame for al with hiddenColumns, a specific width and
267 * height, and specific sequenceId
270 * @param hiddenColumns
273 * @param sequenceSetId
276 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
277 int height, String sequenceSetId)
279 this(al, hiddenColumns, width, height, sequenceSetId, null);
283 * Create alignment frame for al with hiddenColumns, a specific width and
284 * height, and specific sequenceId
287 * @param hiddenColumns
290 * @param sequenceSetId
295 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
296 int height, String sequenceSetId, String viewId)
298 setSize(width, height);
300 if (al.getDataset() == null)
305 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
307 alignPanel = new AlignmentPanel(this, viewport);
309 addAlignmentPanel(alignPanel, true);
313 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
314 HiddenColumns hiddenColumns, int width, int height)
316 setSize(width, height);
318 if (al.getDataset() == null)
323 viewport = new AlignViewport(al, hiddenColumns);
325 if (hiddenSeqs != null && hiddenSeqs.length > 0)
327 viewport.hideSequence(hiddenSeqs);
329 alignPanel = new AlignmentPanel(this, viewport);
330 addAlignmentPanel(alignPanel, true);
335 * Make a new AlignFrame from existing alignmentPanels
342 public AlignFrame(AlignmentPanel ap)
346 addAlignmentPanel(ap, false);
351 * initalise the alignframe from the underlying viewport data and the
358 // setBackground(Color.white); // BH 2019
360 if (!Jalview.isHeadlessMode())
362 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
365 avc = new jalview.controller.AlignViewController(this, viewport,
367 if (viewport.getAlignmentConservationAnnotation() == null)
369 // BLOSUM62Colour.setEnabled(false);
370 conservationMenuItem.setEnabled(false);
371 modifyConservation.setEnabled(false);
372 // PIDColour.setEnabled(false);
373 // abovePIDThreshold.setEnabled(false);
374 // modifyPID.setEnabled(false);
377 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
379 if (sortby.equals("Id"))
381 sortIDMenuItem_actionPerformed(null);
383 else if (sortby.equals("Pairwise Identity"))
385 sortPairwiseMenuItem_actionPerformed(null);
389 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
391 setMenusFromViewport(viewport);
392 buildSortByAnnotationScoresMenu();
393 calculateTree.addActionListener(new ActionListener()
397 public void actionPerformed(ActionEvent e)
404 if (Desktop.desktop != null)
406 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
407 if (!Platform.isJS())
409 addServiceListeners();
414 if (viewport.getWrapAlignment())
416 wrapMenuItem_actionPerformed(null);
419 if (Cache.getDefault("SHOW_OVERVIEW", false))
421 this.overviewMenuItem_actionPerformed(null);
426 final List<AlignmentViewPanel> selviews = new ArrayList<>();
427 final List<AlignmentPanel> origview = new ArrayList<>();
428 final String menuLabel = MessageManager
429 .getString("label.copy_format_from");
430 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
431 new ViewSetProvider()
435 public AlignmentPanel[] getAllAlignmentPanels()
438 origview.add(alignPanel);
439 // make an array of all alignment panels except for this one
440 List<AlignmentPanel> aps = new ArrayList<>(
441 Arrays.asList(Desktop.getAlignmentPanels(null)));
442 aps.remove(AlignFrame.this.alignPanel);
443 return aps.toArray(new AlignmentPanel[aps.size()]);
445 }, selviews, new ItemListener()
449 public void itemStateChanged(ItemEvent e)
451 if (origview.size() > 0)
453 final AlignmentPanel ap = origview.get(0);
456 * Copy the ViewStyle of the selected panel to 'this one'.
457 * Don't change value of 'scaleProteinAsCdna' unless copying
460 ViewStyleI vs = selviews.get(0).getAlignViewport()
462 boolean fromSplitFrame = selviews.get(0)
463 .getAlignViewport().getCodingComplement() != null;
466 vs.setScaleProteinAsCdna(ap.getAlignViewport()
467 .getViewStyle().isScaleProteinAsCdna());
469 ap.getAlignViewport().setViewStyle(vs);
472 * Also rescale ViewStyle of SplitFrame complement if there is
473 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
474 * the whole ViewStyle (allow cDNA protein to have different
477 AlignViewportI complement = ap.getAlignViewport()
478 .getCodingComplement();
479 if (complement != null && vs.isScaleProteinAsCdna())
481 AlignFrame af = Desktop.getAlignFrameFor(complement);
482 ((SplitFrame) af.getSplitViewContainer())
484 af.setMenusForViewport();
488 ap.setSelected(true);
489 ap.alignFrame.setMenusForViewport();
494 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
495 .indexOf("devel") > -1
496 || Cache.getDefault("VERSION", "DEVELOPMENT")
497 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
499 formatMenu.add(vsel);
501 addFocusListener(new FocusAdapter()
504 public void focusGained(FocusEvent e)
506 Jalview.setCurrentAlignFrame(AlignFrame.this);
513 * Change the filename and format for the alignment, and enable the 'reload'
514 * button functionality.
521 public void setFileName(String file, FileFormatI format)
524 setFileFormat(format);
525 reload.setEnabled(true);
529 * JavaScript will have this, maybe others. More dependable than a file name
530 * and maintains a reference to the actual bytes loaded.
534 public void setFileObject(File file)
536 this.fileObject = file;
540 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
543 void addKeyListener()
545 addKeyListener(new KeyAdapter()
548 public void keyPressed(KeyEvent evt)
550 if (viewport.cursorMode
551 && ((evt.getKeyCode() >= KeyEvent.VK_0
552 && evt.getKeyCode() <= KeyEvent.VK_9)
553 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
554 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
555 && Character.isDigit(evt.getKeyChar()))
557 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
560 switch (evt.getKeyCode())
563 case 27: // escape key
564 deselectAllSequenceMenuItem_actionPerformed(null);
568 case KeyEvent.VK_DOWN:
569 if (evt.isAltDown() || !viewport.cursorMode)
571 moveSelectedSequences(false);
573 if (viewport.cursorMode)
575 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
580 if (evt.isAltDown() || !viewport.cursorMode)
582 moveSelectedSequences(true);
584 if (viewport.cursorMode)
586 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
591 case KeyEvent.VK_LEFT:
592 if (evt.isAltDown() || !viewport.cursorMode)
594 slideSequences(false,
595 alignPanel.getSeqPanel().getKeyboardNo1());
599 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
604 case KeyEvent.VK_RIGHT:
605 if (evt.isAltDown() || !viewport.cursorMode)
607 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
611 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
615 case KeyEvent.VK_SPACE:
616 if (viewport.cursorMode)
618 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
619 || evt.isShiftDown() || evt.isAltDown());
623 // case KeyEvent.VK_A:
624 // if (viewport.cursorMode)
626 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
627 // //jalview.bin.Console.outPrintln("A");
631 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
632 * jalview.bin.Console.outPrintln("closing bracket"); } break;
634 case KeyEvent.VK_DELETE:
635 case KeyEvent.VK_BACK_SPACE:
636 if (!viewport.cursorMode)
638 cut_actionPerformed();
642 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
643 || evt.isShiftDown() || evt.isAltDown());
649 if (viewport.cursorMode)
651 alignPanel.getSeqPanel().setCursorRow();
655 if (viewport.cursorMode && !evt.isControlDown())
657 alignPanel.getSeqPanel().setCursorColumn();
661 if (viewport.cursorMode)
663 alignPanel.getSeqPanel().setCursorPosition();
667 case KeyEvent.VK_ENTER:
668 case KeyEvent.VK_COMMA:
669 if (viewport.cursorMode)
671 alignPanel.getSeqPanel().setCursorRowAndColumn();
676 if (viewport.cursorMode)
678 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
682 if (viewport.cursorMode)
684 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
689 viewport.cursorMode = !viewport.cursorMode;
690 setStatus(MessageManager
691 .formatMessage("label.keyboard_editing_mode", new String[]
692 { (viewport.cursorMode ? "on" : "off") }));
693 if (viewport.cursorMode)
695 ViewportRanges ranges = viewport.getRanges();
696 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
698 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
701 alignPanel.getSeqPanel().seqCanvas.repaint();
707 Help.showHelpWindow();
708 } catch (Exception ex)
710 ex.printStackTrace();
715 boolean toggleSeqs = !evt.isControlDown();
716 boolean toggleCols = !evt.isShiftDown();
717 toggleHiddenRegions(toggleSeqs, toggleCols);
722 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
723 boolean modifyExisting = true; // always modify, don't clear
724 // evt.isShiftDown();
725 boolean invertHighlighted = evt.isAltDown();
726 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
730 case KeyEvent.VK_PAGE_UP:
731 viewport.getRanges().pageUp();
733 case KeyEvent.VK_PAGE_DOWN:
734 viewport.getRanges().pageDown();
740 public void keyReleased(KeyEvent evt)
742 switch (evt.getKeyCode())
744 case KeyEvent.VK_LEFT:
745 if (evt.isAltDown() || !viewport.cursorMode)
747 viewport.firePropertyChange("alignment", null,
748 viewport.getAlignment().getSequences());
752 case KeyEvent.VK_RIGHT:
753 if (evt.isAltDown() || !viewport.cursorMode)
755 viewport.firePropertyChange("alignment", null,
756 viewport.getAlignment().getSequences());
764 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
766 ap.alignFrame = this;
767 avc = new jalview.controller.AlignViewController(this, viewport,
772 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
774 int aSize = alignPanels.size();
776 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
778 if (aSize == 1 && ap.av.getViewName() == null)
780 this.getContentPane().add(ap, BorderLayout.CENTER);
786 setInitialTabVisible();
789 expandViews.setEnabled(true);
790 gatherViews.setEnabled(true);
791 tabbedPane.addTab(ap.av.getViewName(), ap);
793 ap.setVisible(false);
798 if (ap.av.isPadGaps())
800 ap.av.getAlignment().padGaps();
802 ap.av.updateConservation(ap);
803 ap.av.updateConsensus(ap);
804 ap.av.updateStrucConsensus(ap);
808 public void setInitialTabVisible()
810 expandViews.setEnabled(true);
811 gatherViews.setEnabled(true);
812 tabbedPane.setVisible(true);
813 AlignmentPanel first = alignPanels.get(0);
814 tabbedPane.addTab(first.av.getViewName(), first);
815 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
818 public AlignViewport getViewport()
823 /* Set up intrinsic listeners for dynamically generated GUI bits. */
824 private void addServiceListeners()
826 final java.beans.PropertyChangeListener thisListener;
827 Desktop.instance.addJalviewPropertyChangeListener("services",
828 thisListener = new java.beans.PropertyChangeListener()
831 public void propertyChange(PropertyChangeEvent evt)
833 // // jalview.bin.Console.outPrintln("Discoverer property
835 // if (evt.getPropertyName().equals("services"))
837 SwingUtilities.invokeLater(new Runnable()
843 jalview.bin.Console.errPrintln(
844 "Rebuild WS Menu for service change");
845 BuildWebServiceMenu();
852 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
855 public void internalFrameClosed(
856 javax.swing.event.InternalFrameEvent evt)
858 // jalview.bin.Console.outPrintln("deregistering discoverer listener");
859 Desktop.instance.removeJalviewPropertyChangeListener("services",
861 closeMenuItem_actionPerformed(true);
864 // Finally, build the menu once to get current service state
865 new Thread(new Runnable()
870 BuildWebServiceMenu();
876 * Configure menu items that vary according to whether the alignment is
877 * nucleotide or protein
879 public void setGUINucleotide()
881 AlignmentI al = getViewport().getAlignment();
882 boolean nucleotide = al.isNucleotide();
884 loadVcf.setVisible(nucleotide);
885 showTranslation.setVisible(nucleotide);
886 showReverse.setVisible(nucleotide);
887 showReverseComplement.setVisible(nucleotide);
888 conservationMenuItem.setEnabled(!nucleotide);
890 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
891 showGroupConservation.setEnabled(!nucleotide);
893 showComplementMenuItem
894 .setText(nucleotide ? MessageManager.getString("label.protein")
895 : MessageManager.getString("label.nucleotide"));
899 * set up menus for the current viewport. This may be called after any
900 * operation that affects the data in the current view (selection changed,
901 * etc) to update the menus to reflect the new state.
904 public void setMenusForViewport()
906 setMenusFromViewport(viewport);
910 * Need to call this method when tabs are selected for multiple views, or when
911 * loading from Jalview2XML.java
916 public void setMenusFromViewport(AlignViewport av)
918 padGapsMenuitem.setSelected(av.isPadGaps());
919 colourTextMenuItem.setSelected(av.isShowColourText());
920 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
921 modifyPID.setEnabled(abovePIDThreshold.isSelected());
922 conservationMenuItem.setSelected(av.getConservationSelected());
923 modifyConservation.setEnabled(conservationMenuItem.isSelected());
924 seqLimits.setSelected(av.getShowJVSuffix());
925 idRightAlign.setSelected(av.isRightAlignIds());
926 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
927 renderGapsMenuItem.setSelected(av.isRenderGaps());
928 wrapMenuItem.setSelected(av.getWrapAlignment());
929 scaleAbove.setVisible(av.getWrapAlignment());
930 scaleLeft.setVisible(av.getWrapAlignment());
931 scaleRight.setVisible(av.getWrapAlignment());
932 annotationPanelMenuItem.setState(av.isShowAnnotation());
934 * Show/hide annotations only enabled if annotation panel is shown
936 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
939 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
940 viewBoxesMenuItem.setSelected(av.getShowBoxes());
941 viewTextMenuItem.setSelected(av.getShowText());
942 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
943 showGroupConsensus.setSelected(av.isShowGroupConsensus());
944 showGroupConservation.setSelected(av.isShowGroupConservation());
945 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
946 showSequenceLogo.setSelected(av.isShowSequenceLogo());
947 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
949 ColourMenuHelper.setColourSelected(colourMenu,
950 av.getGlobalColourScheme());
952 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
953 hiddenMarkers.setState(av.getShowHiddenMarkers());
954 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
955 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
956 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
957 autoCalculate.setSelected(av.autoCalculateConsensus);
958 sortByTree.setSelected(av.sortByTree);
959 listenToViewSelections.setSelected(av.followSelection);
961 showProducts.setEnabled(canShowProducts());
962 setGroovyEnabled(Desktop.getGroovyConsole() != null);
968 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
972 public void setGroovyEnabled(boolean b)
974 runGroovy.setEnabled(b);
977 private IProgressIndicator progressBar;
982 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
985 public void setProgressBar(String message, long id)
987 if (!Platform.isHeadless() && progressBar != null)
988 progressBar.setProgressBar(message, id);
992 public void registerHandler(final long id,
993 final IProgressIndicatorHandler handler)
995 if (progressBar != null)
996 progressBar.registerHandler(id, handler);
1001 * @return true if any progress bars are still active
1004 public boolean operationInProgress()
1006 return progressBar == null ? false : progressBar.operationInProgress();
1010 * Sets the text of the status bar. Note that setting a null or empty value
1011 * will cause the status bar to be hidden, with possibly undesirable flicker
1012 * of the screen layout.
1015 public void setStatus(String text)
1017 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1021 * Added so Castor Mapping file can obtain Jalview Version
1023 public String getVersion()
1025 return Cache.getProperty("VERSION");
1028 public FeatureRenderer getFeatureRenderer()
1030 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1034 public void fetchSequence_actionPerformed()
1036 new SequenceFetcher(this);
1040 public void addFromFile_actionPerformed(ActionEvent e)
1042 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1046 public void reload_actionPerformed(ActionEvent e)
1048 if (fileName != null)
1050 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1051 // originating file's format
1052 // TODO: work out how to recover feature settings for correct view(s) when
1053 // file is reloaded.
1054 if (FileFormat.Jalview.equals(currentFileFormat))
1056 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1057 for (int i = 0; i < frames.length; i++)
1059 if (frames[i] instanceof AlignFrame && frames[i] != this
1060 && ((AlignFrame) frames[i]).fileName != null
1061 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1065 frames[i].setSelected(true);
1066 Desktop.instance.closeAssociatedWindows();
1067 } catch (java.beans.PropertyVetoException ex)
1073 Desktop.instance.closeAssociatedWindows();
1075 FileLoader loader = new FileLoader();
1076 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1077 ? DataSourceType.URL
1078 : DataSourceType.FILE;
1079 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1083 Rectangle bounds = this.getBounds();
1085 FileLoader loader = new FileLoader();
1087 AlignFrame newframe = null;
1089 if (fileObject == null)
1092 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1093 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1094 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1099 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1100 DataSourceType.FILE, currentFileFormat);
1103 newframe.setBounds(bounds);
1104 if (featureSettings != null && featureSettings.isShowing())
1106 final Rectangle fspos = featureSettings.frame.getBounds();
1107 // TODO: need a 'show feature settings' function that takes bounds -
1108 // need to refactor Desktop.addFrame
1109 newframe.featureSettings_actionPerformed(null);
1110 final FeatureSettings nfs = newframe.featureSettings;
1111 SwingUtilities.invokeLater(new Runnable()
1116 nfs.frame.setBounds(fspos);
1119 this.featureSettings.close();
1120 this.featureSettings = null;
1122 this.closeMenuItem_actionPerformed(true);
1128 public void addFromText_actionPerformed(ActionEvent e)
1131 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1135 public void addFromURL_actionPerformed(ActionEvent e)
1137 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1141 public void save_actionPerformed(ActionEvent e)
1143 if (fileName == null || (currentFileFormat == null)
1144 || HttpUtils.startsWithHttpOrHttps(fileName))
1146 saveAs_actionPerformed();
1150 saveAlignment(fileName, currentFileFormat);
1155 * Saves the alignment to a file with a name chosen by the user, if necessary
1156 * warning if a file would be overwritten
1159 public void saveAs_actionPerformed()
1161 String format = currentFileFormat == null ? null
1162 : currentFileFormat.getName();
1163 JalviewFileChooser chooser = JalviewFileChooser
1164 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1166 chooser.setFileView(new JalviewFileView());
1167 chooser.setDialogTitle(
1168 MessageManager.getString("label.save_alignment_to_file"));
1169 chooser.setToolTipText(MessageManager.getString("action.save"));
1171 int value = chooser.showSaveDialog(this);
1173 if (value != JalviewFileChooser.APPROVE_OPTION)
1177 currentFileFormat = chooser.getSelectedFormat();
1178 // todo is this (2005) test now obsolete - value is never null?
1179 while (currentFileFormat == null)
1181 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1183 .getString("label.select_file_format_before_saving"),
1184 MessageManager.getString("label.file_format_not_specified"),
1185 JvOptionPane.WARNING_MESSAGE);
1186 currentFileFormat = chooser.getSelectedFormat();
1187 value = chooser.showSaveDialog(this);
1188 if (value != JalviewFileChooser.APPROVE_OPTION)
1194 fileName = chooser.getSelectedFile().getPath();
1196 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1197 Cache.setProperty("LAST_DIRECTORY", fileName);
1198 saveAlignment(fileName, currentFileFormat);
1201 boolean lastSaveSuccessful = false;
1203 FileFormatI lastFormatSaved;
1205 String lastFilenameSaved;
1208 * Raise a dialog or status message for the last call to saveAlignment.
1210 * @return true if last call to saveAlignment(file, format) was successful.
1212 public boolean isSaveAlignmentSuccessful()
1215 if (!lastSaveSuccessful)
1217 if (!Platform.isHeadless())
1219 JvOptionPane.showInternalMessageDialog(this, MessageManager
1220 .formatMessage("label.couldnt_save_file", new Object[]
1221 { lastFilenameSaved }),
1222 MessageManager.getString("label.error_saving_file"),
1223 JvOptionPane.WARNING_MESSAGE);
1227 Console.error(MessageManager
1228 .formatMessage("label.couldnt_save_file", new Object[]
1229 { lastFilenameSaved }));
1235 setStatus(MessageManager.formatMessage(
1236 "label.successfully_saved_to_file_in_format", new Object[]
1237 { lastFilenameSaved, lastFormatSaved }));
1240 return lastSaveSuccessful;
1244 * Saves the alignment to the specified file path, in the specified format,
1245 * which may be an alignment format, or Jalview project format. If the
1246 * alignment has hidden regions, or the format is one capable of including
1247 * non-sequence data (features, annotations, groups), then the user may be
1248 * prompted to specify what to include in the output.
1253 public void saveAlignment(String file, FileFormatI format)
1255 saveAlignment(file, format, false, false);
1258 public void saveAlignment(String file, FileFormatI format, boolean stdout,
1259 boolean forceBackup)
1261 lastSaveSuccessful = true;
1264 lastFilenameSaved = file;
1266 lastFormatSaved = format;
1268 if (FileFormat.Jalview.equals(format))
1270 String shortName = title;
1271 if (shortName.indexOf(File.separatorChar) > -1)
1273 shortName = shortName
1274 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1276 // TODO deal with stdout=true
1277 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1280 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1281 if (lastSaveSuccessful)
1283 this.getViewport().setSavedUpToDate(true);
1286 statusBar.setText(MessageManager.formatMessage(
1287 "label.successfully_saved_to_file_in_format", new Object[]
1293 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1294 Runnable cancelAction = () -> {
1295 lastSaveSuccessful = false;
1297 Runnable outputAction = () -> {
1298 // todo defer this to inside formatSequences (or later)
1299 AlignmentExportData exportData = viewport.getAlignExportData(options);
1300 String output = new FormatAdapter(alignPanel, options)
1301 .formatSequences(format, exportData.getAlignment(),
1302 exportData.getOmitHidden(),
1303 exportData.getStartEndPostions(),
1304 viewport.getAlignment().getHiddenColumns());
1307 lastSaveSuccessful = false;
1311 // create backupfiles object and get new temp filename destination
1312 boolean doBackup = forceBackup
1313 || (BackupFiles.getEnabled() && !stdout);
1314 BackupFiles backupfiles = null;
1317 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1318 backupfiles = new BackupFiles(file);
1322 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1324 Console.trace("ALIGNFRAME setting PrintWriter");
1325 PrintWriter out = stdout
1326 ? new PrintWriter(new OutputStreamWriter(System.out))
1327 : new PrintWriter(new FileWriter(tempFilePath));
1329 if (backupfiles != null)
1331 Console.trace("ALIGNFRAME about to write to temp file "
1332 + backupfiles.getTempFilePath());
1339 Console.trace("ALIGNFRAME about to close file");
1341 Console.trace("ALIGNFRAME closed file");
1343 AlignFrame.this.setTitle(stdout ? "STDOUT" : file);
1346 statusBar.setText(MessageManager.formatMessage(
1347 "label.successfully_printed_to_stdout_in_format",
1349 { format.getName() }));
1353 statusBar.setText(MessageManager.formatMessage(
1354 "label.successfully_saved_to_file_in_format",
1356 { fileName, format.getName() }));
1358 lastSaveSuccessful = true;
1359 } catch (IOException e)
1361 lastSaveSuccessful = false;
1363 "ALIGNFRAME Something happened writing the temp file");
1364 Console.error(e.getMessage());
1365 Console.debug(Cache.getStackTraceString(e));
1366 } catch (Exception ex)
1368 lastSaveSuccessful = false;
1370 "ALIGNFRAME Something unexpected happened writing the temp file");
1371 Console.error(ex.getMessage());
1372 Console.debug(Cache.getStackTraceString(ex));
1377 backupfiles.setWriteSuccess(lastSaveSuccessful);
1378 Console.debug("ALIGNFRAME writing temp file was "
1379 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1380 // do the backup file roll and rename the temp file to actual file
1381 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1382 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1383 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1384 + (lastSaveSuccessful ? "" : "un") + "successfully");
1387 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1388 if (lastSaveSuccessful)
1390 AlignFrame.this.getViewport().setSavedUpToDate(true);
1396 * show dialog with export options if applicable; else just do it
1398 if (AlignExportOptions.isNeeded(viewport, format))
1400 AlignExportOptions choices = new AlignExportOptions(
1401 alignPanel.getAlignViewport(), format, options);
1402 choices.setResponseAction(0, outputAction);
1403 choices.setResponseAction(1, cancelAction);
1404 choices.showDialog();
1411 } catch (Exception e)
1413 // TODO Auto-generated catch block
1414 e.printStackTrace();
1420 * Outputs the alignment to textbox in the requested format, if necessary
1421 * first prompting the user for whether to include hidden regions or
1424 * @param fileFormatName
1427 protected void outputText_actionPerformed(String fileFormatName)
1429 FileFormatI fileFormat = FileFormats.getInstance()
1430 .forName(fileFormatName);
1431 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1432 Runnable outputAction = () -> {
1433 // todo defer this to inside formatSequences (or later)
1434 AlignmentExportData exportData = viewport.getAlignExportData(options);
1435 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1436 cap.setForInput(null);
1439 FileFormatI format = fileFormat;
1440 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1441 format, exportData.getAlignment(),
1442 exportData.getOmitHidden(),
1443 exportData.getStartEndPostions(),
1444 viewport.getAlignment().getHiddenColumns()));
1445 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1446 "label.alignment_output_command", new Object[]
1447 { fileFormat.getName() }), 600, 500);
1448 } catch (OutOfMemoryError oom)
1450 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1457 * show dialog with export options if applicable; else just do it
1459 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1461 AlignExportOptions choices = new AlignExportOptions(
1462 alignPanel.getAlignViewport(), fileFormat, options);
1463 choices.setResponseAction(0, outputAction);
1464 choices.showDialog();
1471 } catch (Exception e)
1473 e.printStackTrace();
1485 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1487 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1490 htmlSVG.exportHTML(null);
1491 } catch (ImageOutputException x)
1493 // report problem to console and raise dialog
1498 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1500 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1503 bjs.exportHTML(null);
1504 } catch (ImageOutputException x)
1506 // report problem to console and raise dialog
1510 public void createImageMap(File file, String image)
1514 alignPanel.makePNGImageMap(file, image);
1515 } catch (ImageOutputException x)
1517 // report problem to console and raise dialog
1522 public void createPNG_actionPerformed(ActionEvent e)
1527 } catch (ImageOutputException ioex)
1529 // raise dialog, and report via console
1534 public void createEPS_actionPerformed(ActionEvent e)
1539 } catch (ImageOutputException ioex)
1541 // raise dialog, and report via console
1547 public void createSVG_actionPerformed(ActionEvent e)
1552 } catch (ImageOutputException ioex)
1554 // raise dialog, and report via console
1560 * Creates a PNG image of the alignment and writes it to the given file. If
1561 * the file is null, the user is prompted to choose a file.
1565 public void createPNG(File f) throws ImageOutputException
1567 createPNG(f, null, BitmapImageSizing.defaultBitmapImageSizing());
1570 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1571 throws ImageOutputException
1573 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1577 * Creates an EPS image of the alignment and writes it to the given file. If
1578 * the file is null, the user is prompted to choose a file.
1582 public void createEPS(File f) throws ImageOutputException
1587 public void createEPS(File f, String renderer) throws ImageOutputException
1589 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1593 * Creates an SVG image of the alignment and writes it to the given file. If
1594 * the file is null, the user is prompted to choose a file.
1598 public void createSVG(File f) throws ImageOutputException
1603 public void createSVG(File f, String renderer) throws ImageOutputException
1605 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1609 public void pageSetup_actionPerformed(ActionEvent e)
1611 PrinterJob printJob = PrinterJob.getPrinterJob();
1612 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1622 public void printMenuItem_actionPerformed(ActionEvent e)
1624 // Putting in a thread avoids Swing painting problems
1625 PrintThread thread = new PrintThread(alignPanel);
1630 public void exportFeatures_actionPerformed(ActionEvent e)
1632 new AnnotationExporter(alignPanel).exportFeatures();
1636 public void exportAnnotations_actionPerformed(ActionEvent e)
1638 new AnnotationExporter(alignPanel).exportAnnotations();
1642 public void associatedData_actionPerformed(ActionEvent e)
1644 final JalviewFileChooser chooser = new JalviewFileChooser(
1645 Cache.getProperty("LAST_DIRECTORY"));
1646 chooser.setFileView(new JalviewFileView());
1647 String tooltip = MessageManager
1648 .getString("label.load_jalview_annotations");
1649 chooser.setDialogTitle(tooltip);
1650 chooser.setToolTipText(tooltip);
1651 chooser.setResponseHandler(0, () -> {
1652 String choice = chooser.getSelectedFile().getPath();
1653 Cache.setProperty("LAST_DIRECTORY", choice);
1654 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1657 chooser.showOpenDialog(this);
1661 * Close the current view or all views in the alignment frame. If the frame
1662 * only contains one view then the alignment will be removed from memory.
1664 * @param closeAllTabs
1667 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1669 if (alignPanels != null && alignPanels.size() < 2)
1671 closeAllTabs = true;
1674 Desktop.closeModal(this);
1678 if (alignPanels != null)
1682 if (this.isClosed())
1684 // really close all the windows - otherwise wait till
1685 // setClosed(true) is called
1686 for (int i = 0; i < alignPanels.size(); i++)
1688 AlignmentPanel ap = alignPanels.get(i);
1695 closeView(alignPanel);
1700 if (featureSettings != null && featureSettings.isOpen())
1702 featureSettings.close();
1703 featureSettings = null;
1707 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1708 * be called recursively, with the frame now in 'closed' state
1710 this.setClosed(true);
1712 } catch (Exception ex)
1714 ex.printStackTrace();
1719 * Close the specified panel and close up tabs appropriately.
1721 * @param panelToClose
1723 public void closeView(AlignmentPanel panelToClose)
1725 int index = tabbedPane.getSelectedIndex();
1726 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1727 alignPanels.remove(panelToClose);
1728 panelToClose.closePanel();
1729 panelToClose = null;
1731 tabbedPane.removeTabAt(closedindex);
1732 tabbedPane.validate();
1734 if (index > closedindex || index == tabbedPane.getTabCount())
1736 // modify currently selected tab index if necessary.
1740 this.tabSelectionChanged(index);
1746 void updateEditMenuBar()
1749 if (viewport.getHistoryList().size() > 0)
1751 undoMenuItem.setEnabled(true);
1752 CommandI command = viewport.getHistoryList().peek();
1753 undoMenuItem.setText(MessageManager
1754 .formatMessage("label.undo_command", new Object[]
1755 { command.getDescription() }));
1759 undoMenuItem.setEnabled(false);
1760 undoMenuItem.setText(MessageManager.getString("action.undo"));
1763 if (viewport.getRedoList().size() > 0)
1765 redoMenuItem.setEnabled(true);
1767 CommandI command = viewport.getRedoList().peek();
1768 redoMenuItem.setText(MessageManager
1769 .formatMessage("label.redo_command", new Object[]
1770 { command.getDescription() }));
1774 redoMenuItem.setEnabled(false);
1775 redoMenuItem.setText(MessageManager.getString("action.redo"));
1780 public void addHistoryItem(CommandI command)
1782 if (command.getSize() > 0)
1784 viewport.addToHistoryList(command);
1785 viewport.clearRedoList();
1786 updateEditMenuBar();
1787 viewport.updateHiddenColumns();
1788 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1789 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1790 // viewport.getColumnSelection()
1791 // .getHiddenColumns().size() > 0);
1797 * @return alignment objects for all views
1799 public AlignmentI[] getViewAlignments()
1801 if (alignPanels != null)
1803 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1805 for (AlignmentPanel ap : alignPanels)
1807 als[i++] = ap.av.getAlignment();
1811 if (viewport != null)
1813 return new AlignmentI[] { viewport.getAlignment() };
1825 protected void undoMenuItem_actionPerformed(ActionEvent e)
1827 if (viewport.getHistoryList().isEmpty())
1831 CommandI command = viewport.getHistoryList().pop();
1832 viewport.addToRedoList(command);
1833 command.undoCommand(getViewAlignments());
1835 AlignmentViewport originalSource = getOriginatingSource(command);
1836 updateEditMenuBar();
1838 if (originalSource != null)
1840 if (originalSource != viewport)
1843 "Implementation worry: mismatch of viewport origin for undo");
1845 originalSource.updateHiddenColumns();
1846 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1848 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1849 // viewport.getColumnSelection()
1850 // .getHiddenColumns().size() > 0);
1851 originalSource.firePropertyChange("alignment", null,
1852 originalSource.getAlignment().getSequences());
1863 protected void redoMenuItem_actionPerformed(ActionEvent e)
1865 if (viewport.getRedoList().size() < 1)
1870 CommandI command = viewport.getRedoList().pop();
1871 viewport.addToHistoryList(command);
1872 command.doCommand(getViewAlignments());
1874 AlignmentViewport originalSource = getOriginatingSource(command);
1875 updateEditMenuBar();
1877 if (originalSource != null)
1880 if (originalSource != viewport)
1883 "Implementation worry: mismatch of viewport origin for redo");
1885 originalSource.updateHiddenColumns();
1886 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1888 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1889 // viewport.getColumnSelection()
1890 // .getHiddenColumns().size() > 0);
1891 originalSource.firePropertyChange("alignment", null,
1892 originalSource.getAlignment().getSequences());
1896 AlignmentViewport getOriginatingSource(CommandI command)
1898 AlignmentViewport originalSource = null;
1899 // For sequence removal and addition, we need to fire
1900 // the property change event FROM the viewport where the
1901 // original alignment was altered
1902 AlignmentI al = null;
1903 if (command instanceof EditCommand)
1905 EditCommand editCommand = (EditCommand) command;
1906 al = editCommand.getAlignment();
1907 List<Component> comps = PaintRefresher.components
1908 .get(viewport.getSequenceSetId());
1910 for (Component comp : comps)
1912 if (comp instanceof AlignmentPanel)
1914 if (al == ((AlignmentPanel) comp).av.getAlignment())
1916 originalSource = ((AlignmentPanel) comp).av;
1923 if (originalSource == null)
1925 // The original view is closed, we must validate
1926 // the current view against the closed view first
1929 PaintRefresher.validateSequences(al, viewport.getAlignment());
1932 originalSource = viewport;
1935 return originalSource;
1939 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1940 * or the sequence under cursor in keyboard mode
1945 public void moveSelectedSequences(boolean up)
1947 SequenceGroup sg = viewport.getSelectionGroup();
1951 if (viewport.cursorMode)
1953 sg = new SequenceGroup();
1954 sg.addSequence(viewport.getAlignment().getSequenceAt(
1955 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1963 if (sg.getSize() < 1)
1968 // TODO: JAL-3733 - add an event to the undo buffer for this !
1970 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1971 viewport.getHiddenRepSequences(), up);
1972 alignPanel.paintAlignment(true, false);
1975 synchronized void slideSequences(boolean right, int size)
1977 List<SequenceI> sg = new ArrayList<>();
1978 if (viewport.cursorMode)
1980 sg.add(viewport.getAlignment()
1981 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1983 else if (viewport.getSelectionGroup() != null
1984 && viewport.getSelectionGroup().getSize() != viewport
1985 .getAlignment().getHeight())
1987 sg = viewport.getSelectionGroup()
1988 .getSequences(viewport.getHiddenRepSequences());
1996 List<SequenceI> invertGroup = new ArrayList<>();
1998 for (SequenceI seq : viewport.getAlignment().getSequences())
2000 if (!sg.contains(seq))
2002 invertGroup.add(seq);
2006 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
2008 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
2009 for (int i = 0; i < invertGroup.size(); i++)
2011 seqs2[i] = invertGroup.get(i);
2014 SlideSequencesCommand ssc;
2017 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
2018 viewport.getGapCharacter());
2022 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
2023 viewport.getGapCharacter());
2026 int groupAdjustment = 0;
2027 if (ssc.getGapsInsertedBegin() && right)
2029 if (viewport.cursorMode)
2031 alignPanel.getSeqPanel().moveCursor(size, 0);
2035 groupAdjustment = size;
2038 else if (!ssc.getGapsInsertedBegin() && !right)
2040 if (viewport.cursorMode)
2042 alignPanel.getSeqPanel().moveCursor(-size, 0);
2046 groupAdjustment = -size;
2050 if (groupAdjustment != 0)
2052 viewport.getSelectionGroup().setStartRes(
2053 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2054 viewport.getSelectionGroup().setEndRes(
2055 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2059 * just extend the last slide command if compatible; but not if in
2060 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2062 boolean appendHistoryItem = false;
2063 Deque<CommandI> historyList = viewport.getHistoryList();
2064 boolean inSplitFrame = getSplitViewContainer() != null;
2065 if (!inSplitFrame && historyList != null && historyList.size() > 0
2066 && historyList.peek() instanceof SlideSequencesCommand)
2068 appendHistoryItem = ssc.appendSlideCommand(
2069 (SlideSequencesCommand) historyList.peek());
2072 if (!appendHistoryItem)
2074 addHistoryItem(ssc);
2087 protected void copy_actionPerformed()
2089 if (viewport.getSelectionGroup() == null)
2093 // TODO: preserve the ordering of displayed alignment annotation in any
2094 // internal paste (particularly sequence associated annotation)
2095 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2096 String[] omitHidden = null;
2098 if (viewport.hasHiddenColumns())
2100 omitHidden = viewport.getViewAsString(true);
2103 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2104 seqs, omitHidden, null);
2106 StringSelection ss = new StringSelection(output);
2110 jalview.gui.Desktop.internalCopy = true;
2111 // Its really worth setting the clipboard contents
2112 // to empty before setting the large StringSelection!!
2113 Toolkit.getDefaultToolkit().getSystemClipboard()
2114 .setContents(new StringSelection(""), null);
2116 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2118 } catch (OutOfMemoryError er)
2120 new OOMWarning("copying region", er);
2124 HiddenColumns hiddenColumns = null;
2125 if (viewport.hasHiddenColumns())
2127 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2128 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2130 // create new HiddenColumns object with copy of hidden regions
2131 // between startRes and endRes, offset by startRes
2132 hiddenColumns = new HiddenColumns(
2133 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2134 hiddenCutoff, hiddenOffset);
2137 Desktop.jalviewClipboard = new Object[] { seqs,
2138 viewport.getAlignment().getDataset(), hiddenColumns };
2139 setStatus(MessageManager.formatMessage(
2140 "label.copied_sequences_to_clipboard", new Object[]
2141 { Integer.valueOf(seqs.length).toString() }));
2151 protected void pasteNew_actionPerformed(ActionEvent e)
2163 protected void pasteThis_actionPerformed(ActionEvent e)
2169 * Paste contents of Jalview clipboard
2171 * @param newAlignment
2172 * true to paste to a new alignment, otherwise add to this.
2174 void paste(boolean newAlignment)
2176 boolean externalPaste = true;
2179 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2180 Transferable contents = c.getContents(this);
2182 if (contents == null)
2191 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2192 if (str.length() < 1)
2197 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2199 } catch (OutOfMemoryError er)
2201 new OOMWarning("Out of memory pasting sequences!!", er);
2205 SequenceI[] sequences;
2206 boolean annotationAdded = false;
2207 AlignmentI alignment = null;
2209 if (Desktop.jalviewClipboard != null)
2211 // The clipboard was filled from within Jalview, we must use the
2213 // And dataset from the copied alignment
2214 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2215 // be doubly sure that we create *new* sequence objects.
2216 sequences = new SequenceI[newseq.length];
2217 for (int i = 0; i < newseq.length; i++)
2219 sequences[i] = new Sequence(newseq[i]);
2221 alignment = new Alignment(sequences);
2222 externalPaste = false;
2226 // parse the clipboard as an alignment.
2227 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2229 sequences = alignment.getSequencesArray();
2233 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2239 if (Desktop.jalviewClipboard != null)
2241 // dataset is inherited
2242 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2246 // new dataset is constructed
2247 alignment.setDataset(null);
2249 alwidth = alignment.getWidth() + 1;
2253 AlignmentI pastedal = alignment; // preserve pasted alignment object
2254 // Add pasted sequences and dataset into existing alignment.
2255 alignment = viewport.getAlignment();
2256 alwidth = alignment.getWidth() + 1;
2257 // decide if we need to import sequences from an existing dataset
2258 boolean importDs = Desktop.jalviewClipboard != null
2259 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2260 // importDs==true instructs us to copy over new dataset sequences from
2261 // an existing alignment
2262 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2264 // minimum dataset set
2266 for (int i = 0; i < sequences.length; i++)
2270 newDs.addElement(null);
2272 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2274 if (importDs && ds != null)
2276 if (!newDs.contains(ds))
2278 newDs.setElementAt(ds, i);
2279 ds = new Sequence(ds);
2280 // update with new dataset sequence
2281 sequences[i].setDatasetSequence(ds);
2285 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2290 // copy and derive new dataset sequence
2291 sequences[i] = sequences[i].deriveSequence();
2292 alignment.getDataset()
2293 .addSequence(sequences[i].getDatasetSequence());
2294 // TODO: avoid creation of duplicate dataset sequences with a
2295 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2297 alignment.addSequence(sequences[i]); // merges dataset
2301 newDs.clear(); // tidy up
2303 if (alignment.getAlignmentAnnotation() != null)
2305 for (AlignmentAnnotation alan : alignment
2306 .getAlignmentAnnotation())
2308 if (alan.graphGroup > fgroup)
2310 fgroup = alan.graphGroup;
2314 if (pastedal.getAlignmentAnnotation() != null)
2316 // Add any annotation attached to alignment.
2317 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2318 for (int i = 0; i < alann.length; i++)
2320 annotationAdded = true;
2321 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2323 AlignmentAnnotation newann = new AlignmentAnnotation(
2325 if (newann.graphGroup > -1)
2327 if (newGraphGroups.size() <= newann.graphGroup
2328 || newGraphGroups.get(newann.graphGroup) == null)
2330 for (int q = newGraphGroups
2331 .size(); q <= newann.graphGroup; q++)
2333 newGraphGroups.add(q, null);
2335 newGraphGroups.set(newann.graphGroup,
2336 Integer.valueOf(++fgroup));
2338 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2342 newann.padAnnotation(alwidth);
2343 alignment.addAnnotation(newann);
2353 addHistoryItem(new EditCommand(
2354 MessageManager.getString("label.add_sequences"),
2355 Action.PASTE, sequences, 0, alignment.getWidth(),
2358 // Add any annotations attached to sequences
2359 for (int i = 0; i < sequences.length; i++)
2361 if (sequences[i].getAnnotation() != null)
2363 AlignmentAnnotation newann;
2364 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2366 annotationAdded = true;
2367 newann = sequences[i].getAnnotation()[a];
2368 newann.adjustForAlignment();
2369 newann.padAnnotation(alwidth);
2370 if (newann.graphGroup > -1)
2372 if (newann.graphGroup > -1)
2374 if (newGraphGroups.size() <= newann.graphGroup
2375 || newGraphGroups.get(newann.graphGroup) == null)
2377 for (int q = newGraphGroups
2378 .size(); q <= newann.graphGroup; q++)
2380 newGraphGroups.add(q, null);
2382 newGraphGroups.set(newann.graphGroup,
2383 Integer.valueOf(++fgroup));
2385 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2389 // annotation was duplicated earlier
2390 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2391 // take care of contact matrix too
2392 ContactMatrixI cm = sequences[i]
2393 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2396 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2400 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2408 // propagate alignment changed.
2409 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2410 if (annotationAdded)
2412 // Duplicate sequence annotation in all views.
2413 AlignmentI[] alview = this.getViewAlignments();
2414 for (int i = 0; i < sequences.length; i++)
2416 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2421 for (int avnum = 0; avnum < alview.length; avnum++)
2423 if (alview[avnum] != alignment)
2425 // duplicate in a view other than the one with input focus
2426 int avwidth = alview[avnum].getWidth() + 1;
2427 // this relies on sann being preserved after we
2428 // modify the sequence's annotation array for each duplication
2429 for (int a = 0; a < sann.length; a++)
2431 AlignmentAnnotation newann = new AlignmentAnnotation(
2433 sequences[i].addAlignmentAnnotation(newann);
2434 newann.padAnnotation(avwidth);
2435 alview[avnum].addAnnotation(newann); // annotation was
2436 // duplicated earlier
2437 // TODO JAL-1145 graphGroups are not updated for sequence
2438 // annotation added to several views. This may cause
2440 alview[avnum].setAnnotationIndex(newann, a);
2445 buildSortByAnnotationScoresMenu();
2447 viewport.firePropertyChange("alignment", null,
2448 alignment.getSequences());
2449 if (alignPanels != null)
2451 for (AlignmentPanel ap : alignPanels)
2453 ap.validateAnnotationDimensions(false);
2458 alignPanel.validateAnnotationDimensions(false);
2464 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2466 String newtitle = new String("Copied sequences");
2468 if (Desktop.jalviewClipboard != null
2469 && Desktop.jalviewClipboard[2] != null)
2471 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2472 af.viewport.setHiddenColumns(hc);
2475 // >>>This is a fix for the moment, until a better solution is
2477 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2478 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2479 .getFeatureRenderer());
2481 // TODO: maintain provenance of an alignment, rather than just make the
2482 // title a concatenation of operations.
2485 if (title.startsWith("Copied sequences"))
2491 newtitle = newtitle.concat("- from " + title);
2496 newtitle = new String("Pasted sequences");
2499 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2504 } catch (Exception ex)
2506 ex.printStackTrace();
2507 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2508 // could be anything being pasted in here
2514 protected void expand_newalign(ActionEvent e)
2518 AlignmentI alignment = AlignmentUtils
2519 .expandContext(getViewport().getAlignment(), -1);
2520 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2522 String newtitle = new String("Flanking alignment");
2524 if (Desktop.jalviewClipboard != null
2525 && Desktop.jalviewClipboard[2] != null)
2527 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2528 af.viewport.setHiddenColumns(hc);
2531 // >>>This is a fix for the moment, until a better solution is
2533 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2534 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2535 .getFeatureRenderer());
2537 // TODO: maintain provenance of an alignment, rather than just make the
2538 // title a concatenation of operations.
2540 if (title.startsWith("Copied sequences"))
2546 newtitle = newtitle.concat("- from " + title);
2550 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2552 } catch (Exception ex)
2554 ex.printStackTrace();
2555 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2556 // could be anything being pasted in here
2557 } catch (OutOfMemoryError oom)
2559 new OOMWarning("Viewing flanking region of alignment", oom);
2564 * Action Cut (delete and copy) the selected region
2567 protected void cut_actionPerformed()
2569 copy_actionPerformed();
2570 delete_actionPerformed();
2574 * Performs menu option to Delete the currently selected region
2577 protected void delete_actionPerformed()
2580 SequenceGroup sg = viewport.getSelectionGroup();
2586 Runnable okAction = () -> {
2587 SequenceI[] cut = sg.getSequences()
2588 .toArray(new SequenceI[sg.getSize()]);
2590 addHistoryItem(new EditCommand(
2591 MessageManager.getString("label.cut_sequences"), Action.CUT,
2592 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2593 viewport.getAlignment()));
2595 viewport.setSelectionGroup(null);
2596 viewport.sendSelection();
2597 viewport.getAlignment().deleteGroup(sg);
2599 viewport.firePropertyChange("alignment", null,
2600 viewport.getAlignment().getSequences());
2601 if (viewport.getAlignment().getHeight() < 1)
2605 AlignFrame.this.setClosed(true);
2606 } catch (Exception ex)
2613 * If the cut affects all sequences, prompt for confirmation
2615 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2617 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2618 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2619 if (wholeHeight && wholeWidth)
2621 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2622 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2623 Object[] options = new Object[] {
2624 MessageManager.getString("action.ok"),
2625 MessageManager.getString("action.cancel") };
2626 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2627 MessageManager.getString("label.delete_all"),
2628 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2629 options, options[0]);
2636 } catch (Exception e)
2638 e.printStackTrace();
2650 protected void deleteGroups_actionPerformed(ActionEvent e)
2652 if (avc.deleteGroups())
2654 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2655 alignPanel.updateAnnotation();
2656 alignPanel.paintAlignment(true, true);
2667 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2669 SequenceGroup sg = new SequenceGroup(
2670 viewport.getAlignment().getSequences());
2672 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2673 viewport.setSelectionGroup(sg);
2674 viewport.isSelectionGroupChanged(true);
2675 viewport.sendSelection();
2676 // JAL-2034 - should delegate to
2677 // alignPanel to decide if overview needs
2679 alignPanel.paintAlignment(false, false);
2680 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2690 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2692 if (viewport.cursorMode)
2694 alignPanel.getSeqPanel().keyboardNo1 = null;
2695 alignPanel.getSeqPanel().keyboardNo2 = null;
2697 viewport.setSelectionGroup(null);
2698 viewport.getColumnSelection().clear();
2699 viewport.setSearchResults(null);
2700 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2701 // JAL-2034 - should delegate to
2702 // alignPanel to decide if overview needs
2704 alignPanel.paintAlignment(false, false);
2705 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2706 viewport.sendSelection();
2716 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2718 SequenceGroup sg = viewport.getSelectionGroup();
2722 selectAllSequenceMenuItem_actionPerformed(null);
2727 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2729 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2731 // JAL-2034 - should delegate to
2732 // alignPanel to decide if overview needs
2735 alignPanel.paintAlignment(true, false);
2736 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2737 viewport.sendSelection();
2741 public void invertColSel_actionPerformed(ActionEvent e)
2743 viewport.invertColumnSelection();
2744 alignPanel.paintAlignment(true, false);
2745 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2746 viewport.sendSelection();
2756 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2758 trimAlignment(true);
2768 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2770 trimAlignment(false);
2773 void trimAlignment(boolean trimLeft)
2775 ColumnSelection colSel = viewport.getColumnSelection();
2778 if (!colSel.isEmpty())
2782 column = colSel.getMin();
2786 column = colSel.getMax();
2790 if (viewport.getSelectionGroup() != null)
2792 seqs = viewport.getSelectionGroup()
2793 .getSequencesAsArray(viewport.getHiddenRepSequences());
2797 seqs = viewport.getAlignment().getSequencesArray();
2800 TrimRegionCommand trimRegion;
2803 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2804 column, viewport.getAlignment());
2805 viewport.getRanges().setStartRes(0);
2809 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2810 column, viewport.getAlignment());
2813 setStatus(MessageManager.formatMessage("label.removed_columns",
2815 { Integer.valueOf(trimRegion.getSize()).toString() }));
2817 addHistoryItem(trimRegion);
2819 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2821 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2822 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2824 viewport.getAlignment().deleteGroup(sg);
2828 viewport.firePropertyChange("alignment", null,
2829 viewport.getAlignment().getSequences());
2840 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2842 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2845 if (viewport.getSelectionGroup() != null)
2847 seqs = viewport.getSelectionGroup()
2848 .getSequencesAsArray(viewport.getHiddenRepSequences());
2849 start = viewport.getSelectionGroup().getStartRes();
2850 end = viewport.getSelectionGroup().getEndRes();
2854 seqs = viewport.getAlignment().getSequencesArray();
2857 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2858 "Remove Gapped Columns", seqs, start, end,
2859 viewport.getAlignment());
2861 addHistoryItem(removeGapCols);
2863 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2865 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2867 // This is to maintain viewport position on first residue
2868 // of first sequence
2869 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2870 ViewportRanges ranges = viewport.getRanges();
2871 int startRes = seq.findPosition(ranges.getStartRes());
2872 // ShiftList shifts;
2873 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2874 // edit.alColumnChanges=shifts.getInverse();
2875 // if (viewport.hasHiddenColumns)
2876 // viewport.getColumnSelection().compensateForEdits(shifts);
2877 ranges.setStartRes(seq.findIndex(startRes) - 1);
2878 viewport.firePropertyChange("alignment", null,
2879 viewport.getAlignment().getSequences());
2890 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2892 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2895 if (viewport.getSelectionGroup() != null)
2897 seqs = viewport.getSelectionGroup()
2898 .getSequencesAsArray(viewport.getHiddenRepSequences());
2899 start = viewport.getSelectionGroup().getStartRes();
2900 end = viewport.getSelectionGroup().getEndRes();
2904 seqs = viewport.getAlignment().getSequencesArray();
2907 // This is to maintain viewport position on first residue
2908 // of first sequence
2909 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2910 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2912 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2913 viewport.getAlignment()));
2915 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2917 viewport.firePropertyChange("alignment", null,
2918 viewport.getAlignment().getSequences());
2929 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2931 viewport.setPadGaps(padGapsMenuitem.isSelected());
2932 viewport.firePropertyChange("alignment", null,
2933 viewport.getAlignment().getSequences());
2937 * Opens a Finder dialog
2942 public void findMenuItem_actionPerformed(ActionEvent e)
2944 new Finder(alignPanel, false, null);
2948 * Create a new view of the current alignment.
2951 public void newView_actionPerformed(ActionEvent e)
2953 newView(null, true);
2957 * Creates and shows a new view of the current alignment.
2960 * title of newly created view; if null, one will be generated
2961 * @param copyAnnotation
2962 * if true then duplicate all annnotation, groups and settings
2963 * @return new alignment panel, already displayed.
2965 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2968 * Create a new AlignmentPanel (with its own, new Viewport)
2970 AlignmentPanel newap = new jalview.project.Jalview2XML()
2971 .copyAlignPanel(alignPanel);
2972 if (!copyAnnotation)
2975 * remove all groups and annotation except for the automatic stuff
2977 newap.av.getAlignment().deleteAllGroups();
2978 newap.av.getAlignment().deleteAllAnnotations(false);
2981 newap.av.setGatherViewsHere(false);
2983 if (viewport.getViewName() == null)
2985 viewport.setViewName(
2986 MessageManager.getString("label.view_name_original"));
2990 * Views share the same edits undo and redo stacks
2992 newap.av.setHistoryList(viewport.getHistoryList());
2993 newap.av.setRedoList(viewport.getRedoList());
2996 * copy any visualisation settings that are not saved in the project
2998 newap.av.setColourAppliesToAllGroups(
2999 viewport.getColourAppliesToAllGroups());
3002 * Views share the same mappings; need to deregister any new mappings
3003 * created by copyAlignPanel, and register the new reference to the shared
3006 newap.av.replaceMappings(viewport.getAlignment());
3009 * start up cDNA consensus (if applicable) now mappings are in place
3011 if (newap.av.initComplementConsensus())
3013 newap.refresh(true); // adjust layout of annotations
3016 newap.av.setViewName(getNewViewName(viewTitle));
3018 addAlignmentPanel(newap, true);
3019 newap.alignmentChanged();
3021 if (alignPanels.size() == 2)
3023 viewport.setGatherViewsHere(true);
3025 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
3031 * Make a new name for the view, ensuring it is unique within the current
3032 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3033 * these now use viewId. Unique view names are still desirable for usability.)
3038 protected String getNewViewName(String viewTitle)
3040 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3041 boolean addFirstIndex = false;
3042 if (viewTitle == null || viewTitle.trim().length() == 0)
3044 viewTitle = MessageManager.getString("action.view");
3045 addFirstIndex = true;
3049 index = 1;// we count from 1 if given a specific name
3051 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3053 List<Component> comps = PaintRefresher.components
3054 .get(viewport.getSequenceSetId());
3056 List<String> existingNames = getExistingViewNames(comps);
3058 while (existingNames.contains(newViewName))
3060 newViewName = viewTitle + " " + (++index);
3066 * Returns a list of distinct view names found in the given list of
3067 * components. View names are held on the viewport of an AlignmentPanel.
3072 protected List<String> getExistingViewNames(List<Component> comps)
3074 List<String> existingNames = new ArrayList<>();
3075 for (Component comp : comps)
3077 if (comp instanceof AlignmentPanel)
3079 AlignmentPanel ap = (AlignmentPanel) comp;
3080 if (!existingNames.contains(ap.av.getViewName()))
3082 existingNames.add(ap.av.getViewName());
3086 return existingNames;
3090 * Explode tabbed views into separate windows.
3093 public void expandViews_actionPerformed(ActionEvent e)
3095 Desktop.explodeViews(this);
3099 * Gather views in separate windows back into a tabbed presentation.
3102 public void gatherViews_actionPerformed(ActionEvent e)
3104 Desktop.instance.gatherViews(this);
3114 public void font_actionPerformed(ActionEvent e)
3116 new FontChooser(alignPanel);
3126 protected void seqLimit_actionPerformed(ActionEvent e)
3128 viewport.setShowJVSuffix(seqLimits.isSelected());
3130 alignPanel.getIdPanel().getIdCanvas()
3131 .setPreferredSize(alignPanel.calculateIdWidth());
3132 alignPanel.paintAlignment(true, false);
3136 public void idRightAlign_actionPerformed(ActionEvent e)
3138 viewport.setRightAlignIds(idRightAlign.isSelected());
3139 alignPanel.paintAlignment(false, false);
3143 public void centreColumnLabels_actionPerformed(ActionEvent e)
3145 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3146 alignPanel.paintAlignment(false, false);
3152 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3155 protected void followHighlight_actionPerformed()
3158 * Set the 'follow' flag on the Viewport (and scroll to position if now
3161 final boolean state = this.followHighlightMenuItem.getState();
3162 viewport.setFollowHighlight(state);
3165 alignPanel.scrollToPosition(viewport.getSearchResults());
3176 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3178 viewport.setColourText(colourTextMenuItem.isSelected());
3179 alignPanel.paintAlignment(false, false);
3189 public void wrapMenuItem_actionPerformed(ActionEvent e)
3191 setWrapFormat(wrapMenuItem.isSelected(), false);
3194 public void setWrapFormat(boolean b, boolean setMenuItem)
3196 scaleAbove.setVisible(b);
3197 scaleLeft.setVisible(b);
3198 scaleRight.setVisible(b);
3199 viewport.setWrapAlignment(b);
3200 alignPanel.updateLayout();
3203 wrapMenuItem.setSelected(b);
3208 public void showAllSeqs_actionPerformed(ActionEvent e)
3210 viewport.showAllHiddenSeqs();
3214 public void showAllColumns_actionPerformed(ActionEvent e)
3216 viewport.showAllHiddenColumns();
3217 alignPanel.paintAlignment(true, true);
3218 viewport.sendSelection();
3222 public void hideSelSequences_actionPerformed(ActionEvent e)
3224 viewport.hideAllSelectedSeqs();
3228 * called by key handler and the hide all/show all menu items
3233 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3236 boolean hide = false;
3237 SequenceGroup sg = viewport.getSelectionGroup();
3238 if (!toggleSeqs && !toggleCols)
3240 // Hide everything by the current selection - this is a hack - we do the
3241 // invert and then hide
3242 // first check that there will be visible columns after the invert.
3243 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3244 && sg.getStartRes() <= sg.getEndRes()))
3246 // now invert the sequence set, if required - empty selection implies
3247 // that no hiding is required.
3250 invertSequenceMenuItem_actionPerformed(null);
3251 sg = viewport.getSelectionGroup();
3255 viewport.expandColSelection(sg, true);
3256 // finally invert the column selection and get the new sequence
3258 invertColSel_actionPerformed(null);
3265 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3267 hideSelSequences_actionPerformed(null);
3270 else if (!(toggleCols && viewport.hasSelectedColumns()))
3272 showAllSeqs_actionPerformed(null);
3278 if (viewport.hasSelectedColumns())
3280 hideSelColumns_actionPerformed(null);
3283 viewport.setSelectionGroup(sg);
3288 showAllColumns_actionPerformed(null);
3297 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3298 * event.ActionEvent)
3301 public void hideAllButSelection_actionPerformed(ActionEvent e)
3303 toggleHiddenRegions(false, false);
3304 viewport.sendSelection();
3311 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3315 public void hideAllSelection_actionPerformed(ActionEvent e)
3317 SequenceGroup sg = viewport.getSelectionGroup();
3318 viewport.expandColSelection(sg, false);
3319 viewport.hideAllSelectedSeqs();
3320 viewport.hideSelectedColumns();
3321 alignPanel.updateLayout();
3322 alignPanel.paintAlignment(true, true);
3323 viewport.sendSelection();
3330 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3334 public void showAllhidden_actionPerformed(ActionEvent e)
3336 viewport.showAllHiddenColumns();
3337 viewport.showAllHiddenSeqs();
3338 alignPanel.paintAlignment(true, true);
3339 viewport.sendSelection();
3343 public void hideSelColumns_actionPerformed(ActionEvent e)
3345 viewport.hideSelectedColumns();
3346 alignPanel.updateLayout();
3347 alignPanel.paintAlignment(true, true);
3348 viewport.sendSelection();
3352 public void hiddenMarkers_actionPerformed(ActionEvent e)
3354 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3365 protected void scaleAbove_actionPerformed(ActionEvent e)
3367 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3368 alignPanel.updateLayout();
3369 alignPanel.paintAlignment(true, false);
3379 protected void scaleLeft_actionPerformed(ActionEvent e)
3381 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3382 alignPanel.updateLayout();
3383 alignPanel.paintAlignment(true, false);
3393 protected void scaleRight_actionPerformed(ActionEvent e)
3395 viewport.setScaleRightWrapped(scaleRight.isSelected());
3396 alignPanel.updateLayout();
3397 alignPanel.paintAlignment(true, false);
3407 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3409 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3410 alignPanel.paintAlignment(false, false);
3420 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3422 viewport.setShowText(viewTextMenuItem.isSelected());
3423 alignPanel.paintAlignment(false, false);
3433 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3435 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3436 alignPanel.paintAlignment(false, false);
3439 public FeatureSettings featureSettings;
3442 public FeatureSettingsControllerI getFeatureSettingsUI()
3444 return featureSettings;
3448 public void featureSettings_actionPerformed(ActionEvent e)
3450 showFeatureSettingsUI();
3454 public FeatureSettingsControllerI showFeatureSettingsUI()
3456 if (featureSettings != null)
3458 featureSettings.closeOldSettings();
3459 featureSettings = null;
3461 if (!showSeqFeatures.isSelected())
3463 // make sure features are actually displayed
3464 showSeqFeatures.setSelected(true);
3465 showSeqFeatures_actionPerformed(null);
3467 featureSettings = new FeatureSettings(this);
3468 return featureSettings;
3472 * Set or clear 'Show Sequence Features'
3478 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3480 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3481 alignPanel.paintAlignment(true, true);
3485 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3486 * the annotations panel as a whole.
3488 * The options to show/hide all annotations should be enabled when the panel
3489 * is shown, and disabled when the panel is hidden.
3494 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3496 final boolean setVisible = annotationPanelMenuItem.isSelected();
3497 viewport.setShowAnnotation(setVisible);
3498 this.showAllSeqAnnotations.setEnabled(setVisible);
3499 this.hideAllSeqAnnotations.setEnabled(setVisible);
3500 this.showAllAlAnnotations.setEnabled(setVisible);
3501 this.hideAllAlAnnotations.setEnabled(setVisible);
3502 alignPanel.updateLayout();
3506 public void alignmentProperties()
3509 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3512 String content = MessageManager.formatMessage("label.html_content",
3514 { contents.toString() });
3517 if (Platform.isJS())
3519 JLabel textLabel = new JLabel();
3520 textLabel.setText(content);
3521 textLabel.setBackground(Color.WHITE);
3523 pane = new JPanel(new BorderLayout());
3524 ((JPanel) pane).setOpaque(true);
3525 pane.setBackground(Color.WHITE);
3526 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3535 JEditorPane editPane = new JEditorPane("text/html", "");
3536 editPane.setEditable(false);
3537 editPane.setText(content);
3541 JInternalFrame frame = new JInternalFrame();
3542 frame.setFrameIcon(null);
3543 frame.getContentPane().add(new JScrollPane(pane));
3545 Desktop.addInternalFrame(frame, MessageManager
3546 .formatMessage("label.alignment_properties", new Object[]
3547 { getTitle() }), 500, 400);
3551 * Opens an Overview panel for the alignment, unless one is open already
3556 public void overviewMenuItem_actionPerformed(ActionEvent e)
3558 boolean showHiddenRegions = Cache
3559 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3560 openOverviewPanel(showHiddenRegions);
3563 public OverviewPanel openOverviewPanel(boolean showHidden)
3565 if (alignPanel.overviewPanel != null)
3567 return alignPanel.overviewPanel;
3569 JInternalFrame frame = new JInternalFrame();
3570 frame.setFrameIcon(null);
3571 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3573 frame.setContentPane(overview);
3574 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3575 frame.getHeight(), true, true);
3577 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3578 final AlignmentPanel thePanel = this.alignPanel;
3579 frame.addInternalFrameListener(
3580 new javax.swing.event.InternalFrameAdapter()
3583 public void internalFrameClosed(
3584 javax.swing.event.InternalFrameEvent evt)
3587 thePanel.setOverviewPanel(null);
3590 if (getKeyListeners().length > 0)
3592 frame.addKeyListener(getKeyListeners()[0]);
3595 alignPanel.setOverviewPanel(overview);
3596 alignPanel.setOverviewTitle(this);
3602 public void textColour_actionPerformed()
3604 new TextColourChooser().chooseColour(alignPanel, null);
3608 * public void covariationColour_actionPerformed() {
3610 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3614 public void annotationColour_actionPerformed()
3616 new AnnotationColourChooser(viewport, alignPanel);
3620 public void annotationColumn_actionPerformed(ActionEvent e)
3622 new AnnotationColumnChooser(viewport, alignPanel);
3626 * Action on the user checking or unchecking the option to apply the selected
3627 * colour scheme to all groups. If unchecked, groups may have their own
3628 * independent colour schemes.
3633 public void applyToAllGroups_actionPerformed(boolean selected)
3635 viewport.setColourAppliesToAllGroups(selected);
3639 * Action on user selecting a colour from the colour menu
3642 * the name (not the menu item label!) of the colour scheme
3645 public void changeColour_actionPerformed(String name)
3648 * 'User Defined' opens a panel to configure or load a
3649 * user-defined colour scheme
3651 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3653 new UserDefinedColours(alignPanel);
3658 * otherwise set the chosen colour scheme (or null for 'None')
3660 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3661 viewport, viewport.getAlignment(),
3662 viewport.getHiddenRepSequences());
3667 * Actions on setting or changing the alignment colour scheme
3672 public void changeColour(ColourSchemeI cs)
3674 // TODO: pull up to controller method
3675 ColourMenuHelper.setColourSelected(colourMenu, cs);
3677 viewport.setGlobalColourScheme(cs);
3679 alignPanel.paintAlignment(true, true);
3683 * Show the PID threshold slider panel
3686 protected void modifyPID_actionPerformed()
3688 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3689 alignPanel.getViewName());
3690 SliderPanel.showPIDSlider();
3694 * Show the Conservation slider panel
3697 protected void modifyConservation_actionPerformed()
3699 SliderPanel.setConservationSlider(alignPanel,
3700 viewport.getResidueShading(), alignPanel.getViewName());
3701 SliderPanel.showConservationSlider();
3705 * Action on selecting or deselecting (Colour) By Conservation
3708 public void conservationMenuItem_actionPerformed(boolean selected)
3710 modifyConservation.setEnabled(selected);
3711 viewport.setConservationSelected(selected);
3712 viewport.getResidueShading().setConservationApplied(selected);
3714 changeColour(viewport.getGlobalColourScheme());
3717 modifyConservation_actionPerformed();
3721 SliderPanel.hideConservationSlider();
3726 * Action on selecting or deselecting (Colour) Above PID Threshold
3729 public void abovePIDThreshold_actionPerformed(boolean selected)
3731 modifyPID.setEnabled(selected);
3732 viewport.setAbovePIDThreshold(selected);
3735 viewport.getResidueShading().setThreshold(0,
3736 viewport.isIgnoreGapsConsensus());
3739 changeColour(viewport.getGlobalColourScheme());
3742 modifyPID_actionPerformed();
3746 SliderPanel.hidePIDSlider();
3757 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3759 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3760 AlignmentSorter.sortByPID(viewport.getAlignment(),
3761 viewport.getAlignment().getSequenceAt(0));
3762 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3763 viewport.getAlignment()));
3764 alignPanel.paintAlignment(true, false);
3774 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3776 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3777 AlignmentSorter.sortByID(viewport.getAlignment());
3779 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3780 alignPanel.paintAlignment(true, false);
3790 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3792 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3793 AlignmentSorter.sortByLength(viewport.getAlignment());
3794 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3795 viewport.getAlignment()));
3796 alignPanel.paintAlignment(true, false);
3806 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3808 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3809 AlignmentSorter.sortByGroup(viewport.getAlignment());
3810 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3811 viewport.getAlignment()));
3813 alignPanel.paintAlignment(true, false);
3823 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3825 new RedundancyPanel(alignPanel, this);
3835 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3837 if ((viewport.getSelectionGroup() == null)
3838 || (viewport.getSelectionGroup().getSize() < 2))
3840 JvOptionPane.showInternalMessageDialog(this,
3841 MessageManager.getString(
3842 "label.you_must_select_least_two_sequences"),
3843 MessageManager.getString("label.invalid_selection"),
3844 JvOptionPane.WARNING_MESSAGE);
3848 JInternalFrame frame = new JInternalFrame();
3849 frame.setFrameIcon(null);
3850 frame.setContentPane(new PairwiseAlignPanel(viewport));
3851 Desktop.addInternalFrame(frame,
3852 MessageManager.getString("action.pairwise_alignment"), 600,
3858 public void autoCalculate_actionPerformed(ActionEvent e)
3860 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3861 if (viewport.autoCalculateConsensus)
3863 viewport.firePropertyChange("alignment", null,
3864 viewport.getAlignment().getSequences());
3869 public void sortByTreeOption_actionPerformed(ActionEvent e)
3871 viewport.sortByTree = sortByTree.isSelected();
3875 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3877 viewport.followSelection = listenToViewSelections.isSelected();
3881 * Constructs a tree panel and adds it to the desktop
3884 * tree type (NJ or AV)
3886 * name of score model used to compute the tree
3888 * parameters for the distance or similarity calculation
3890 void newTreePanel(String type, String modelName,
3891 SimilarityParamsI options)
3893 String frameTitle = "";
3896 boolean onSelection = false;
3897 if (viewport.getSelectionGroup() != null
3898 && viewport.getSelectionGroup().getSize() > 0)
3900 SequenceGroup sg = viewport.getSelectionGroup();
3902 /* Decide if the selection is a column region */
3903 for (SequenceI _s : sg.getSequences())
3905 if (_s.getLength() < sg.getEndRes())
3907 JvOptionPane.showMessageDialog(Desktop.desktop,
3908 MessageManager.getString(
3909 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3910 MessageManager.getString(
3911 "label.sequences_selection_not_aligned"),
3912 JvOptionPane.WARNING_MESSAGE);
3921 if (viewport.getAlignment().getHeight() < 2)
3927 tp = new TreePanel(alignPanel, type, modelName, options);
3928 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3930 frameTitle += " from ";
3932 if (viewport.getViewName() != null)
3934 frameTitle += viewport.getViewName() + " of ";
3937 frameTitle += this.title;
3939 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3950 public void addSortByOrderMenuItem(String title,
3951 final AlignmentOrder order)
3953 final JMenuItem item = new JMenuItem(MessageManager
3954 .formatMessage("action.by_title_param", new Object[]
3957 item.addActionListener(new java.awt.event.ActionListener()
3960 public void actionPerformed(ActionEvent e)
3962 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3964 // TODO: JBPNote - have to map order entries to curent SequenceI
3966 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3968 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3969 viewport.getAlignment()));
3971 alignPanel.paintAlignment(true, false);
3977 * Add a new sort by annotation score menu item
3980 * the menu to add the option to
3982 * the label used to retrieve scores for each sequence on the
3985 public void addSortByAnnotScoreMenuItem(JMenu sort,
3986 final String scoreLabel)
3988 final JMenuItem item = new JMenuItem(scoreLabel);
3990 item.addActionListener(new java.awt.event.ActionListener()
3993 public void actionPerformed(ActionEvent e)
3995 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3996 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3997 viewport.getAlignment());// ,viewport.getSelectionGroup());
3998 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3999 viewport.getAlignment()));
4000 alignPanel.paintAlignment(true, false);
4006 * last hash for alignment's annotation array - used to minimise cost of
4009 protected int _annotationScoreVectorHash;
4012 * search the alignment and rebuild the sort by annotation score submenu the
4013 * last alignment annotation vector hash is stored to minimize cost of
4014 * rebuilding in subsequence calls.
4018 public void buildSortByAnnotationScoresMenu()
4020 if (viewport.getAlignment().getAlignmentAnnotation() == null)
4025 if (viewport.getAlignment().getAlignmentAnnotation()
4026 .hashCode() != _annotationScoreVectorHash)
4028 sortByAnnotScore.removeAll();
4029 // almost certainly a quicker way to do this - but we keep it simple
4030 Hashtable<String, String> scoreSorts = new Hashtable<>();
4031 AlignmentAnnotation aann[];
4032 for (SequenceI sqa : viewport.getAlignment().getSequences())
4034 aann = sqa.getAnnotation();
4035 for (int i = 0; aann != null && i < aann.length; i++)
4037 if (aann[i].hasScore() && aann[i].sequenceRef != null)
4039 scoreSorts.put(aann[i].label, aann[i].label);
4043 Enumeration<String> labels = scoreSorts.keys();
4044 while (labels.hasMoreElements())
4046 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4048 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4051 _annotationScoreVectorHash = viewport.getAlignment()
4052 .getAlignmentAnnotation().hashCode();
4057 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4058 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4059 * call. Listeners are added to remove the menu item when the treePanel is
4060 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4064 public void buildTreeSortMenu()
4066 sortByTreeMenu.removeAll();
4068 List<Component> comps = PaintRefresher.components
4069 .get(viewport.getSequenceSetId());
4070 List<TreePanel> treePanels = new ArrayList<>();
4071 for (Component comp : comps)
4073 if (comp instanceof TreePanel)
4075 treePanels.add((TreePanel) comp);
4079 if (treePanels.size() < 1)
4081 sortByTreeMenu.setVisible(false);
4085 sortByTreeMenu.setVisible(true);
4087 for (final TreePanel tp : treePanels)
4089 final JMenuItem item = new JMenuItem(tp.getTitle());
4090 item.addActionListener(new java.awt.event.ActionListener()
4093 public void actionPerformed(ActionEvent e)
4095 tp.sortByTree_actionPerformed();
4096 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4101 sortByTreeMenu.add(item);
4105 public boolean sortBy(AlignmentOrder alorder, String undoname)
4107 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4108 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4109 if (undoname != null)
4111 addHistoryItem(new OrderCommand(undoname, oldOrder,
4112 viewport.getAlignment()));
4114 alignPanel.paintAlignment(true, false);
4119 * Work out whether the whole set of sequences or just the selected set will
4120 * be submitted for multiple alignment.
4123 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4125 // Now, check we have enough sequences
4126 AlignmentView msa = null;
4128 if ((viewport.getSelectionGroup() != null)
4129 && (viewport.getSelectionGroup().getSize() > 1))
4131 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4132 // some common interface!
4134 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4135 * SequenceI[sz = seqs.getSize(false)];
4137 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4138 * seqs.getSequenceAt(i); }
4140 msa = viewport.getAlignmentView(true);
4142 else if (viewport.getSelectionGroup() != null
4143 && viewport.getSelectionGroup().getSize() == 1)
4145 int option = JvOptionPane.showConfirmDialog(this,
4146 MessageManager.getString("warn.oneseq_msainput_selection"),
4147 MessageManager.getString("label.invalid_selection"),
4148 JvOptionPane.OK_CANCEL_OPTION);
4149 if (option == JvOptionPane.OK_OPTION)
4151 msa = viewport.getAlignmentView(false);
4156 msa = viewport.getAlignmentView(false);
4162 * Decides what is submitted to a secondary structure prediction service: the
4163 * first sequence in the alignment, or in the current selection, or, if the
4164 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4165 * region or the whole alignment. (where the first sequence in the set is the
4166 * one that the prediction will be for).
4168 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4170 AlignmentView seqs = null;
4172 if ((viewport.getSelectionGroup() != null)
4173 && (viewport.getSelectionGroup().getSize() > 0))
4175 seqs = viewport.getAlignmentView(true);
4179 seqs = viewport.getAlignmentView(false);
4181 // limit sequences - JBPNote in future - could spawn multiple prediction
4183 // TODO: viewport.getAlignment().isAligned is a global state - the local
4184 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4185 if (!viewport.getAlignment().isAligned(false))
4187 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4188 // TODO: if seqs.getSequences().length>1 then should really have warned
4202 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4204 // Pick the tree file
4205 JalviewFileChooser chooser = new JalviewFileChooser(
4206 Cache.getProperty("LAST_DIRECTORY"));
4207 chooser.setFileView(new JalviewFileView());
4208 chooser.setDialogTitle(
4209 MessageManager.getString("label.select_newick_like_tree_file"));
4210 chooser.setToolTipText(
4211 MessageManager.getString("label.load_tree_file"));
4213 chooser.setResponseHandler(0, () -> {
4214 String filePath = chooser.getSelectedFile().getPath();
4215 Cache.setProperty("LAST_DIRECTORY", filePath);
4216 NewickFile fin = null;
4219 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4220 DataSourceType.FILE));
4221 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4222 } catch (Exception ex)
4224 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4225 MessageManager.getString("label.problem_reading_tree_file"),
4226 JvOptionPane.WARNING_MESSAGE);
4227 ex.printStackTrace();
4229 if (fin != null && fin.hasWarningMessage())
4231 JvOptionPane.showMessageDialog(Desktop.desktop,
4232 fin.getWarningMessage(),
4234 .getString("label.possible_problem_with_tree_file"),
4235 JvOptionPane.WARNING_MESSAGE);
4238 chooser.showOpenDialog(this);
4241 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4243 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4246 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4247 int h, int x, int y)
4249 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4253 * Add a treeviewer for the tree extracted from a Newick file object to the
4254 * current alignment view
4261 * Associated alignment input data (or null)
4270 * @return TreePanel handle
4272 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4273 AlignmentView input, int w, int h, int x, int y)
4275 TreePanel tp = null;
4281 if (nf.getTree() != null)
4283 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4289 tp.setLocation(x, y);
4292 Desktop.addInternalFrame(tp, treeTitle, w, h);
4294 } catch (Exception ex)
4296 ex.printStackTrace();
4302 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4305 int w = 400, h = 500;
4309 NewickFile fin = new NewickFile(
4310 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4311 String title = aa.label + " " + cm.getTreeMethod() + " tree"
4312 + (aa.sequenceRef != null
4313 ? (" for " + aa.sequenceRef.getDisplayId(false))
4316 showColumnWiseTree(fin, aa, title, w, h, x, y);
4317 } catch (Throwable xx)
4319 Console.error("Unexpected exception showing tree for contact matrix",
4324 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4325 String treeTitle, int w, int h, int x, int y)
4330 if (nf.getTree() == null)
4334 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4340 tp.setLocation(x, y);
4343 Desktop.addInternalFrame(tp, treeTitle, w, h);
4345 } catch (Throwable xx)
4347 Console.error("Unexpected exception showing tree for contact matrix",
4353 private boolean buildingMenu = false;
4356 * Generates menu items and listener event actions for web service clients
4359 public void BuildWebServiceMenu()
4361 while (buildingMenu)
4366 .errPrintln("Waiting for building menu to finish.");
4368 } catch (Exception e)
4372 final AlignFrame me = this;
4373 buildingMenu = true;
4374 new Thread(new Runnable()
4379 final List<JMenuItem> legacyItems = new ArrayList<>();
4382 // jalview.bin.Console.errPrintln("Building ws menu again "
4383 // + Thread.currentThread());
4384 // TODO: add support for context dependent disabling of services based
4386 // alignment and current selection
4387 // TODO: add additional serviceHandle parameter to specify abstract
4389 // class independently of AbstractName
4390 // TODO: add in rediscovery GUI function to restart discoverer
4391 // TODO: group services by location as well as function and/or
4393 // object broker mechanism.
4394 final Vector<JMenu> wsmenu = new Vector<>();
4395 final IProgressIndicator af = me;
4398 * do not i18n these strings - they are hard-coded in class
4399 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4400 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4402 final JMenu msawsmenu = new JMenu("Alignment");
4403 final JMenu secstrmenu = new JMenu(
4404 "Secondary Structure Prediction");
4405 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4406 final JMenu analymenu = new JMenu("Analysis");
4407 final JMenu dismenu = new JMenu("Protein Disorder");
4408 // JAL-940 - only show secondary structure prediction services from
4409 // the legacy server
4410 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4412 Discoverer.services != null && (Discoverer.services.size() > 0))
4414 // TODO: refactor to allow list of AbstractName/Handler bindings to
4416 // stored or retrieved from elsewhere
4417 // No MSAWS used any more:
4418 // Vector msaws = null; // (Vector)
4419 // Discoverer.services.get("MsaWS");
4420 Vector<ServiceHandle> secstrpr = Discoverer.services
4422 if (secstrpr != null)
4424 // Add any secondary structure prediction services
4425 for (int i = 0, j = secstrpr.size(); i < j; i++)
4427 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4428 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4429 .getServiceClient(sh);
4430 int p = secstrmenu.getItemCount();
4431 impl.attachWSMenuEntry(secstrmenu, me);
4432 int q = secstrmenu.getItemCount();
4433 for (int litm = p; litm < q; litm++)
4435 legacyItems.add(secstrmenu.getItem(litm));
4441 // Add all submenus in the order they should appear on the web
4443 wsmenu.add(msawsmenu);
4444 wsmenu.add(secstrmenu);
4445 wsmenu.add(dismenu);
4446 wsmenu.add(analymenu);
4447 // No search services yet
4448 // wsmenu.add(seqsrchmenu);
4450 javax.swing.SwingUtilities.invokeLater(new Runnable()
4457 webService.removeAll();
4458 // first, add discovered services onto the webservices menu
4459 if (wsmenu.size() > 0)
4461 for (int i = 0, j = wsmenu.size(); i < j; i++)
4463 webService.add(wsmenu.get(i));
4468 webService.add(me.webServiceNoServices);
4470 // TODO: move into separate menu builder class.
4472 // logic for 2.11.1.4 is
4473 // always look to see if there is a discover. if there isn't
4474 // we can't show any Jws2 services
4475 // if there are services available, show them - regardless of
4476 // the 'show JWS2 preference'
4477 // if the discoverer is running then say so
4478 // otherwise offer to trigger discovery if 'show JWS2' is not
4480 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4481 if (jws2servs != null)
4483 if (jws2servs.hasServices())
4485 jws2servs.attachWSMenuEntry(webService, me);
4486 for (Jws2Instance sv : jws2servs.getServices())
4488 if (sv.description.toLowerCase(Locale.ROOT)
4491 for (JMenuItem jmi : legacyItems)
4493 jmi.setVisible(false);
4499 if (jws2servs.isRunning())
4501 JMenuItem tm = new JMenuItem(
4502 "Still discovering JABA Services");
4503 tm.setEnabled(false);
4506 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4508 JMenuItem enableJws2 = new JMenuItem(
4509 "Discover Web Services");
4510 enableJws2.setToolTipText(
4511 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4512 enableJws2.setEnabled(true);
4513 enableJws2.addActionListener(new ActionListener()
4517 public void actionPerformed(ActionEvent e)
4519 // start service discoverer, but ignore preference
4520 Desktop.instance.startServiceDiscovery(false,
4524 webService.add(enableJws2);
4528 build_urlServiceMenu(me.webService);
4529 build_fetchdbmenu(webService);
4530 for (JMenu item : wsmenu)
4532 if (item.getItemCount() == 0)
4534 item.setEnabled(false);
4538 item.setEnabled(true);
4541 } catch (Exception e)
4544 "Exception during web service menu building process.",
4549 } catch (Exception e)
4552 buildingMenu = false;
4559 * construct any groupURL type service menu entries.
4563 protected void build_urlServiceMenu(JMenu webService)
4565 // TODO: remove this code when 2.7 is released
4566 // DEBUG - alignmentView
4568 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4569 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4571 * @Override public void actionPerformed(ActionEvent e) {
4572 * jalview.datamodel.AlignmentView
4573 * .testSelectionViews(af.viewport.getAlignment(),
4574 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4576 * }); webService.add(testAlView);
4578 // TODO: refactor to RestClient discoverer and merge menu entries for
4579 // rest-style services with other types of analysis/calculation service
4580 // SHmmr test client - still being implemented.
4581 // DEBUG - alignmentView
4583 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4586 client.attachWSMenuEntry(
4587 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4593 * Searches the alignment sequences for xRefs and builds the Show
4594 * Cross-References menu (formerly called Show Products), with database
4595 * sources for which cross-references are found (protein sources for a
4596 * nucleotide alignment and vice versa)
4598 * @return true if Show Cross-references menu should be enabled
4600 public boolean canShowProducts()
4602 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4603 AlignmentI dataset = viewport.getAlignment().getDataset();
4605 showProducts.removeAll();
4606 final boolean dna = viewport.getAlignment().isNucleotide();
4608 if (seqs == null || seqs.length == 0)
4610 // nothing to see here.
4614 boolean showp = false;
4617 List<String> ptypes = new CrossRef(seqs, dataset)
4618 .findXrefSourcesForSequences(dna);
4620 for (final String source : ptypes)
4623 final AlignFrame af = this;
4624 JMenuItem xtype = new JMenuItem(source);
4625 xtype.addActionListener(new ActionListener()
4628 public void actionPerformed(ActionEvent e)
4630 showProductsFor(af.viewport.getSequenceSelection(), dna,
4634 showProducts.add(xtype);
4636 showProducts.setVisible(showp);
4637 showProducts.setEnabled(showp);
4638 } catch (Exception e)
4641 "canShowProducts threw an exception - please report to help@jalview.org",
4649 * Finds and displays cross-references for the selected sequences (protein
4650 * products for nucleotide sequences, dna coding sequences for peptides).
4653 * the sequences to show cross-references for
4655 * true if from a nucleotide alignment (so showing proteins)
4657 * the database to show cross-references for
4659 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4660 final String source)
4662 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4667 * Construct and display a new frame containing the translation of this
4668 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4671 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4673 AlignmentI al = null;
4676 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4678 al = dna.translateCdna(codeTable);
4679 } catch (Exception ex)
4681 Console.error("Exception during translation. Please report this !",
4683 final String msg = MessageManager.getString(
4684 "label.error_when_translating_sequences_submit_bug_report");
4685 final String errorTitle = MessageManager
4686 .getString("label.implementation_error")
4687 + MessageManager.getString("label.translation_failed");
4688 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4689 JvOptionPane.ERROR_MESSAGE);
4692 if (al == null || al.getHeight() == 0)
4694 final String msg = MessageManager.getString(
4695 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4696 final String errorTitle = MessageManager
4697 .getString("label.translation_failed");
4698 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4699 JvOptionPane.WARNING_MESSAGE);
4703 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4704 af.setFileFormat(this.currentFileFormat);
4705 final String newTitle = MessageManager
4706 .formatMessage("label.translation_of_params", new Object[]
4707 { this.getTitle(), codeTable.getId() });
4708 af.setTitle(newTitle);
4709 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4711 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4712 viewport.openSplitFrame(af, new Alignment(seqs));
4716 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4723 * Set the file format
4727 public void setFileFormat(FileFormatI format)
4729 this.currentFileFormat = format;
4733 * Try to load a features file onto the alignment.
4736 * contents or path to retrieve file or a File object
4738 * access mode of file (see jalview.io.AlignFile)
4739 * @return true if features file was parsed correctly.
4741 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4744 return avc.parseFeaturesFile(file, sourceType,
4745 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4750 public void refreshFeatureUI(boolean enableIfNecessary)
4752 // note - currently this is only still here rather than in the controller
4753 // because of the featureSettings hard reference that is yet to be
4755 if (enableIfNecessary)
4757 viewport.setShowSequenceFeatures(true);
4758 showSeqFeatures.setSelected(true);
4764 public void dragEnter(DropTargetDragEvent evt)
4769 public void dragExit(DropTargetEvent evt)
4774 public void dragOver(DropTargetDragEvent evt)
4779 public void dropActionChanged(DropTargetDragEvent evt)
4784 public void drop(DropTargetDropEvent evt)
4786 // JAL-1552 - acceptDrop required before getTransferable call for
4787 // Java's Transferable for native dnd
4788 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4789 Transferable t = evt.getTransferable();
4791 final AlignFrame thisaf = this;
4792 final List<Object> files = new ArrayList<>();
4793 List<DataSourceType> protocols = new ArrayList<>();
4797 Desktop.transferFromDropTarget(files, protocols, evt, t);
4798 } catch (Exception e)
4800 e.printStackTrace();
4804 new Thread(new Runnable()
4811 // check to see if any of these files have names matching sequences
4814 SequenceIdMatcher idm = new SequenceIdMatcher(
4815 viewport.getAlignment().getSequencesArray());
4817 * Object[] { String,SequenceI}
4819 ArrayList<Object[]> filesmatched = new ArrayList<>();
4820 ArrayList<Object> filesnotmatched = new ArrayList<>();
4821 for (int i = 0; i < files.size(); i++)
4824 Object file = files.get(i);
4825 String fileName = file.toString();
4827 DataSourceType protocol = (file instanceof File
4828 ? DataSourceType.FILE
4829 : FormatAdapter.checkProtocol(fileName));
4830 if (protocol == DataSourceType.FILE)
4833 if (file instanceof File)
4836 Platform.cacheFileData(fl);
4840 fl = new File(fileName);
4842 pdbfn = fl.getName();
4844 else if (protocol == DataSourceType.URL)
4846 URL url = new URL(fileName);
4847 pdbfn = url.getFile();
4849 if (pdbfn.length() > 0)
4851 // attempt to find a match in the alignment
4852 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4853 int l = 0, c = pdbfn.indexOf(".");
4854 while (mtch == null && c != -1)
4859 } while ((c = pdbfn.indexOf(".", l)) > l);
4862 pdbfn = pdbfn.substring(0, l);
4864 mtch = idm.findAllIdMatches(pdbfn);
4871 type = new IdentifyFile().identify(file, protocol);
4872 } catch (Exception ex)
4876 if (type != null && type.isStructureFile())
4878 filesmatched.add(new Object[] { file, protocol, mtch });
4882 // File wasn't named like one of the sequences or wasn't a PDB
4884 filesnotmatched.add(file);
4888 if (filesmatched.size() > 0)
4890 boolean autoAssociate = Cache
4891 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4894 String msg = MessageManager.formatMessage(
4895 "label.automatically_associate_structure_files_with_sequences_same_name",
4897 { Integer.valueOf(filesmatched.size())
4899 String ttl = MessageManager.getString(
4900 "label.automatically_associate_structure_files_by_name");
4901 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4902 ttl, JvOptionPane.YES_NO_OPTION);
4903 autoAssociate = choice == JvOptionPane.YES_OPTION;
4907 for (Object[] fm : filesmatched)
4909 // try and associate
4910 // TODO: may want to set a standard ID naming formalism for
4911 // associating PDB files which have no IDs.
4912 for (SequenceI toassoc : (SequenceI[]) fm[2])
4914 PDBEntry pe = new AssociatePdbFileWithSeq()
4915 .associatePdbWithSeq(fm[0].toString(),
4916 (DataSourceType) fm[1], toassoc, false,
4920 jalview.bin.Console.errPrintln("Associated file : "
4921 + (fm[0].toString()) + " with "
4922 + toassoc.getDisplayId(true));
4926 // TODO: do we need to update overview ? only if features are
4928 alignPanel.paintAlignment(true, false);
4934 * add declined structures as sequences
4936 for (Object[] o : filesmatched)
4938 filesnotmatched.add(o[0]);
4942 if (filesnotmatched.size() > 0)
4944 if (assocfiles > 0 && (Cache.getDefault(
4945 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4946 || JvOptionPane.showConfirmDialog(thisaf,
4947 "<html>" + MessageManager.formatMessage(
4948 "label.ignore_unmatched_dropped_files_info",
4951 filesnotmatched.size())
4954 MessageManager.getString(
4955 "label.ignore_unmatched_dropped_files"),
4956 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4960 for (Object fn : filesnotmatched)
4962 loadJalviewDataFile(fn, null, null, null);
4966 } catch (Exception ex)
4968 ex.printStackTrace();
4976 * Attempt to load a "dropped" file or URL string, by testing in turn for
4978 * <li>an Annotation file</li>
4979 * <li>a JNet file</li>
4980 * <li>a features file</li>
4981 * <li>else try to interpret as an alignment file</li>
4985 * either a filename or a URL string.
4987 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4988 FileFormatI format, SequenceI assocSeq)
4990 // BH 2018 was String file
4993 if (sourceType == null)
4995 sourceType = FormatAdapter.checkProtocol(file);
4997 // if the file isn't identified, or not positively identified as some
4998 // other filetype (PFAM is default unidentified alignment file type) then
4999 // try to parse as annotation.
5000 boolean isAnnotation = (format == null
5001 || FileFormat.Pfam.equals(format))
5002 ? new AnnotationFile().annotateAlignmentView(viewport,
5008 // first see if its a T-COFFEE score file
5009 TCoffeeScoreFile tcf = null;
5012 tcf = new TCoffeeScoreFile(file, sourceType);
5015 if (tcf.annotateAlignment(viewport.getAlignment(), true))
5019 new TCoffeeColourScheme(viewport.getAlignment()));
5020 isAnnotation = true;
5021 setStatus(MessageManager.getString(
5022 "label.successfully_pasted_tcoffee_scores_to_alignment"));
5026 // some problem - if no warning its probable that the ID matching
5027 // process didn't work
5028 JvOptionPane.showMessageDialog(Desktop.desktop,
5029 tcf.getWarningMessage() == null
5030 ? MessageManager.getString(
5031 "label.check_file_matches_sequence_ids_alignment")
5032 : tcf.getWarningMessage(),
5033 MessageManager.getString(
5034 "label.problem_reading_tcoffee_score_file"),
5035 JvOptionPane.WARNING_MESSAGE);
5042 } catch (Exception x)
5045 "Exception when processing data source as T-COFFEE score file",
5051 // try to see if its a JNet 'concise' style annotation file *before*
5053 // try to parse it as a features file
5056 format = new IdentifyFile().identify(file, sourceType);
5058 if (FileFormat.ScoreMatrix == format)
5060 ScoreMatrixFile sm = new ScoreMatrixFile(
5061 new FileParse(file, sourceType));
5063 // todo: i18n this message
5064 setStatus(MessageManager.formatMessage(
5065 "label.successfully_loaded_matrix",
5066 sm.getMatrixName()));
5068 else if (FileFormat.Jnet.equals(format))
5070 JPredFile predictions = new JPredFile(file, sourceType);
5071 new JnetAnnotationMaker();
5072 JnetAnnotationMaker.add_annotation(predictions,
5073 viewport.getAlignment(), 0, false);
5074 viewport.getAlignment().setupJPredAlignment();
5075 isAnnotation = true;
5077 // else if (IdentifyFile.FeaturesFile.equals(format))
5078 else if (FileFormat.Features.equals(format))
5080 if (parseFeaturesFile(file, sourceType))
5082 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5083 if (splitFrame != null)
5085 splitFrame.repaint();
5089 alignPanel.paintAlignment(true, true);
5095 new FileLoader().LoadFile(viewport, file, sourceType, format);
5102 alignPanel.adjustAnnotationHeight();
5103 viewport.updateSequenceIdColours();
5104 buildSortByAnnotationScoresMenu();
5105 alignPanel.paintAlignment(true, true);
5107 } catch (Exception ex)
5109 ex.printStackTrace();
5110 } catch (OutOfMemoryError oom)
5115 } catch (Exception x)
5120 + (sourceType != null
5121 ? (sourceType == DataSourceType.PASTE
5123 : "using " + sourceType + " from "
5127 ? "(parsing as '" + format + "' file)"
5129 oom, Desktop.desktop);
5134 * Method invoked by the ChangeListener on the tabbed pane, in other words
5135 * when a different tabbed pane is selected by the user or programmatically.
5138 public void tabSelectionChanged(int index)
5143 * update current Overview window title (if there is one)
5144 * to add view name "Original" if necessary
5146 alignPanel.setOverviewTitle(this);
5149 * switch panels and set Overview title (if there is one
5150 * because it was opened automatically)
5152 alignPanel = alignPanels.get(index);
5153 alignPanel.setOverviewTitle(this);
5155 viewport = alignPanel.av;
5156 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5157 setMenusFromViewport(viewport);
5158 if (featureSettings != null && featureSettings.isOpen()
5159 && featureSettings.fr.getViewport() != viewport)
5161 if (viewport.isShowSequenceFeatures())
5163 // refresh the featureSettings to reflect UI change
5164 showFeatureSettingsUI();
5168 // close feature settings for this view.
5169 featureSettings.close();
5176 * 'focus' any colour slider that is open to the selected viewport
5178 if (viewport.getConservationSelected())
5180 SliderPanel.setConservationSlider(alignPanel,
5181 viewport.getResidueShading(), alignPanel.getViewName());
5185 SliderPanel.hideConservationSlider();
5187 if (viewport.getAbovePIDThreshold())
5189 SliderPanel.setPIDSliderSource(alignPanel,
5190 viewport.getResidueShading(), alignPanel.getViewName());
5194 SliderPanel.hidePIDSlider();
5198 * If there is a frame linked to this one in a SplitPane, switch it to the
5199 * same view tab index. No infinite recursion of calls should happen, since
5200 * tabSelectionChanged() should not get invoked on setting the selected
5201 * index to an unchanged value. Guard against setting an invalid index
5202 * before the new view peer tab has been created.
5204 final AlignViewportI peer = viewport.getCodingComplement();
5207 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5208 .getAlignPanel().alignFrame;
5209 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5211 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5217 * On right mouse click on view tab, prompt for and set new view name.
5220 public void tabbedPane_mousePressed(MouseEvent e)
5222 if (e.isPopupTrigger())
5224 String msg = MessageManager.getString("label.enter_view_name");
5225 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5226 String reply = JvOptionPane.showInputDialog(msg, ttl);
5230 viewport.setViewName(reply);
5231 // TODO warn if reply is in getExistingViewNames()?
5232 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5237 public AlignViewport getCurrentView()
5243 * Open the dialog for regex description parsing.
5246 protected void extractScores_actionPerformed(ActionEvent e)
5248 ParseProperties pp = new jalview.analysis.ParseProperties(
5249 viewport.getAlignment());
5250 // TODO: verify regex and introduce GUI dialog for version 2.5
5251 // if (pp.getScoresFromDescription("col", "score column ",
5252 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5254 if (pp.getScoresFromDescription("description column",
5255 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5257 buildSortByAnnotationScoresMenu();
5265 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5269 protected void showDbRefs_actionPerformed(ActionEvent e)
5271 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5277 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5281 protected void showNpFeats_actionPerformed(ActionEvent e)
5283 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5287 * find the viewport amongst the tabs in this alignment frame and close that
5292 public boolean closeView(AlignViewportI av)
5296 this.closeMenuItem_actionPerformed(false);
5299 Component[] comp = tabbedPane.getComponents();
5300 for (int i = 0; comp != null && i < comp.length; i++)
5302 if (comp[i] instanceof AlignmentPanel)
5304 if (((AlignmentPanel) comp[i]).av == av)
5307 closeView((AlignmentPanel) comp[i]);
5315 protected void build_fetchdbmenu(JMenu webService)
5317 // Temporary hack - DBRef Fetcher always top level ws entry.
5318 // TODO We probably want to store a sequence database checklist in
5319 // preferences and have checkboxes.. rather than individual sources selected
5321 final JMenu rfetch = new JMenu(
5322 MessageManager.getString("action.fetch_db_references"));
5323 rfetch.setToolTipText(MessageManager.getString(
5324 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5325 webService.add(rfetch);
5327 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5328 MessageManager.getString("option.trim_retrieved_seqs"));
5329 trimrs.setToolTipText(
5330 MessageManager.getString("label.trim_retrieved_sequences"));
5332 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5333 trimrs.addActionListener(new ActionListener()
5336 public void actionPerformed(ActionEvent e)
5338 trimrs.setSelected(trimrs.isSelected());
5339 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5340 Boolean.valueOf(trimrs.isSelected()).toString());
5344 JMenuItem fetchr = new JMenuItem(
5345 MessageManager.getString("label.standard_databases"));
5346 fetchr.setToolTipText(
5347 MessageManager.getString("label.fetch_embl_uniprot"));
5348 fetchr.addActionListener(new ActionListener()
5352 public void actionPerformed(ActionEvent e)
5354 new Thread(new Runnable()
5359 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5360 .getAlignment().isNucleotide();
5361 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5362 alignPanel.av.getSequenceSelection(),
5363 alignPanel.alignFrame, null,
5364 alignPanel.alignFrame.featureSettings, isNucleotide);
5365 dbRefFetcher.addListener(new FetchFinishedListenerI()
5368 public void finished()
5371 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5372 .getFeatureSettingsModels())
5375 alignPanel.av.mergeFeaturesStyle(srcSettings);
5377 AlignFrame.this.setMenusForViewport();
5380 dbRefFetcher.fetchDBRefs(false);
5388 new Thread(new Runnable()
5393 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5394 .getSequenceFetcherSingleton();
5395 javax.swing.SwingUtilities.invokeLater(new Runnable()
5400 String[] dbclasses = sf.getNonAlignmentSources();
5401 List<DbSourceProxy> otherdb;
5402 JMenu dfetch = new JMenu();
5403 JMenu ifetch = new JMenu();
5404 JMenuItem fetchr = null;
5405 int comp = 0, icomp = 0, mcomp = 15;
5406 String mname = null;
5408 for (String dbclass : dbclasses)
5410 otherdb = sf.getSourceProxy(dbclass);
5411 // add a single entry for this class, or submenu allowing 'fetch
5413 if (otherdb == null || otherdb.size() < 1)
5419 mname = "From " + dbclass;
5421 if (otherdb.size() == 1)
5423 final DbSourceProxy[] dassource = otherdb
5424 .toArray(new DbSourceProxy[0]);
5425 DbSourceProxy src = otherdb.get(0);
5426 fetchr = new JMenuItem(src.getDbSource());
5427 fetchr.addActionListener(new ActionListener()
5431 public void actionPerformed(ActionEvent e)
5433 new Thread(new Runnable()
5439 boolean isNucleotide = alignPanel.alignFrame
5440 .getViewport().getAlignment()
5442 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5443 alignPanel.av.getSequenceSelection(),
5444 alignPanel.alignFrame, dassource,
5445 alignPanel.alignFrame.featureSettings,
5448 .addListener(new FetchFinishedListenerI()
5451 public void finished()
5453 FeatureSettingsModelI srcSettings = dassource[0]
5454 .getFeatureColourScheme();
5455 alignPanel.av.mergeFeaturesStyle(
5457 AlignFrame.this.setMenusForViewport();
5460 dbRefFetcher.fetchDBRefs(false);
5466 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5467 MessageManager.formatMessage(
5468 "label.fetch_retrieve_from", new Object[]
5469 { src.getDbName() })));
5475 final DbSourceProxy[] dassource = otherdb
5476 .toArray(new DbSourceProxy[0]);
5478 DbSourceProxy src = otherdb.get(0);
5479 fetchr = new JMenuItem(MessageManager
5480 .formatMessage("label.fetch_all_param", new Object[]
5481 { src.getDbSource() }));
5482 fetchr.addActionListener(new ActionListener()
5485 public void actionPerformed(ActionEvent e)
5487 new Thread(new Runnable()
5493 boolean isNucleotide = alignPanel.alignFrame
5494 .getViewport().getAlignment()
5496 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5497 alignPanel.av.getSequenceSelection(),
5498 alignPanel.alignFrame, dassource,
5499 alignPanel.alignFrame.featureSettings,
5502 .addListener(new FetchFinishedListenerI()
5505 public void finished()
5507 AlignFrame.this.setMenusForViewport();
5510 dbRefFetcher.fetchDBRefs(false);
5516 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5517 MessageManager.formatMessage(
5518 "label.fetch_retrieve_from_all_sources",
5520 { Integer.valueOf(otherdb.size())
5522 src.getDbSource(), src.getDbName() })));
5525 // and then build the rest of the individual menus
5526 ifetch = new JMenu(MessageManager.formatMessage(
5527 "label.source_from_db_source", new Object[]
5528 { src.getDbSource() }));
5530 String imname = null;
5532 for (DbSourceProxy sproxy : otherdb)
5534 String dbname = sproxy.getDbName();
5535 String sname = dbname.length() > 5
5536 ? dbname.substring(0, 5) + "..."
5538 String msname = dbname.length() > 10
5539 ? dbname.substring(0, 10) + "..."
5543 imname = MessageManager
5544 .formatMessage("label.from_msname", new Object[]
5547 fetchr = new JMenuItem(msname);
5548 final DbSourceProxy[] dassrc = { sproxy };
5549 fetchr.addActionListener(new ActionListener()
5553 public void actionPerformed(ActionEvent e)
5555 new Thread(new Runnable()
5561 boolean isNucleotide = alignPanel.alignFrame
5562 .getViewport().getAlignment()
5564 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5565 alignPanel.av.getSequenceSelection(),
5566 alignPanel.alignFrame, dassrc,
5567 alignPanel.alignFrame.featureSettings,
5570 .addListener(new FetchFinishedListenerI()
5573 public void finished()
5575 AlignFrame.this.setMenusForViewport();
5578 dbRefFetcher.fetchDBRefs(false);
5584 fetchr.setToolTipText(
5585 "<html>" + MessageManager.formatMessage(
5586 "label.fetch_retrieve_from", new Object[]
5590 if (++icomp >= mcomp || i == (otherdb.size()))
5592 ifetch.setText(MessageManager.formatMessage(
5593 "label.source_to_target", imname, sname));
5595 ifetch = new JMenu();
5603 if (comp >= mcomp || dbi >= (dbclasses.length))
5605 dfetch.setText(MessageManager.formatMessage(
5606 "label.source_to_target", mname, dbclass));
5608 dfetch = new JMenu();
5621 * Left justify the whole alignment.
5624 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5626 AlignmentI al = viewport.getAlignment();
5628 viewport.firePropertyChange("alignment", null, al);
5632 * Right justify the whole alignment.
5635 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5637 AlignmentI al = viewport.getAlignment();
5639 viewport.firePropertyChange("alignment", null, al);
5643 public void setShowSeqFeatures(boolean b)
5645 showSeqFeatures.setSelected(b);
5646 viewport.setShowSequenceFeatures(b);
5653 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5654 * awt.event.ActionEvent)
5657 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5659 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5660 alignPanel.paintAlignment(false, false);
5667 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5671 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5673 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5674 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5682 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5683 * .event.ActionEvent)
5686 protected void showGroupConservation_actionPerformed(ActionEvent e)
5688 viewport.setShowGroupConservation(showGroupConservation.getState());
5689 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5696 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5697 * .event.ActionEvent)
5700 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5702 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5703 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5710 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5711 * .event.ActionEvent)
5714 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5716 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5717 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5721 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5723 showSequenceLogo.setState(true);
5724 viewport.setShowSequenceLogo(true);
5725 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5726 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5730 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5732 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5739 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5740 * .event.ActionEvent)
5743 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5745 if (avc.makeGroupsFromSelection())
5747 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5748 alignPanel.updateAnnotation();
5749 alignPanel.paintAlignment(true,
5750 viewport.needToUpdateStructureViews());
5754 public void clearAlignmentSeqRep()
5756 // TODO refactor alignmentseqrep to controller
5757 if (viewport.getAlignment().hasSeqrep())
5759 viewport.getAlignment().setSeqrep(null);
5760 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5761 alignPanel.updateAnnotation();
5762 alignPanel.paintAlignment(true, true);
5767 protected void createGroup_actionPerformed(ActionEvent e)
5769 if (avc.createGroup())
5771 if (applyAutoAnnotationSettings.isSelected())
5773 alignPanel.updateAnnotation(true, false);
5775 alignPanel.alignmentChanged();
5780 protected void unGroup_actionPerformed(ActionEvent e)
5784 alignPanel.alignmentChanged();
5789 * make the given alignmentPanel the currently selected tab
5791 * @param alignmentPanel
5793 public void setDisplayedView(AlignmentPanel alignmentPanel)
5795 if (!viewport.getSequenceSetId()
5796 .equals(alignmentPanel.av.getSequenceSetId()))
5798 throw new Error(MessageManager.getString(
5799 "error.implementation_error_cannot_show_view_alignment_frame"));
5801 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5802 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5804 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5809 * Action on selection of menu options to Show or Hide annotations.
5812 * @param forSequences
5813 * update sequence-related annotations
5814 * @param forAlignment
5815 * update non-sequence-related annotations
5818 public void setAnnotationsVisibility(boolean visible,
5819 boolean forSequences, boolean forAlignment)
5821 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5822 .getAlignmentAnnotation();
5827 for (AlignmentAnnotation aa : anns)
5830 * don't display non-positional annotations on an alignment
5832 if (aa.annotations == null)
5836 boolean apply = (aa.sequenceRef == null && forAlignment)
5837 || (aa.sequenceRef != null && forSequences);
5840 aa.visible = visible;
5843 alignPanel.validateAnnotationDimensions(true);
5844 alignPanel.alignmentChanged();
5848 * Store selected annotation sort order for the view and repaint.
5851 protected void sortAnnotations_actionPerformed()
5853 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5855 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5856 alignPanel.paintAlignment(false, false);
5861 * @return alignment panels in this alignment frame
5863 public List<? extends AlignmentViewPanel> getAlignPanels()
5865 // alignPanels is never null
5866 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5871 * Open a new alignment window, with the cDNA associated with this (protein)
5872 * alignment, aligned as is the protein.
5874 protected void viewAsCdna_actionPerformed()
5876 // TODO no longer a menu action - refactor as required
5877 final AlignmentI alignment = getViewport().getAlignment();
5878 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5879 if (mappings == null)
5883 List<SequenceI> cdnaSeqs = new ArrayList<>();
5884 for (SequenceI aaSeq : alignment.getSequences())
5886 for (AlignedCodonFrame acf : mappings)
5888 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5892 * There is a cDNA mapping for this protein sequence - add to new
5893 * alignment. It will share the same dataset sequence as other mapped
5894 * cDNA (no new mappings need to be created).
5896 final Sequence newSeq = new Sequence(dnaSeq);
5897 newSeq.setDatasetSequence(dnaSeq);
5898 cdnaSeqs.add(newSeq);
5902 if (cdnaSeqs.size() == 0)
5904 // show a warning dialog no mapped cDNA
5907 AlignmentI cdna = new Alignment(
5908 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5909 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5910 AlignFrame.DEFAULT_HEIGHT);
5911 cdna.alignAs(alignment);
5912 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5914 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5915 AlignFrame.DEFAULT_HEIGHT);
5919 * Set visibility of dna/protein complement view (available when shown in a
5925 protected void showComplement_actionPerformed(boolean show)
5927 SplitContainerI sf = getSplitViewContainer();
5930 sf.setComplementVisible(this, show);
5935 * Generate the reverse (optionally complemented) of the selected sequences,
5936 * and add them to the alignment
5939 protected void showReverse_actionPerformed(boolean complement)
5941 AlignmentI al = null;
5944 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5945 al = dna.reverseCdna(complement);
5946 viewport.addAlignment(al, "");
5947 addHistoryItem(new EditCommand(
5948 MessageManager.getString("label.add_sequences"), Action.PASTE,
5949 al.getSequencesArray(), 0, al.getWidth(),
5950 viewport.getAlignment()));
5951 } catch (Exception ex)
5953 jalview.bin.Console.errPrintln(ex.getMessage());
5959 * Try to run a script in the Groovy console, having first ensured that this
5960 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5961 * be targeted at this alignment.
5964 protected void runGroovy_actionPerformed()
5966 Jalview.setCurrentAlignFrame(this);
5967 groovy.ui.Console console = Desktop.getGroovyConsole();
5968 if (console != null)
5972 console.runScript();
5973 } catch (Exception ex)
5975 jalview.bin.Console.errPrintln((ex.toString()));
5976 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5977 MessageManager.getString("label.couldnt_run_groovy_script"),
5978 MessageManager.getString("label.groovy_support_failed"),
5979 JvOptionPane.ERROR_MESSAGE);
5985 .errPrintln("Can't run Groovy script as console not found");
5990 * Hides columns containing (or not containing) a specified feature, provided
5991 * that would not leave all columns hidden
5993 * @param featureType
5994 * @param columnsContaining
5997 public boolean hideFeatureColumns(String featureType,
5998 boolean columnsContaining)
6000 boolean notForHiding = avc.markColumnsContainingFeatures(
6001 columnsContaining, false, false, featureType);
6004 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
6005 false, featureType))
6007 getViewport().hideSelectedColumns();
6015 protected void selectHighlightedColumns_actionPerformed(
6016 ActionEvent actionEvent)
6018 // include key modifier check in case user selects from menu
6019 avc.markHighlightedColumns(
6020 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
6021 (actionEvent.getModifiers() & (ActionEvent.META_MASK
6022 | ActionEvent.CTRL_MASK)) != 0);
6026 protected void copyHighlightedColumns_actionPerformed(
6027 ActionEvent actionEvent)
6029 avc.copyHighlightedRegionsToClipboard();
6033 * Rebuilds the Colour menu, including any user-defined colours which have
6034 * been loaded either on startup or during the session
6036 public void buildColourMenu()
6038 colourMenu.removeAll();
6040 colourMenu.add(applyToAllGroups);
6041 colourMenu.add(textColour);
6042 colourMenu.addSeparator();
6044 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6045 viewport.getAlignment(), false);
6047 colourMenu.add(annotationColour);
6048 bg.add(annotationColour);
6049 colourMenu.addSeparator();
6050 colourMenu.add(conservationMenuItem);
6051 colourMenu.add(modifyConservation);
6052 colourMenu.add(abovePIDThreshold);
6053 colourMenu.add(modifyPID);
6055 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6056 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6060 * Open a dialog (if not already open) that allows the user to select and
6061 * calculate PCA or Tree analysis
6063 protected void openTreePcaDialog()
6065 if (alignPanel.getCalculationDialog() == null)
6067 new CalculationChooser(AlignFrame.this);
6072 protected void loadVcf_actionPerformed()
6074 JalviewFileChooser chooser = new JalviewFileChooser(
6075 Cache.getProperty("LAST_DIRECTORY"));
6076 chooser.setFileView(new JalviewFileView());
6077 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6078 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6079 final AlignFrame us = this;
6080 chooser.setResponseHandler(0, () -> {
6081 String choice = chooser.getSelectedFile().getPath();
6082 Cache.setProperty("LAST_DIRECTORY", choice);
6083 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6084 new VCFLoader(choice).loadVCF(seqs, us);
6086 chooser.showOpenDialog(null);
6090 private Rectangle lastFeatureSettingsBounds = null;
6093 public void setFeatureSettingsGeometry(Rectangle bounds)
6095 lastFeatureSettingsBounds = bounds;
6099 public Rectangle getFeatureSettingsGeometry()
6101 return lastFeatureSettingsBounds;
6106 class PrintThread extends Thread
6110 public PrintThread(AlignmentPanel ap)
6115 static PageFormat pf;
6120 PrinterJob printJob = PrinterJob.getPrinterJob();
6124 printJob.setPrintable(ap, pf);
6128 printJob.setPrintable(ap);
6131 if (printJob.printDialog())
6136 } catch (Exception PrintException)
6138 PrintException.printStackTrace();