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);
1258 public void saveAlignment(String file, FileFormatI format, boolean stdout)
1260 lastSaveSuccessful = true;
1263 lastFilenameSaved = file;
1265 lastFormatSaved = format;
1267 if (FileFormat.Jalview.equals(format))
1269 String shortName = title;
1270 if (shortName.indexOf(File.separatorChar) > -1)
1272 shortName = shortName
1273 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1275 // TODO deal with stdout=true
1276 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1279 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1280 if (lastSaveSuccessful)
1282 this.getViewport().setSavedUpToDate(true);
1285 statusBar.setText(MessageManager.formatMessage(
1286 "label.successfully_saved_to_file_in_format", new Object[]
1292 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1293 Runnable cancelAction = () -> {
1294 lastSaveSuccessful = false;
1296 Runnable outputAction = () -> {
1297 // todo defer this to inside formatSequences (or later)
1298 AlignmentExportData exportData = viewport.getAlignExportData(options);
1299 String output = new FormatAdapter(alignPanel, options)
1300 .formatSequences(format, exportData.getAlignment(),
1301 exportData.getOmitHidden(),
1302 exportData.getStartEndPostions(),
1303 viewport.getAlignment().getHiddenColumns());
1306 lastSaveSuccessful = false;
1310 // create backupfiles object and get new temp filename destination
1311 boolean doBackup = BackupFiles.getEnabled() && !stdout;
1312 BackupFiles backupfiles = null;
1315 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1316 backupfiles = new BackupFiles(file);
1320 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1322 Console.trace("ALIGNFRAME setting PrintWriter");
1323 PrintWriter out = stdout
1324 ? new PrintWriter(new OutputStreamWriter(System.out))
1325 : new PrintWriter(new FileWriter(tempFilePath));
1327 if (backupfiles != null)
1329 Console.trace("ALIGNFRAME about to write to temp file "
1330 + backupfiles.getTempFilePath());
1337 Console.trace("ALIGNFRAME about to close file");
1339 Console.trace("ALIGNFRAME closed file");
1341 AlignFrame.this.setTitle(stdout ? "STDOUT" : file);
1344 statusBar.setText(MessageManager.formatMessage(
1345 "label.successfully_printed_to_stdout_in_format",
1347 { format.getName() }));
1351 statusBar.setText(MessageManager.formatMessage(
1352 "label.successfully_saved_to_file_in_format",
1354 { fileName, format.getName() }));
1356 lastSaveSuccessful = true;
1357 } catch (IOException e)
1359 lastSaveSuccessful = false;
1361 "ALIGNFRAME Something happened writing the temp file");
1362 Console.error(e.getMessage());
1363 Console.debug(Cache.getStackTraceString(e));
1364 } catch (Exception ex)
1366 lastSaveSuccessful = false;
1368 "ALIGNFRAME Something unexpected happened writing the temp file");
1369 Console.error(ex.getMessage());
1370 Console.debug(Cache.getStackTraceString(ex));
1375 backupfiles.setWriteSuccess(lastSaveSuccessful);
1376 Console.debug("ALIGNFRAME writing temp file was "
1377 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1378 // do the backup file roll and rename the temp file to actual file
1379 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1380 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1381 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1382 + (lastSaveSuccessful ? "" : "un") + "successfully");
1385 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1386 if (lastSaveSuccessful)
1388 AlignFrame.this.getViewport().setSavedUpToDate(true);
1394 * show dialog with export options if applicable; else just do it
1396 if (AlignExportOptions.isNeeded(viewport, format))
1398 AlignExportOptions choices = new AlignExportOptions(
1399 alignPanel.getAlignViewport(), format, options);
1400 choices.setResponseAction(0, outputAction);
1401 choices.setResponseAction(1, cancelAction);
1402 choices.showDialog();
1409 } catch (Exception e)
1411 // TODO Auto-generated catch block
1412 e.printStackTrace();
1418 * Outputs the alignment to textbox in the requested format, if necessary
1419 * first prompting the user for whether to include hidden regions or
1422 * @param fileFormatName
1425 protected void outputText_actionPerformed(String fileFormatName)
1427 FileFormatI fileFormat = FileFormats.getInstance()
1428 .forName(fileFormatName);
1429 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1430 Runnable outputAction = () -> {
1431 // todo defer this to inside formatSequences (or later)
1432 AlignmentExportData exportData = viewport.getAlignExportData(options);
1433 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1434 cap.setForInput(null);
1437 FileFormatI format = fileFormat;
1438 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1439 format, exportData.getAlignment(),
1440 exportData.getOmitHidden(),
1441 exportData.getStartEndPostions(),
1442 viewport.getAlignment().getHiddenColumns()));
1443 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1444 "label.alignment_output_command", new Object[]
1445 { fileFormat.getName() }), 600, 500);
1446 } catch (OutOfMemoryError oom)
1448 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1455 * show dialog with export options if applicable; else just do it
1457 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1459 AlignExportOptions choices = new AlignExportOptions(
1460 alignPanel.getAlignViewport(), fileFormat, options);
1461 choices.setResponseAction(0, outputAction);
1462 choices.showDialog();
1469 } catch (Exception e)
1471 e.printStackTrace();
1483 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1485 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1488 htmlSVG.exportHTML(null);
1489 } catch (ImageOutputException x)
1491 // report problem to console and raise dialog
1496 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1498 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1501 bjs.exportHTML(null);
1502 } catch (ImageOutputException x)
1504 // report problem to console and raise dialog
1508 public void createImageMap(File file, String image)
1512 alignPanel.makePNGImageMap(file, image);
1513 } catch (ImageOutputException x)
1515 // report problem to console and raise dialog
1520 public void createPNG_actionPerformed(ActionEvent e)
1525 } catch (ImageOutputException ioex)
1527 // raise dialog, and report via console
1532 public void createEPS_actionPerformed(ActionEvent e)
1537 } catch (ImageOutputException ioex)
1539 // raise dialog, and report via console
1545 public void createSVG_actionPerformed(ActionEvent e)
1550 } catch (ImageOutputException ioex)
1552 // raise dialog, and report via console
1558 * Creates a PNG image of the alignment and writes it to the given file. If
1559 * the file is null, the user is prompted to choose a file.
1563 public void createPNG(File f) throws ImageOutputException
1565 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1568 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1569 throws ImageOutputException
1571 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1575 * Creates an EPS image of the alignment and writes it to the given file. If
1576 * the file is null, the user is prompted to choose a file.
1580 public void createEPS(File f) throws ImageOutputException
1585 public void createEPS(File f, String renderer) throws ImageOutputException
1587 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1591 * Creates an SVG image of the alignment and writes it to the given file. If
1592 * the file is null, the user is prompted to choose a file.
1596 public void createSVG(File f) throws ImageOutputException
1601 public void createSVG(File f, String renderer) throws ImageOutputException
1603 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1607 public void pageSetup_actionPerformed(ActionEvent e)
1609 PrinterJob printJob = PrinterJob.getPrinterJob();
1610 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1620 public void printMenuItem_actionPerformed(ActionEvent e)
1622 // Putting in a thread avoids Swing painting problems
1623 PrintThread thread = new PrintThread(alignPanel);
1628 public void exportFeatures_actionPerformed(ActionEvent e)
1630 new AnnotationExporter(alignPanel).exportFeatures();
1634 public void exportAnnotations_actionPerformed(ActionEvent e)
1636 new AnnotationExporter(alignPanel).exportAnnotations();
1640 public void associatedData_actionPerformed(ActionEvent e)
1642 final JalviewFileChooser chooser = new JalviewFileChooser(
1643 Cache.getProperty("LAST_DIRECTORY"));
1644 chooser.setFileView(new JalviewFileView());
1645 String tooltip = MessageManager
1646 .getString("label.load_jalview_annotations");
1647 chooser.setDialogTitle(tooltip);
1648 chooser.setToolTipText(tooltip);
1649 chooser.setResponseHandler(0, () -> {
1650 String choice = chooser.getSelectedFile().getPath();
1651 Cache.setProperty("LAST_DIRECTORY", choice);
1652 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1655 chooser.showOpenDialog(this);
1659 * Close the current view or all views in the alignment frame. If the frame
1660 * only contains one view then the alignment will be removed from memory.
1662 * @param closeAllTabs
1665 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1667 if (alignPanels != null && alignPanels.size() < 2)
1669 closeAllTabs = true;
1674 if (alignPanels != null)
1678 if (this.isClosed())
1680 // really close all the windows - otherwise wait till
1681 // setClosed(true) is called
1682 for (int i = 0; i < alignPanels.size(); i++)
1684 AlignmentPanel ap = alignPanels.get(i);
1691 closeView(alignPanel);
1696 if (featureSettings != null && featureSettings.isOpen())
1698 featureSettings.close();
1699 featureSettings = null;
1702 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1703 * be called recursively, with the frame now in 'closed' state
1705 this.setClosed(true);
1707 } catch (Exception ex)
1709 ex.printStackTrace();
1714 * Close the specified panel and close up tabs appropriately.
1716 * @param panelToClose
1718 public void closeView(AlignmentPanel panelToClose)
1720 int index = tabbedPane.getSelectedIndex();
1721 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1722 alignPanels.remove(panelToClose);
1723 panelToClose.closePanel();
1724 panelToClose = null;
1726 tabbedPane.removeTabAt(closedindex);
1727 tabbedPane.validate();
1729 if (index > closedindex || index == tabbedPane.getTabCount())
1731 // modify currently selected tab index if necessary.
1735 this.tabSelectionChanged(index);
1741 void updateEditMenuBar()
1744 if (viewport.getHistoryList().size() > 0)
1746 undoMenuItem.setEnabled(true);
1747 CommandI command = viewport.getHistoryList().peek();
1748 undoMenuItem.setText(MessageManager
1749 .formatMessage("label.undo_command", new Object[]
1750 { command.getDescription() }));
1754 undoMenuItem.setEnabled(false);
1755 undoMenuItem.setText(MessageManager.getString("action.undo"));
1758 if (viewport.getRedoList().size() > 0)
1760 redoMenuItem.setEnabled(true);
1762 CommandI command = viewport.getRedoList().peek();
1763 redoMenuItem.setText(MessageManager
1764 .formatMessage("label.redo_command", new Object[]
1765 { command.getDescription() }));
1769 redoMenuItem.setEnabled(false);
1770 redoMenuItem.setText(MessageManager.getString("action.redo"));
1775 public void addHistoryItem(CommandI command)
1777 if (command.getSize() > 0)
1779 viewport.addToHistoryList(command);
1780 viewport.clearRedoList();
1781 updateEditMenuBar();
1782 viewport.updateHiddenColumns();
1783 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1784 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1785 // viewport.getColumnSelection()
1786 // .getHiddenColumns().size() > 0);
1792 * @return alignment objects for all views
1794 AlignmentI[] getViewAlignments()
1796 if (alignPanels != null)
1798 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1800 for (AlignmentPanel ap : alignPanels)
1802 als[i++] = ap.av.getAlignment();
1806 if (viewport != null)
1808 return new AlignmentI[] { viewport.getAlignment() };
1820 protected void undoMenuItem_actionPerformed(ActionEvent e)
1822 if (viewport.getHistoryList().isEmpty())
1826 CommandI command = viewport.getHistoryList().pop();
1827 viewport.addToRedoList(command);
1828 command.undoCommand(getViewAlignments());
1830 AlignmentViewport originalSource = getOriginatingSource(command);
1831 updateEditMenuBar();
1833 if (originalSource != null)
1835 if (originalSource != viewport)
1838 "Implementation worry: mismatch of viewport origin for undo");
1840 originalSource.updateHiddenColumns();
1841 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1843 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1844 // viewport.getColumnSelection()
1845 // .getHiddenColumns().size() > 0);
1846 originalSource.firePropertyChange("alignment", null,
1847 originalSource.getAlignment().getSequences());
1858 protected void redoMenuItem_actionPerformed(ActionEvent e)
1860 if (viewport.getRedoList().size() < 1)
1865 CommandI command = viewport.getRedoList().pop();
1866 viewport.addToHistoryList(command);
1867 command.doCommand(getViewAlignments());
1869 AlignmentViewport originalSource = getOriginatingSource(command);
1870 updateEditMenuBar();
1872 if (originalSource != null)
1875 if (originalSource != viewport)
1878 "Implementation worry: mismatch of viewport origin for redo");
1880 originalSource.updateHiddenColumns();
1881 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1883 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1884 // viewport.getColumnSelection()
1885 // .getHiddenColumns().size() > 0);
1886 originalSource.firePropertyChange("alignment", null,
1887 originalSource.getAlignment().getSequences());
1891 AlignmentViewport getOriginatingSource(CommandI command)
1893 AlignmentViewport originalSource = null;
1894 // For sequence removal and addition, we need to fire
1895 // the property change event FROM the viewport where the
1896 // original alignment was altered
1897 AlignmentI al = null;
1898 if (command instanceof EditCommand)
1900 EditCommand editCommand = (EditCommand) command;
1901 al = editCommand.getAlignment();
1902 List<Component> comps = PaintRefresher.components
1903 .get(viewport.getSequenceSetId());
1905 for (Component comp : comps)
1907 if (comp instanceof AlignmentPanel)
1909 if (al == ((AlignmentPanel) comp).av.getAlignment())
1911 originalSource = ((AlignmentPanel) comp).av;
1918 if (originalSource == null)
1920 // The original view is closed, we must validate
1921 // the current view against the closed view first
1924 PaintRefresher.validateSequences(al, viewport.getAlignment());
1927 originalSource = viewport;
1930 return originalSource;
1934 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1935 * or the sequence under cursor in keyboard mode
1940 public void moveSelectedSequences(boolean up)
1942 SequenceGroup sg = viewport.getSelectionGroup();
1946 if (viewport.cursorMode)
1948 sg = new SequenceGroup();
1949 sg.addSequence(viewport.getAlignment().getSequenceAt(
1950 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1958 if (sg.getSize() < 1)
1963 // TODO: JAL-3733 - add an event to the undo buffer for this !
1965 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1966 viewport.getHiddenRepSequences(), up);
1967 alignPanel.paintAlignment(true, false);
1970 synchronized void slideSequences(boolean right, int size)
1972 List<SequenceI> sg = new ArrayList<>();
1973 if (viewport.cursorMode)
1975 sg.add(viewport.getAlignment()
1976 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1978 else if (viewport.getSelectionGroup() != null
1979 && viewport.getSelectionGroup().getSize() != viewport
1980 .getAlignment().getHeight())
1982 sg = viewport.getSelectionGroup()
1983 .getSequences(viewport.getHiddenRepSequences());
1991 List<SequenceI> invertGroup = new ArrayList<>();
1993 for (SequenceI seq : viewport.getAlignment().getSequences())
1995 if (!sg.contains(seq))
1997 invertGroup.add(seq);
2001 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
2003 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
2004 for (int i = 0; i < invertGroup.size(); i++)
2006 seqs2[i] = invertGroup.get(i);
2009 SlideSequencesCommand ssc;
2012 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
2013 viewport.getGapCharacter());
2017 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
2018 viewport.getGapCharacter());
2021 int groupAdjustment = 0;
2022 if (ssc.getGapsInsertedBegin() && right)
2024 if (viewport.cursorMode)
2026 alignPanel.getSeqPanel().moveCursor(size, 0);
2030 groupAdjustment = size;
2033 else if (!ssc.getGapsInsertedBegin() && !right)
2035 if (viewport.cursorMode)
2037 alignPanel.getSeqPanel().moveCursor(-size, 0);
2041 groupAdjustment = -size;
2045 if (groupAdjustment != 0)
2047 viewport.getSelectionGroup().setStartRes(
2048 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
2049 viewport.getSelectionGroup().setEndRes(
2050 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
2054 * just extend the last slide command if compatible; but not if in
2055 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
2057 boolean appendHistoryItem = false;
2058 Deque<CommandI> historyList = viewport.getHistoryList();
2059 boolean inSplitFrame = getSplitViewContainer() != null;
2060 if (!inSplitFrame && historyList != null && historyList.size() > 0
2061 && historyList.peek() instanceof SlideSequencesCommand)
2063 appendHistoryItem = ssc.appendSlideCommand(
2064 (SlideSequencesCommand) historyList.peek());
2067 if (!appendHistoryItem)
2069 addHistoryItem(ssc);
2082 protected void copy_actionPerformed()
2084 if (viewport.getSelectionGroup() == null)
2088 // TODO: preserve the ordering of displayed alignment annotation in any
2089 // internal paste (particularly sequence associated annotation)
2090 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2091 String[] omitHidden = null;
2093 if (viewport.hasHiddenColumns())
2095 omitHidden = viewport.getViewAsString(true);
2098 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2099 seqs, omitHidden, null);
2101 StringSelection ss = new StringSelection(output);
2105 jalview.gui.Desktop.internalCopy = true;
2106 // Its really worth setting the clipboard contents
2107 // to empty before setting the large StringSelection!!
2108 Toolkit.getDefaultToolkit().getSystemClipboard()
2109 .setContents(new StringSelection(""), null);
2111 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2113 } catch (OutOfMemoryError er)
2115 new OOMWarning("copying region", er);
2119 HiddenColumns hiddenColumns = null;
2120 if (viewport.hasHiddenColumns())
2122 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2123 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2125 // create new HiddenColumns object with copy of hidden regions
2126 // between startRes and endRes, offset by startRes
2127 hiddenColumns = new HiddenColumns(
2128 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2129 hiddenCutoff, hiddenOffset);
2132 Desktop.jalviewClipboard = new Object[] { seqs,
2133 viewport.getAlignment().getDataset(), hiddenColumns };
2134 setStatus(MessageManager.formatMessage(
2135 "label.copied_sequences_to_clipboard", new Object[]
2136 { Integer.valueOf(seqs.length).toString() }));
2146 protected void pasteNew_actionPerformed(ActionEvent e)
2158 protected void pasteThis_actionPerformed(ActionEvent e)
2164 * Paste contents of Jalview clipboard
2166 * @param newAlignment
2167 * true to paste to a new alignment, otherwise add to this.
2169 void paste(boolean newAlignment)
2171 boolean externalPaste = true;
2174 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2175 Transferable contents = c.getContents(this);
2177 if (contents == null)
2186 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2187 if (str.length() < 1)
2192 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2194 } catch (OutOfMemoryError er)
2196 new OOMWarning("Out of memory pasting sequences!!", er);
2200 SequenceI[] sequences;
2201 boolean annotationAdded = false;
2202 AlignmentI alignment = null;
2204 if (Desktop.jalviewClipboard != null)
2206 // The clipboard was filled from within Jalview, we must use the
2208 // And dataset from the copied alignment
2209 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2210 // be doubly sure that we create *new* sequence objects.
2211 sequences = new SequenceI[newseq.length];
2212 for (int i = 0; i < newseq.length; i++)
2214 sequences[i] = new Sequence(newseq[i]);
2216 alignment = new Alignment(sequences);
2217 externalPaste = false;
2221 // parse the clipboard as an alignment.
2222 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2224 sequences = alignment.getSequencesArray();
2228 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2234 if (Desktop.jalviewClipboard != null)
2236 // dataset is inherited
2237 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2241 // new dataset is constructed
2242 alignment.setDataset(null);
2244 alwidth = alignment.getWidth() + 1;
2248 AlignmentI pastedal = alignment; // preserve pasted alignment object
2249 // Add pasted sequences and dataset into existing alignment.
2250 alignment = viewport.getAlignment();
2251 alwidth = alignment.getWidth() + 1;
2252 // decide if we need to import sequences from an existing dataset
2253 boolean importDs = Desktop.jalviewClipboard != null
2254 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2255 // importDs==true instructs us to copy over new dataset sequences from
2256 // an existing alignment
2257 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2259 // minimum dataset set
2261 for (int i = 0; i < sequences.length; i++)
2265 newDs.addElement(null);
2267 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2269 if (importDs && ds != null)
2271 if (!newDs.contains(ds))
2273 newDs.setElementAt(ds, i);
2274 ds = new Sequence(ds);
2275 // update with new dataset sequence
2276 sequences[i].setDatasetSequence(ds);
2280 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2285 // copy and derive new dataset sequence
2286 sequences[i] = sequences[i].deriveSequence();
2287 alignment.getDataset()
2288 .addSequence(sequences[i].getDatasetSequence());
2289 // TODO: avoid creation of duplicate dataset sequences with a
2290 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2292 alignment.addSequence(sequences[i]); // merges dataset
2296 newDs.clear(); // tidy up
2298 if (alignment.getAlignmentAnnotation() != null)
2300 for (AlignmentAnnotation alan : alignment
2301 .getAlignmentAnnotation())
2303 if (alan.graphGroup > fgroup)
2305 fgroup = alan.graphGroup;
2309 if (pastedal.getAlignmentAnnotation() != null)
2311 // Add any annotation attached to alignment.
2312 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2313 for (int i = 0; i < alann.length; i++)
2315 annotationAdded = true;
2316 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2318 AlignmentAnnotation newann = new AlignmentAnnotation(
2320 if (newann.graphGroup > -1)
2322 if (newGraphGroups.size() <= newann.graphGroup
2323 || newGraphGroups.get(newann.graphGroup) == null)
2325 for (int q = newGraphGroups
2326 .size(); q <= newann.graphGroup; q++)
2328 newGraphGroups.add(q, null);
2330 newGraphGroups.set(newann.graphGroup,
2331 Integer.valueOf(++fgroup));
2333 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2337 newann.padAnnotation(alwidth);
2338 alignment.addAnnotation(newann);
2348 addHistoryItem(new EditCommand(
2349 MessageManager.getString("label.add_sequences"),
2350 Action.PASTE, sequences, 0, alignment.getWidth(),
2353 // Add any annotations attached to sequences
2354 for (int i = 0; i < sequences.length; i++)
2356 if (sequences[i].getAnnotation() != null)
2358 AlignmentAnnotation newann;
2359 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2361 annotationAdded = true;
2362 newann = sequences[i].getAnnotation()[a];
2363 newann.adjustForAlignment();
2364 newann.padAnnotation(alwidth);
2365 if (newann.graphGroup > -1)
2367 if (newann.graphGroup > -1)
2369 if (newGraphGroups.size() <= newann.graphGroup
2370 || newGraphGroups.get(newann.graphGroup) == null)
2372 for (int q = newGraphGroups
2373 .size(); q <= newann.graphGroup; q++)
2375 newGraphGroups.add(q, null);
2377 newGraphGroups.set(newann.graphGroup,
2378 Integer.valueOf(++fgroup));
2380 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2384 // annotation was duplicated earlier
2385 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2386 // take care of contact matrix too
2387 ContactMatrixI cm = sequences[i]
2388 .getContactMatrixFor(sequences[i].getAnnotation()[a]);
2391 alignment.addContactListFor(sequences[i].getAnnotation()[a],
2395 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2403 // propagate alignment changed.
2404 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2405 if (annotationAdded)
2407 // Duplicate sequence annotation in all views.
2408 AlignmentI[] alview = this.getViewAlignments();
2409 for (int i = 0; i < sequences.length; i++)
2411 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2416 for (int avnum = 0; avnum < alview.length; avnum++)
2418 if (alview[avnum] != alignment)
2420 // duplicate in a view other than the one with input focus
2421 int avwidth = alview[avnum].getWidth() + 1;
2422 // this relies on sann being preserved after we
2423 // modify the sequence's annotation array for each duplication
2424 for (int a = 0; a < sann.length; a++)
2426 AlignmentAnnotation newann = new AlignmentAnnotation(
2428 sequences[i].addAlignmentAnnotation(newann);
2429 newann.padAnnotation(avwidth);
2430 alview[avnum].addAnnotation(newann); // annotation was
2431 // duplicated earlier
2432 // TODO JAL-1145 graphGroups are not updated for sequence
2433 // annotation added to several views. This may cause
2435 alview[avnum].setAnnotationIndex(newann, a);
2440 buildSortByAnnotationScoresMenu();
2442 viewport.firePropertyChange("alignment", null,
2443 alignment.getSequences());
2444 if (alignPanels != null)
2446 for (AlignmentPanel ap : alignPanels)
2448 ap.validateAnnotationDimensions(false);
2453 alignPanel.validateAnnotationDimensions(false);
2459 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2461 String newtitle = new String("Copied sequences");
2463 if (Desktop.jalviewClipboard != null
2464 && Desktop.jalviewClipboard[2] != null)
2466 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2467 af.viewport.setHiddenColumns(hc);
2470 // >>>This is a fix for the moment, until a better solution is
2472 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2473 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2474 .getFeatureRenderer());
2476 // TODO: maintain provenance of an alignment, rather than just make the
2477 // title a concatenation of operations.
2480 if (title.startsWith("Copied sequences"))
2486 newtitle = newtitle.concat("- from " + title);
2491 newtitle = new String("Pasted sequences");
2494 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2499 } catch (Exception ex)
2501 ex.printStackTrace();
2502 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2503 // could be anything being pasted in here
2509 protected void expand_newalign(ActionEvent e)
2513 AlignmentI alignment = AlignmentUtils
2514 .expandContext(getViewport().getAlignment(), -1);
2515 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2517 String newtitle = new String("Flanking alignment");
2519 if (Desktop.jalviewClipboard != null
2520 && Desktop.jalviewClipboard[2] != null)
2522 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2523 af.viewport.setHiddenColumns(hc);
2526 // >>>This is a fix for the moment, until a better solution is
2528 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2529 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2530 .getFeatureRenderer());
2532 // TODO: maintain provenance of an alignment, rather than just make the
2533 // title a concatenation of operations.
2535 if (title.startsWith("Copied sequences"))
2541 newtitle = newtitle.concat("- from " + title);
2545 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2547 } catch (Exception ex)
2549 ex.printStackTrace();
2550 jalview.bin.Console.outPrintln("Exception whilst pasting: " + ex);
2551 // could be anything being pasted in here
2552 } catch (OutOfMemoryError oom)
2554 new OOMWarning("Viewing flanking region of alignment", oom);
2559 * Action Cut (delete and copy) the selected region
2562 protected void cut_actionPerformed()
2564 copy_actionPerformed();
2565 delete_actionPerformed();
2569 * Performs menu option to Delete the currently selected region
2572 protected void delete_actionPerformed()
2575 SequenceGroup sg = viewport.getSelectionGroup();
2581 Runnable okAction = () -> {
2582 SequenceI[] cut = sg.getSequences()
2583 .toArray(new SequenceI[sg.getSize()]);
2585 addHistoryItem(new EditCommand(
2586 MessageManager.getString("label.cut_sequences"), Action.CUT,
2587 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2588 viewport.getAlignment()));
2590 viewport.setSelectionGroup(null);
2591 viewport.sendSelection();
2592 viewport.getAlignment().deleteGroup(sg);
2594 viewport.firePropertyChange("alignment", null,
2595 viewport.getAlignment().getSequences());
2596 if (viewport.getAlignment().getHeight() < 1)
2600 AlignFrame.this.setClosed(true);
2601 } catch (Exception ex)
2608 * If the cut affects all sequences, prompt for confirmation
2610 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2612 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2613 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2614 if (wholeHeight && wholeWidth)
2616 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2617 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2618 Object[] options = new Object[] {
2619 MessageManager.getString("action.ok"),
2620 MessageManager.getString("action.cancel") };
2621 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2622 MessageManager.getString("label.delete_all"),
2623 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2624 options, options[0]);
2631 } catch (Exception e)
2633 e.printStackTrace();
2645 protected void deleteGroups_actionPerformed(ActionEvent e)
2647 if (avc.deleteGroups())
2649 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2650 alignPanel.updateAnnotation();
2651 alignPanel.paintAlignment(true, true);
2662 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2664 SequenceGroup sg = new SequenceGroup(
2665 viewport.getAlignment().getSequences());
2667 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2668 viewport.setSelectionGroup(sg);
2669 viewport.isSelectionGroupChanged(true);
2670 viewport.sendSelection();
2671 // JAL-2034 - should delegate to
2672 // alignPanel to decide if overview needs
2674 alignPanel.paintAlignment(false, false);
2675 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2685 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2687 if (viewport.cursorMode)
2689 alignPanel.getSeqPanel().keyboardNo1 = null;
2690 alignPanel.getSeqPanel().keyboardNo2 = null;
2692 viewport.setSelectionGroup(null);
2693 viewport.getColumnSelection().clear();
2694 viewport.setSearchResults(null);
2695 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2696 // JAL-2034 - should delegate to
2697 // alignPanel to decide if overview needs
2699 alignPanel.paintAlignment(false, false);
2700 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2701 viewport.sendSelection();
2711 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2713 SequenceGroup sg = viewport.getSelectionGroup();
2717 selectAllSequenceMenuItem_actionPerformed(null);
2722 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2724 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2726 // JAL-2034 - should delegate to
2727 // alignPanel to decide if overview needs
2730 alignPanel.paintAlignment(true, false);
2731 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2732 viewport.sendSelection();
2736 public void invertColSel_actionPerformed(ActionEvent e)
2738 viewport.invertColumnSelection();
2739 alignPanel.paintAlignment(true, false);
2740 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2741 viewport.sendSelection();
2751 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2753 trimAlignment(true);
2763 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2765 trimAlignment(false);
2768 void trimAlignment(boolean trimLeft)
2770 ColumnSelection colSel = viewport.getColumnSelection();
2773 if (!colSel.isEmpty())
2777 column = colSel.getMin();
2781 column = colSel.getMax();
2785 if (viewport.getSelectionGroup() != null)
2787 seqs = viewport.getSelectionGroup()
2788 .getSequencesAsArray(viewport.getHiddenRepSequences());
2792 seqs = viewport.getAlignment().getSequencesArray();
2795 TrimRegionCommand trimRegion;
2798 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2799 column, viewport.getAlignment());
2800 viewport.getRanges().setStartRes(0);
2804 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2805 column, viewport.getAlignment());
2808 setStatus(MessageManager.formatMessage("label.removed_columns",
2810 { Integer.valueOf(trimRegion.getSize()).toString() }));
2812 addHistoryItem(trimRegion);
2814 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2816 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2817 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2819 viewport.getAlignment().deleteGroup(sg);
2823 viewport.firePropertyChange("alignment", null,
2824 viewport.getAlignment().getSequences());
2835 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2837 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2840 if (viewport.getSelectionGroup() != null)
2842 seqs = viewport.getSelectionGroup()
2843 .getSequencesAsArray(viewport.getHiddenRepSequences());
2844 start = viewport.getSelectionGroup().getStartRes();
2845 end = viewport.getSelectionGroup().getEndRes();
2849 seqs = viewport.getAlignment().getSequencesArray();
2852 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2853 "Remove Gapped Columns", seqs, start, end,
2854 viewport.getAlignment());
2856 addHistoryItem(removeGapCols);
2858 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2860 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2862 // This is to maintain viewport position on first residue
2863 // of first sequence
2864 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2865 ViewportRanges ranges = viewport.getRanges();
2866 int startRes = seq.findPosition(ranges.getStartRes());
2867 // ShiftList shifts;
2868 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2869 // edit.alColumnChanges=shifts.getInverse();
2870 // if (viewport.hasHiddenColumns)
2871 // viewport.getColumnSelection().compensateForEdits(shifts);
2872 ranges.setStartRes(seq.findIndex(startRes) - 1);
2873 viewport.firePropertyChange("alignment", null,
2874 viewport.getAlignment().getSequences());
2885 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2887 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2890 if (viewport.getSelectionGroup() != null)
2892 seqs = viewport.getSelectionGroup()
2893 .getSequencesAsArray(viewport.getHiddenRepSequences());
2894 start = viewport.getSelectionGroup().getStartRes();
2895 end = viewport.getSelectionGroup().getEndRes();
2899 seqs = viewport.getAlignment().getSequencesArray();
2902 // This is to maintain viewport position on first residue
2903 // of first sequence
2904 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2905 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2907 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2908 viewport.getAlignment()));
2910 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2912 viewport.firePropertyChange("alignment", null,
2913 viewport.getAlignment().getSequences());
2924 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2926 viewport.setPadGaps(padGapsMenuitem.isSelected());
2927 viewport.firePropertyChange("alignment", null,
2928 viewport.getAlignment().getSequences());
2932 * Opens a Finder dialog
2937 public void findMenuItem_actionPerformed(ActionEvent e)
2939 new Finder(alignPanel, false, null);
2943 * Create a new view of the current alignment.
2946 public void newView_actionPerformed(ActionEvent e)
2948 newView(null, true);
2952 * Creates and shows a new view of the current alignment.
2955 * title of newly created view; if null, one will be generated
2956 * @param copyAnnotation
2957 * if true then duplicate all annnotation, groups and settings
2958 * @return new alignment panel, already displayed.
2960 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2963 * Create a new AlignmentPanel (with its own, new Viewport)
2965 AlignmentPanel newap = new jalview.project.Jalview2XML()
2966 .copyAlignPanel(alignPanel);
2967 if (!copyAnnotation)
2970 * remove all groups and annotation except for the automatic stuff
2972 newap.av.getAlignment().deleteAllGroups();
2973 newap.av.getAlignment().deleteAllAnnotations(false);
2976 newap.av.setGatherViewsHere(false);
2978 if (viewport.getViewName() == null)
2980 viewport.setViewName(
2981 MessageManager.getString("label.view_name_original"));
2985 * Views share the same edits undo and redo stacks
2987 newap.av.setHistoryList(viewport.getHistoryList());
2988 newap.av.setRedoList(viewport.getRedoList());
2991 * copy any visualisation settings that are not saved in the project
2993 newap.av.setColourAppliesToAllGroups(
2994 viewport.getColourAppliesToAllGroups());
2997 * Views share the same mappings; need to deregister any new mappings
2998 * created by copyAlignPanel, and register the new reference to the shared
3001 newap.av.replaceMappings(viewport.getAlignment());
3004 * start up cDNA consensus (if applicable) now mappings are in place
3006 if (newap.av.initComplementConsensus())
3008 newap.refresh(true); // adjust layout of annotations
3011 newap.av.setViewName(getNewViewName(viewTitle));
3013 addAlignmentPanel(newap, true);
3014 newap.alignmentChanged();
3016 if (alignPanels.size() == 2)
3018 viewport.setGatherViewsHere(true);
3020 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
3026 * Make a new name for the view, ensuring it is unique within the current
3027 * sequenceSetId. (This used to be essential for Jalview Project archives, but
3028 * these now use viewId. Unique view names are still desirable for usability.)
3033 protected String getNewViewName(String viewTitle)
3035 int index = Desktop.getViewCount(viewport.getSequenceSetId());
3036 boolean addFirstIndex = false;
3037 if (viewTitle == null || viewTitle.trim().length() == 0)
3039 viewTitle = MessageManager.getString("action.view");
3040 addFirstIndex = true;
3044 index = 1;// we count from 1 if given a specific name
3046 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
3048 List<Component> comps = PaintRefresher.components
3049 .get(viewport.getSequenceSetId());
3051 List<String> existingNames = getExistingViewNames(comps);
3053 while (existingNames.contains(newViewName))
3055 newViewName = viewTitle + " " + (++index);
3061 * Returns a list of distinct view names found in the given list of
3062 * components. View names are held on the viewport of an AlignmentPanel.
3067 protected List<String> getExistingViewNames(List<Component> comps)
3069 List<String> existingNames = new ArrayList<>();
3070 for (Component comp : comps)
3072 if (comp instanceof AlignmentPanel)
3074 AlignmentPanel ap = (AlignmentPanel) comp;
3075 if (!existingNames.contains(ap.av.getViewName()))
3077 existingNames.add(ap.av.getViewName());
3081 return existingNames;
3085 * Explode tabbed views into separate windows.
3088 public void expandViews_actionPerformed(ActionEvent e)
3090 Desktop.explodeViews(this);
3094 * Gather views in separate windows back into a tabbed presentation.
3097 public void gatherViews_actionPerformed(ActionEvent e)
3099 Desktop.instance.gatherViews(this);
3109 public void font_actionPerformed(ActionEvent e)
3111 new FontChooser(alignPanel);
3121 protected void seqLimit_actionPerformed(ActionEvent e)
3123 viewport.setShowJVSuffix(seqLimits.isSelected());
3125 alignPanel.getIdPanel().getIdCanvas()
3126 .setPreferredSize(alignPanel.calculateIdWidth());
3127 alignPanel.paintAlignment(true, false);
3131 public void idRightAlign_actionPerformed(ActionEvent e)
3133 viewport.setRightAlignIds(idRightAlign.isSelected());
3134 alignPanel.paintAlignment(false, false);
3138 public void centreColumnLabels_actionPerformed(ActionEvent e)
3140 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3141 alignPanel.paintAlignment(false, false);
3147 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3150 protected void followHighlight_actionPerformed()
3153 * Set the 'follow' flag on the Viewport (and scroll to position if now
3156 final boolean state = this.followHighlightMenuItem.getState();
3157 viewport.setFollowHighlight(state);
3160 alignPanel.scrollToPosition(viewport.getSearchResults());
3171 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3173 viewport.setColourText(colourTextMenuItem.isSelected());
3174 alignPanel.paintAlignment(false, false);
3184 public void wrapMenuItem_actionPerformed(ActionEvent e)
3186 setWrapFormat(wrapMenuItem.isSelected(), false);
3189 public void setWrapFormat(boolean b, boolean setMenuItem)
3191 scaleAbove.setVisible(b);
3192 scaleLeft.setVisible(b);
3193 scaleRight.setVisible(b);
3194 viewport.setWrapAlignment(b);
3195 alignPanel.updateLayout();
3198 wrapMenuItem.setSelected(b);
3203 public void showAllSeqs_actionPerformed(ActionEvent e)
3205 viewport.showAllHiddenSeqs();
3209 public void showAllColumns_actionPerformed(ActionEvent e)
3211 viewport.showAllHiddenColumns();
3212 alignPanel.paintAlignment(true, true);
3213 viewport.sendSelection();
3217 public void hideSelSequences_actionPerformed(ActionEvent e)
3219 viewport.hideAllSelectedSeqs();
3223 * called by key handler and the hide all/show all menu items
3228 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3231 boolean hide = false;
3232 SequenceGroup sg = viewport.getSelectionGroup();
3233 if (!toggleSeqs && !toggleCols)
3235 // Hide everything by the current selection - this is a hack - we do the
3236 // invert and then hide
3237 // first check that there will be visible columns after the invert.
3238 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3239 && sg.getStartRes() <= sg.getEndRes()))
3241 // now invert the sequence set, if required - empty selection implies
3242 // that no hiding is required.
3245 invertSequenceMenuItem_actionPerformed(null);
3246 sg = viewport.getSelectionGroup();
3250 viewport.expandColSelection(sg, true);
3251 // finally invert the column selection and get the new sequence
3253 invertColSel_actionPerformed(null);
3260 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3262 hideSelSequences_actionPerformed(null);
3265 else if (!(toggleCols && viewport.hasSelectedColumns()))
3267 showAllSeqs_actionPerformed(null);
3273 if (viewport.hasSelectedColumns())
3275 hideSelColumns_actionPerformed(null);
3278 viewport.setSelectionGroup(sg);
3283 showAllColumns_actionPerformed(null);
3292 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3293 * event.ActionEvent)
3296 public void hideAllButSelection_actionPerformed(ActionEvent e)
3298 toggleHiddenRegions(false, false);
3299 viewport.sendSelection();
3306 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3310 public void hideAllSelection_actionPerformed(ActionEvent e)
3312 SequenceGroup sg = viewport.getSelectionGroup();
3313 viewport.expandColSelection(sg, false);
3314 viewport.hideAllSelectedSeqs();
3315 viewport.hideSelectedColumns();
3316 alignPanel.updateLayout();
3317 alignPanel.paintAlignment(true, true);
3318 viewport.sendSelection();
3325 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3329 public void showAllhidden_actionPerformed(ActionEvent e)
3331 viewport.showAllHiddenColumns();
3332 viewport.showAllHiddenSeqs();
3333 alignPanel.paintAlignment(true, true);
3334 viewport.sendSelection();
3338 public void hideSelColumns_actionPerformed(ActionEvent e)
3340 viewport.hideSelectedColumns();
3341 alignPanel.updateLayout();
3342 alignPanel.paintAlignment(true, true);
3343 viewport.sendSelection();
3347 public void hiddenMarkers_actionPerformed(ActionEvent e)
3349 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3360 protected void scaleAbove_actionPerformed(ActionEvent e)
3362 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3363 alignPanel.updateLayout();
3364 alignPanel.paintAlignment(true, false);
3374 protected void scaleLeft_actionPerformed(ActionEvent e)
3376 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3377 alignPanel.updateLayout();
3378 alignPanel.paintAlignment(true, false);
3388 protected void scaleRight_actionPerformed(ActionEvent e)
3390 viewport.setScaleRightWrapped(scaleRight.isSelected());
3391 alignPanel.updateLayout();
3392 alignPanel.paintAlignment(true, false);
3402 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3404 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3405 alignPanel.paintAlignment(false, false);
3415 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3417 viewport.setShowText(viewTextMenuItem.isSelected());
3418 alignPanel.paintAlignment(false, false);
3428 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3430 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3431 alignPanel.paintAlignment(false, false);
3434 public FeatureSettings featureSettings;
3437 public FeatureSettingsControllerI getFeatureSettingsUI()
3439 return featureSettings;
3443 public void featureSettings_actionPerformed(ActionEvent e)
3445 showFeatureSettingsUI();
3449 public FeatureSettingsControllerI showFeatureSettingsUI()
3451 if (featureSettings != null)
3453 featureSettings.closeOldSettings();
3454 featureSettings = null;
3456 if (!showSeqFeatures.isSelected())
3458 // make sure features are actually displayed
3459 showSeqFeatures.setSelected(true);
3460 showSeqFeatures_actionPerformed(null);
3462 featureSettings = new FeatureSettings(this);
3463 return featureSettings;
3467 * Set or clear 'Show Sequence Features'
3473 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3475 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3476 alignPanel.paintAlignment(true, true);
3480 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3481 * the annotations panel as a whole.
3483 * The options to show/hide all annotations should be enabled when the panel
3484 * is shown, and disabled when the panel is hidden.
3489 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3491 final boolean setVisible = annotationPanelMenuItem.isSelected();
3492 viewport.setShowAnnotation(setVisible);
3493 this.showAllSeqAnnotations.setEnabled(setVisible);
3494 this.hideAllSeqAnnotations.setEnabled(setVisible);
3495 this.showAllAlAnnotations.setEnabled(setVisible);
3496 this.hideAllAlAnnotations.setEnabled(setVisible);
3497 alignPanel.updateLayout();
3501 public void alignmentProperties()
3504 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3507 String content = MessageManager.formatMessage("label.html_content",
3509 { contents.toString() });
3512 if (Platform.isJS())
3514 JLabel textLabel = new JLabel();
3515 textLabel.setText(content);
3516 textLabel.setBackground(Color.WHITE);
3518 pane = new JPanel(new BorderLayout());
3519 ((JPanel) pane).setOpaque(true);
3520 pane.setBackground(Color.WHITE);
3521 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3530 JEditorPane editPane = new JEditorPane("text/html", "");
3531 editPane.setEditable(false);
3532 editPane.setText(content);
3536 JInternalFrame frame = new JInternalFrame();
3537 frame.setFrameIcon(null);
3538 frame.getContentPane().add(new JScrollPane(pane));
3540 Desktop.addInternalFrame(frame, MessageManager
3541 .formatMessage("label.alignment_properties", new Object[]
3542 { getTitle() }), 500, 400);
3546 * Opens an Overview panel for the alignment, unless one is open already
3551 public void overviewMenuItem_actionPerformed(ActionEvent e)
3553 boolean showHiddenRegions = Cache
3554 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3555 openOverviewPanel(showHiddenRegions);
3558 public OverviewPanel openOverviewPanel(boolean showHidden)
3560 if (alignPanel.overviewPanel != null)
3562 return alignPanel.overviewPanel;
3564 JInternalFrame frame = new JInternalFrame();
3565 frame.setFrameIcon(null);
3566 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3568 frame.setContentPane(overview);
3569 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3570 frame.getHeight(), true, true);
3572 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3573 final AlignmentPanel thePanel = this.alignPanel;
3574 frame.addInternalFrameListener(
3575 new javax.swing.event.InternalFrameAdapter()
3578 public void internalFrameClosed(
3579 javax.swing.event.InternalFrameEvent evt)
3582 thePanel.setOverviewPanel(null);
3585 if (getKeyListeners().length > 0)
3587 frame.addKeyListener(getKeyListeners()[0]);
3590 alignPanel.setOverviewPanel(overview);
3591 alignPanel.setOverviewTitle(this);
3597 public void textColour_actionPerformed()
3599 new TextColourChooser().chooseColour(alignPanel, null);
3603 * public void covariationColour_actionPerformed() {
3605 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3609 public void annotationColour_actionPerformed()
3611 new AnnotationColourChooser(viewport, alignPanel);
3615 public void annotationColumn_actionPerformed(ActionEvent e)
3617 new AnnotationColumnChooser(viewport, alignPanel);
3621 * Action on the user checking or unchecking the option to apply the selected
3622 * colour scheme to all groups. If unchecked, groups may have their own
3623 * independent colour schemes.
3628 public void applyToAllGroups_actionPerformed(boolean selected)
3630 viewport.setColourAppliesToAllGroups(selected);
3634 * Action on user selecting a colour from the colour menu
3637 * the name (not the menu item label!) of the colour scheme
3640 public void changeColour_actionPerformed(String name)
3643 * 'User Defined' opens a panel to configure or load a
3644 * user-defined colour scheme
3646 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3648 new UserDefinedColours(alignPanel);
3653 * otherwise set the chosen colour scheme (or null for 'None')
3655 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3656 viewport, viewport.getAlignment(),
3657 viewport.getHiddenRepSequences());
3662 * Actions on setting or changing the alignment colour scheme
3667 public void changeColour(ColourSchemeI cs)
3669 // TODO: pull up to controller method
3670 ColourMenuHelper.setColourSelected(colourMenu, cs);
3672 viewport.setGlobalColourScheme(cs);
3674 alignPanel.paintAlignment(true, true);
3678 * Show the PID threshold slider panel
3681 protected void modifyPID_actionPerformed()
3683 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3684 alignPanel.getViewName());
3685 SliderPanel.showPIDSlider();
3689 * Show the Conservation slider panel
3692 protected void modifyConservation_actionPerformed()
3694 SliderPanel.setConservationSlider(alignPanel,
3695 viewport.getResidueShading(), alignPanel.getViewName());
3696 SliderPanel.showConservationSlider();
3700 * Action on selecting or deselecting (Colour) By Conservation
3703 public void conservationMenuItem_actionPerformed(boolean selected)
3705 modifyConservation.setEnabled(selected);
3706 viewport.setConservationSelected(selected);
3707 viewport.getResidueShading().setConservationApplied(selected);
3709 changeColour(viewport.getGlobalColourScheme());
3712 modifyConservation_actionPerformed();
3716 SliderPanel.hideConservationSlider();
3721 * Action on selecting or deselecting (Colour) Above PID Threshold
3724 public void abovePIDThreshold_actionPerformed(boolean selected)
3726 modifyPID.setEnabled(selected);
3727 viewport.setAbovePIDThreshold(selected);
3730 viewport.getResidueShading().setThreshold(0,
3731 viewport.isIgnoreGapsConsensus());
3734 changeColour(viewport.getGlobalColourScheme());
3737 modifyPID_actionPerformed();
3741 SliderPanel.hidePIDSlider();
3752 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3754 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3755 AlignmentSorter.sortByPID(viewport.getAlignment(),
3756 viewport.getAlignment().getSequenceAt(0));
3757 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3758 viewport.getAlignment()));
3759 alignPanel.paintAlignment(true, false);
3769 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3771 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3772 AlignmentSorter.sortByID(viewport.getAlignment());
3774 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3775 alignPanel.paintAlignment(true, false);
3785 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3787 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3788 AlignmentSorter.sortByLength(viewport.getAlignment());
3789 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3790 viewport.getAlignment()));
3791 alignPanel.paintAlignment(true, false);
3801 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3803 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3804 AlignmentSorter.sortByGroup(viewport.getAlignment());
3805 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3806 viewport.getAlignment()));
3808 alignPanel.paintAlignment(true, false);
3818 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3820 new RedundancyPanel(alignPanel, this);
3830 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3832 if ((viewport.getSelectionGroup() == null)
3833 || (viewport.getSelectionGroup().getSize() < 2))
3835 JvOptionPane.showInternalMessageDialog(this,
3836 MessageManager.getString(
3837 "label.you_must_select_least_two_sequences"),
3838 MessageManager.getString("label.invalid_selection"),
3839 JvOptionPane.WARNING_MESSAGE);
3843 JInternalFrame frame = new JInternalFrame();
3844 frame.setFrameIcon(null);
3845 frame.setContentPane(new PairwiseAlignPanel(viewport));
3846 Desktop.addInternalFrame(frame,
3847 MessageManager.getString("action.pairwise_alignment"), 600,
3853 public void autoCalculate_actionPerformed(ActionEvent e)
3855 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3856 if (viewport.autoCalculateConsensus)
3858 viewport.firePropertyChange("alignment", null,
3859 viewport.getAlignment().getSequences());
3864 public void sortByTreeOption_actionPerformed(ActionEvent e)
3866 viewport.sortByTree = sortByTree.isSelected();
3870 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3872 viewport.followSelection = listenToViewSelections.isSelected();
3876 * Constructs a tree panel and adds it to the desktop
3879 * tree type (NJ or AV)
3881 * name of score model used to compute the tree
3883 * parameters for the distance or similarity calculation
3885 void newTreePanel(String type, String modelName,
3886 SimilarityParamsI options)
3888 String frameTitle = "";
3891 boolean onSelection = false;
3892 if (viewport.getSelectionGroup() != null
3893 && viewport.getSelectionGroup().getSize() > 0)
3895 SequenceGroup sg = viewport.getSelectionGroup();
3897 /* Decide if the selection is a column region */
3898 for (SequenceI _s : sg.getSequences())
3900 if (_s.getLength() < sg.getEndRes())
3902 JvOptionPane.showMessageDialog(Desktop.desktop,
3903 MessageManager.getString(
3904 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3905 MessageManager.getString(
3906 "label.sequences_selection_not_aligned"),
3907 JvOptionPane.WARNING_MESSAGE);
3916 if (viewport.getAlignment().getHeight() < 2)
3922 tp = new TreePanel(alignPanel, type, modelName, options);
3923 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3925 frameTitle += " from ";
3927 if (viewport.getViewName() != null)
3929 frameTitle += viewport.getViewName() + " of ";
3932 frameTitle += this.title;
3934 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3945 public void addSortByOrderMenuItem(String title,
3946 final AlignmentOrder order)
3948 final JMenuItem item = new JMenuItem(MessageManager
3949 .formatMessage("action.by_title_param", new Object[]
3952 item.addActionListener(new java.awt.event.ActionListener()
3955 public void actionPerformed(ActionEvent e)
3957 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3959 // TODO: JBPNote - have to map order entries to curent SequenceI
3961 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3963 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3964 viewport.getAlignment()));
3966 alignPanel.paintAlignment(true, false);
3972 * Add a new sort by annotation score menu item
3975 * the menu to add the option to
3977 * the label used to retrieve scores for each sequence on the
3980 public void addSortByAnnotScoreMenuItem(JMenu sort,
3981 final String scoreLabel)
3983 final JMenuItem item = new JMenuItem(scoreLabel);
3985 item.addActionListener(new java.awt.event.ActionListener()
3988 public void actionPerformed(ActionEvent e)
3990 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3991 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3992 viewport.getAlignment());// ,viewport.getSelectionGroup());
3993 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3994 viewport.getAlignment()));
3995 alignPanel.paintAlignment(true, false);
4001 * last hash for alignment's annotation array - used to minimise cost of
4004 protected int _annotationScoreVectorHash;
4007 * search the alignment and rebuild the sort by annotation score submenu the
4008 * last alignment annotation vector hash is stored to minimize cost of
4009 * rebuilding in subsequence calls.
4013 public void buildSortByAnnotationScoresMenu()
4015 if (viewport.getAlignment().getAlignmentAnnotation() == null)
4020 if (viewport.getAlignment().getAlignmentAnnotation()
4021 .hashCode() != _annotationScoreVectorHash)
4023 sortByAnnotScore.removeAll();
4024 // almost certainly a quicker way to do this - but we keep it simple
4025 Hashtable<String, String> scoreSorts = new Hashtable<>();
4026 AlignmentAnnotation aann[];
4027 for (SequenceI sqa : viewport.getAlignment().getSequences())
4029 aann = sqa.getAnnotation();
4030 for (int i = 0; aann != null && i < aann.length; i++)
4032 if (aann[i].hasScore() && aann[i].sequenceRef != null)
4034 scoreSorts.put(aann[i].label, aann[i].label);
4038 Enumeration<String> labels = scoreSorts.keys();
4039 while (labels.hasMoreElements())
4041 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
4043 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
4046 _annotationScoreVectorHash = viewport.getAlignment()
4047 .getAlignmentAnnotation().hashCode();
4052 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
4053 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
4054 * call. Listeners are added to remove the menu item when the treePanel is
4055 * closed, and adjust the tree leaf to sequence mapping when the alignment is
4059 public void buildTreeSortMenu()
4061 sortByTreeMenu.removeAll();
4063 List<Component> comps = PaintRefresher.components
4064 .get(viewport.getSequenceSetId());
4065 List<TreePanel> treePanels = new ArrayList<>();
4066 for (Component comp : comps)
4068 if (comp instanceof TreePanel)
4070 treePanels.add((TreePanel) comp);
4074 if (treePanels.size() < 1)
4076 sortByTreeMenu.setVisible(false);
4080 sortByTreeMenu.setVisible(true);
4082 for (final TreePanel tp : treePanels)
4084 final JMenuItem item = new JMenuItem(tp.getTitle());
4085 item.addActionListener(new java.awt.event.ActionListener()
4088 public void actionPerformed(ActionEvent e)
4090 tp.sortByTree_actionPerformed();
4091 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4096 sortByTreeMenu.add(item);
4100 public boolean sortBy(AlignmentOrder alorder, String undoname)
4102 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4103 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4104 if (undoname != null)
4106 addHistoryItem(new OrderCommand(undoname, oldOrder,
4107 viewport.getAlignment()));
4109 alignPanel.paintAlignment(true, false);
4114 * Work out whether the whole set of sequences or just the selected set will
4115 * be submitted for multiple alignment.
4118 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4120 // Now, check we have enough sequences
4121 AlignmentView msa = null;
4123 if ((viewport.getSelectionGroup() != null)
4124 && (viewport.getSelectionGroup().getSize() > 1))
4126 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4127 // some common interface!
4129 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4130 * SequenceI[sz = seqs.getSize(false)];
4132 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4133 * seqs.getSequenceAt(i); }
4135 msa = viewport.getAlignmentView(true);
4137 else if (viewport.getSelectionGroup() != null
4138 && viewport.getSelectionGroup().getSize() == 1)
4140 int option = JvOptionPane.showConfirmDialog(this,
4141 MessageManager.getString("warn.oneseq_msainput_selection"),
4142 MessageManager.getString("label.invalid_selection"),
4143 JvOptionPane.OK_CANCEL_OPTION);
4144 if (option == JvOptionPane.OK_OPTION)
4146 msa = viewport.getAlignmentView(false);
4151 msa = viewport.getAlignmentView(false);
4157 * Decides what is submitted to a secondary structure prediction service: the
4158 * first sequence in the alignment, or in the current selection, or, if the
4159 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4160 * region or the whole alignment. (where the first sequence in the set is the
4161 * one that the prediction will be for).
4163 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4165 AlignmentView seqs = null;
4167 if ((viewport.getSelectionGroup() != null)
4168 && (viewport.getSelectionGroup().getSize() > 0))
4170 seqs = viewport.getAlignmentView(true);
4174 seqs = viewport.getAlignmentView(false);
4176 // limit sequences - JBPNote in future - could spawn multiple prediction
4178 // TODO: viewport.getAlignment().isAligned is a global state - the local
4179 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4180 if (!viewport.getAlignment().isAligned(false))
4182 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4183 // TODO: if seqs.getSequences().length>1 then should really have warned
4197 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4199 // Pick the tree file
4200 JalviewFileChooser chooser = new JalviewFileChooser(
4201 Cache.getProperty("LAST_DIRECTORY"));
4202 chooser.setFileView(new JalviewFileView());
4203 chooser.setDialogTitle(
4204 MessageManager.getString("label.select_newick_like_tree_file"));
4205 chooser.setToolTipText(
4206 MessageManager.getString("label.load_tree_file"));
4208 chooser.setResponseHandler(0, () -> {
4209 String filePath = chooser.getSelectedFile().getPath();
4210 Cache.setProperty("LAST_DIRECTORY", filePath);
4211 NewickFile fin = null;
4214 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4215 DataSourceType.FILE));
4216 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4217 } catch (Exception ex)
4219 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4220 MessageManager.getString("label.problem_reading_tree_file"),
4221 JvOptionPane.WARNING_MESSAGE);
4222 ex.printStackTrace();
4224 if (fin != null && fin.hasWarningMessage())
4226 JvOptionPane.showMessageDialog(Desktop.desktop,
4227 fin.getWarningMessage(),
4229 .getString("label.possible_problem_with_tree_file"),
4230 JvOptionPane.WARNING_MESSAGE);
4233 chooser.showOpenDialog(this);
4236 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4238 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4241 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4242 int h, int x, int y)
4244 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4248 * Add a treeviewer for the tree extracted from a Newick file object to the
4249 * current alignment view
4256 * Associated alignment input data (or null)
4265 * @return TreePanel handle
4267 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4268 AlignmentView input, int w, int h, int x, int y)
4270 TreePanel tp = null;
4276 if (nf.getTree() != null)
4278 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4284 tp.setLocation(x, y);
4287 Desktop.addInternalFrame(tp, treeTitle, w, h);
4289 } catch (Exception ex)
4291 ex.printStackTrace();
4297 public void showContactMapTree(AlignmentAnnotation aa, ContactMatrixI cm)
4300 int w = 400, h = 500;
4304 NewickFile fin = new NewickFile(
4305 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4306 String title = aa.label + " " + cm.getTreeMethod() + " tree"
4307 + (aa.sequenceRef != null
4308 ? (" for " + aa.sequenceRef.getDisplayId(false))
4311 showColumnWiseTree(fin, aa, title, w, h, x, y);
4312 } catch (Throwable xx)
4314 Console.error("Unexpected exception showing tree for contact matrix",
4319 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4320 String treeTitle, int w, int h, int x, int y)
4325 if (nf.getTree() == null)
4329 TreePanel tp = new TreePanel(alignPanel, nf, aa, treeTitle);
4335 tp.setLocation(x, y);
4338 Desktop.addInternalFrame(tp, treeTitle, w, h);
4340 } catch (Throwable xx)
4342 Console.error("Unexpected exception showing tree for contact matrix",
4348 private boolean buildingMenu = false;
4351 * Generates menu items and listener event actions for web service clients
4354 public void BuildWebServiceMenu()
4356 while (buildingMenu)
4361 .errPrintln("Waiting for building menu to finish.");
4363 } catch (Exception e)
4367 final AlignFrame me = this;
4368 buildingMenu = true;
4369 new Thread(new Runnable()
4374 final List<JMenuItem> legacyItems = new ArrayList<>();
4377 // jalview.bin.Console.errPrintln("Building ws menu again "
4378 // + Thread.currentThread());
4379 // TODO: add support for context dependent disabling of services based
4381 // alignment and current selection
4382 // TODO: add additional serviceHandle parameter to specify abstract
4384 // class independently of AbstractName
4385 // TODO: add in rediscovery GUI function to restart discoverer
4386 // TODO: group services by location as well as function and/or
4388 // object broker mechanism.
4389 final Vector<JMenu> wsmenu = new Vector<>();
4390 final IProgressIndicator af = me;
4393 * do not i18n these strings - they are hard-coded in class
4394 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4395 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4397 final JMenu msawsmenu = new JMenu("Alignment");
4398 final JMenu secstrmenu = new JMenu(
4399 "Secondary Structure Prediction");
4400 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4401 final JMenu analymenu = new JMenu("Analysis");
4402 final JMenu dismenu = new JMenu("Protein Disorder");
4403 // JAL-940 - only show secondary structure prediction services from
4404 // the legacy server
4405 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4407 Discoverer.services != null && (Discoverer.services.size() > 0))
4409 // TODO: refactor to allow list of AbstractName/Handler bindings to
4411 // stored or retrieved from elsewhere
4412 // No MSAWS used any more:
4413 // Vector msaws = null; // (Vector)
4414 // Discoverer.services.get("MsaWS");
4415 Vector<ServiceHandle> secstrpr = Discoverer.services
4417 if (secstrpr != null)
4419 // Add any secondary structure prediction services
4420 for (int i = 0, j = secstrpr.size(); i < j; i++)
4422 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4423 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4424 .getServiceClient(sh);
4425 int p = secstrmenu.getItemCount();
4426 impl.attachWSMenuEntry(secstrmenu, me);
4427 int q = secstrmenu.getItemCount();
4428 for (int litm = p; litm < q; litm++)
4430 legacyItems.add(secstrmenu.getItem(litm));
4436 // Add all submenus in the order they should appear on the web
4438 wsmenu.add(msawsmenu);
4439 wsmenu.add(secstrmenu);
4440 wsmenu.add(dismenu);
4441 wsmenu.add(analymenu);
4442 // No search services yet
4443 // wsmenu.add(seqsrchmenu);
4445 javax.swing.SwingUtilities.invokeLater(new Runnable()
4452 webService.removeAll();
4453 // first, add discovered services onto the webservices menu
4454 if (wsmenu.size() > 0)
4456 for (int i = 0, j = wsmenu.size(); i < j; i++)
4458 webService.add(wsmenu.get(i));
4463 webService.add(me.webServiceNoServices);
4465 // TODO: move into separate menu builder class.
4467 // logic for 2.11.1.4 is
4468 // always look to see if there is a discover. if there isn't
4469 // we can't show any Jws2 services
4470 // if there are services available, show them - regardless of
4471 // the 'show JWS2 preference'
4472 // if the discoverer is running then say so
4473 // otherwise offer to trigger discovery if 'show JWS2' is not
4475 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4476 if (jws2servs != null)
4478 if (jws2servs.hasServices())
4480 jws2servs.attachWSMenuEntry(webService, me);
4481 for (Jws2Instance sv : jws2servs.getServices())
4483 if (sv.description.toLowerCase(Locale.ROOT)
4486 for (JMenuItem jmi : legacyItems)
4488 jmi.setVisible(false);
4494 if (jws2servs.isRunning())
4496 JMenuItem tm = new JMenuItem(
4497 "Still discovering JABA Services");
4498 tm.setEnabled(false);
4501 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4503 JMenuItem enableJws2 = new JMenuItem(
4504 "Discover Web Services");
4505 enableJws2.setToolTipText(
4506 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4507 enableJws2.setEnabled(true);
4508 enableJws2.addActionListener(new ActionListener()
4512 public void actionPerformed(ActionEvent e)
4514 // start service discoverer, but ignore preference
4515 Desktop.instance.startServiceDiscovery(false,
4519 webService.add(enableJws2);
4523 build_urlServiceMenu(me.webService);
4524 build_fetchdbmenu(webService);
4525 for (JMenu item : wsmenu)
4527 if (item.getItemCount() == 0)
4529 item.setEnabled(false);
4533 item.setEnabled(true);
4536 } catch (Exception e)
4539 "Exception during web service menu building process.",
4544 } catch (Exception e)
4547 buildingMenu = false;
4554 * construct any groupURL type service menu entries.
4558 protected void build_urlServiceMenu(JMenu webService)
4560 // TODO: remove this code when 2.7 is released
4561 // DEBUG - alignmentView
4563 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4564 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4566 * @Override public void actionPerformed(ActionEvent e) {
4567 * jalview.datamodel.AlignmentView
4568 * .testSelectionViews(af.viewport.getAlignment(),
4569 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4571 * }); webService.add(testAlView);
4573 // TODO: refactor to RestClient discoverer and merge menu entries for
4574 // rest-style services with other types of analysis/calculation service
4575 // SHmmr test client - still being implemented.
4576 // DEBUG - alignmentView
4578 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4581 client.attachWSMenuEntry(
4582 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4588 * Searches the alignment sequences for xRefs and builds the Show
4589 * Cross-References menu (formerly called Show Products), with database
4590 * sources for which cross-references are found (protein sources for a
4591 * nucleotide alignment and vice versa)
4593 * @return true if Show Cross-references menu should be enabled
4595 public boolean canShowProducts()
4597 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4598 AlignmentI dataset = viewport.getAlignment().getDataset();
4600 showProducts.removeAll();
4601 final boolean dna = viewport.getAlignment().isNucleotide();
4603 if (seqs == null || seqs.length == 0)
4605 // nothing to see here.
4609 boolean showp = false;
4612 List<String> ptypes = new CrossRef(seqs, dataset)
4613 .findXrefSourcesForSequences(dna);
4615 for (final String source : ptypes)
4618 final AlignFrame af = this;
4619 JMenuItem xtype = new JMenuItem(source);
4620 xtype.addActionListener(new ActionListener()
4623 public void actionPerformed(ActionEvent e)
4625 showProductsFor(af.viewport.getSequenceSelection(), dna,
4629 showProducts.add(xtype);
4631 showProducts.setVisible(showp);
4632 showProducts.setEnabled(showp);
4633 } catch (Exception e)
4636 "canShowProducts threw an exception - please report to help@jalview.org",
4644 * Finds and displays cross-references for the selected sequences (protein
4645 * products for nucleotide sequences, dna coding sequences for peptides).
4648 * the sequences to show cross-references for
4650 * true if from a nucleotide alignment (so showing proteins)
4652 * the database to show cross-references for
4654 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4655 final String source)
4657 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4662 * Construct and display a new frame containing the translation of this
4663 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4666 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4668 AlignmentI al = null;
4671 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4673 al = dna.translateCdna(codeTable);
4674 } catch (Exception ex)
4676 Console.error("Exception during translation. Please report this !",
4678 final String msg = MessageManager.getString(
4679 "label.error_when_translating_sequences_submit_bug_report");
4680 final String errorTitle = MessageManager
4681 .getString("label.implementation_error")
4682 + MessageManager.getString("label.translation_failed");
4683 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4684 JvOptionPane.ERROR_MESSAGE);
4687 if (al == null || al.getHeight() == 0)
4689 final String msg = MessageManager.getString(
4690 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4691 final String errorTitle = MessageManager
4692 .getString("label.translation_failed");
4693 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4694 JvOptionPane.WARNING_MESSAGE);
4698 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4699 af.setFileFormat(this.currentFileFormat);
4700 final String newTitle = MessageManager
4701 .formatMessage("label.translation_of_params", new Object[]
4702 { this.getTitle(), codeTable.getId() });
4703 af.setTitle(newTitle);
4704 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4706 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4707 viewport.openSplitFrame(af, new Alignment(seqs));
4711 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4718 * Set the file format
4722 public void setFileFormat(FileFormatI format)
4724 this.currentFileFormat = format;
4728 * Try to load a features file onto the alignment.
4731 * contents or path to retrieve file or a File object
4733 * access mode of file (see jalview.io.AlignFile)
4734 * @return true if features file was parsed correctly.
4736 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4739 return avc.parseFeaturesFile(file, sourceType,
4740 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4745 public void refreshFeatureUI(boolean enableIfNecessary)
4747 // note - currently this is only still here rather than in the controller
4748 // because of the featureSettings hard reference that is yet to be
4750 if (enableIfNecessary)
4752 viewport.setShowSequenceFeatures(true);
4753 showSeqFeatures.setSelected(true);
4759 public void dragEnter(DropTargetDragEvent evt)
4764 public void dragExit(DropTargetEvent evt)
4769 public void dragOver(DropTargetDragEvent evt)
4774 public void dropActionChanged(DropTargetDragEvent evt)
4779 public void drop(DropTargetDropEvent evt)
4781 // JAL-1552 - acceptDrop required before getTransferable call for
4782 // Java's Transferable for native dnd
4783 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4784 Transferable t = evt.getTransferable();
4786 final AlignFrame thisaf = this;
4787 final List<Object> files = new ArrayList<>();
4788 List<DataSourceType> protocols = new ArrayList<>();
4792 Desktop.transferFromDropTarget(files, protocols, evt, t);
4793 } catch (Exception e)
4795 e.printStackTrace();
4799 new Thread(new Runnable()
4806 // check to see if any of these files have names matching sequences
4809 SequenceIdMatcher idm = new SequenceIdMatcher(
4810 viewport.getAlignment().getSequencesArray());
4812 * Object[] { String,SequenceI}
4814 ArrayList<Object[]> filesmatched = new ArrayList<>();
4815 ArrayList<Object> filesnotmatched = new ArrayList<>();
4816 for (int i = 0; i < files.size(); i++)
4819 Object file = files.get(i);
4820 String fileName = file.toString();
4822 DataSourceType protocol = (file instanceof File
4823 ? DataSourceType.FILE
4824 : FormatAdapter.checkProtocol(fileName));
4825 if (protocol == DataSourceType.FILE)
4828 if (file instanceof File)
4831 Platform.cacheFileData(fl);
4835 fl = new File(fileName);
4837 pdbfn = fl.getName();
4839 else if (protocol == DataSourceType.URL)
4841 URL url = new URL(fileName);
4842 pdbfn = url.getFile();
4844 if (pdbfn.length() > 0)
4846 // attempt to find a match in the alignment
4847 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4848 int l = 0, c = pdbfn.indexOf(".");
4849 while (mtch == null && c != -1)
4854 } while ((c = pdbfn.indexOf(".", l)) > l);
4857 pdbfn = pdbfn.substring(0, l);
4859 mtch = idm.findAllIdMatches(pdbfn);
4866 type = new IdentifyFile().identify(file, protocol);
4867 } catch (Exception ex)
4871 if (type != null && type.isStructureFile())
4873 filesmatched.add(new Object[] { file, protocol, mtch });
4877 // File wasn't named like one of the sequences or wasn't a PDB
4879 filesnotmatched.add(file);
4883 if (filesmatched.size() > 0)
4885 boolean autoAssociate = Cache
4886 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4889 String msg = MessageManager.formatMessage(
4890 "label.automatically_associate_structure_files_with_sequences_same_name",
4892 { Integer.valueOf(filesmatched.size())
4894 String ttl = MessageManager.getString(
4895 "label.automatically_associate_structure_files_by_name");
4896 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4897 ttl, JvOptionPane.YES_NO_OPTION);
4898 autoAssociate = choice == JvOptionPane.YES_OPTION;
4902 for (Object[] fm : filesmatched)
4904 // try and associate
4905 // TODO: may want to set a standard ID naming formalism for
4906 // associating PDB files which have no IDs.
4907 for (SequenceI toassoc : (SequenceI[]) fm[2])
4909 PDBEntry pe = new AssociatePdbFileWithSeq()
4910 .associatePdbWithSeq(fm[0].toString(),
4911 (DataSourceType) fm[1], toassoc, false,
4915 jalview.bin.Console.errPrintln("Associated file : "
4916 + (fm[0].toString()) + " with "
4917 + toassoc.getDisplayId(true));
4921 // TODO: do we need to update overview ? only if features are
4923 alignPanel.paintAlignment(true, false);
4929 * add declined structures as sequences
4931 for (Object[] o : filesmatched)
4933 filesnotmatched.add(o[0]);
4937 if (filesnotmatched.size() > 0)
4939 if (assocfiles > 0 && (Cache.getDefault(
4940 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4941 || JvOptionPane.showConfirmDialog(thisaf,
4942 "<html>" + MessageManager.formatMessage(
4943 "label.ignore_unmatched_dropped_files_info",
4946 filesnotmatched.size())
4949 MessageManager.getString(
4950 "label.ignore_unmatched_dropped_files"),
4951 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4955 for (Object fn : filesnotmatched)
4957 loadJalviewDataFile(fn, null, null, null);
4961 } catch (Exception ex)
4963 ex.printStackTrace();
4971 * Attempt to load a "dropped" file or URL string, by testing in turn for
4973 * <li>an Annotation file</li>
4974 * <li>a JNet file</li>
4975 * <li>a features file</li>
4976 * <li>else try to interpret as an alignment file</li>
4980 * either a filename or a URL string.
4982 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4983 FileFormatI format, SequenceI assocSeq)
4985 // BH 2018 was String file
4988 if (sourceType == null)
4990 sourceType = FormatAdapter.checkProtocol(file);
4992 // if the file isn't identified, or not positively identified as some
4993 // other filetype (PFAM is default unidentified alignment file type) then
4994 // try to parse as annotation.
4995 boolean isAnnotation = (format == null
4996 || FileFormat.Pfam.equals(format))
4997 ? new AnnotationFile().annotateAlignmentView(viewport,
5003 // first see if its a T-COFFEE score file
5004 TCoffeeScoreFile tcf = null;
5007 tcf = new TCoffeeScoreFile(file, sourceType);
5010 if (tcf.annotateAlignment(viewport.getAlignment(), true))
5014 new TCoffeeColourScheme(viewport.getAlignment()));
5015 isAnnotation = true;
5016 setStatus(MessageManager.getString(
5017 "label.successfully_pasted_tcoffee_scores_to_alignment"));
5021 // some problem - if no warning its probable that the ID matching
5022 // process didn't work
5023 JvOptionPane.showMessageDialog(Desktop.desktop,
5024 tcf.getWarningMessage() == null
5025 ? MessageManager.getString(
5026 "label.check_file_matches_sequence_ids_alignment")
5027 : tcf.getWarningMessage(),
5028 MessageManager.getString(
5029 "label.problem_reading_tcoffee_score_file"),
5030 JvOptionPane.WARNING_MESSAGE);
5037 } catch (Exception x)
5040 "Exception when processing data source as T-COFFEE score file",
5046 // try to see if its a JNet 'concise' style annotation file *before*
5048 // try to parse it as a features file
5051 format = new IdentifyFile().identify(file, sourceType);
5053 if (FileFormat.ScoreMatrix == format)
5055 ScoreMatrixFile sm = new ScoreMatrixFile(
5056 new FileParse(file, sourceType));
5058 // todo: i18n this message
5059 setStatus(MessageManager.formatMessage(
5060 "label.successfully_loaded_matrix",
5061 sm.getMatrixName()));
5063 else if (FileFormat.Jnet.equals(format))
5065 JPredFile predictions = new JPredFile(file, sourceType);
5066 new JnetAnnotationMaker();
5067 JnetAnnotationMaker.add_annotation(predictions,
5068 viewport.getAlignment(), 0, false);
5069 viewport.getAlignment().setupJPredAlignment();
5070 isAnnotation = true;
5072 // else if (IdentifyFile.FeaturesFile.equals(format))
5073 else if (FileFormat.Features.equals(format))
5075 if (parseFeaturesFile(file, sourceType))
5077 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
5078 if (splitFrame != null)
5080 splitFrame.repaint();
5084 alignPanel.paintAlignment(true, true);
5090 new FileLoader().LoadFile(viewport, file, sourceType, format);
5097 alignPanel.adjustAnnotationHeight();
5098 viewport.updateSequenceIdColours();
5099 buildSortByAnnotationScoresMenu();
5100 alignPanel.paintAlignment(true, true);
5102 } catch (Exception ex)
5104 ex.printStackTrace();
5105 } catch (OutOfMemoryError oom)
5110 } catch (Exception x)
5115 + (sourceType != null
5116 ? (sourceType == DataSourceType.PASTE
5118 : "using " + sourceType + " from "
5122 ? "(parsing as '" + format + "' file)"
5124 oom, Desktop.desktop);
5129 * Method invoked by the ChangeListener on the tabbed pane, in other words
5130 * when a different tabbed pane is selected by the user or programmatically.
5133 public void tabSelectionChanged(int index)
5138 * update current Overview window title (if there is one)
5139 * to add view name "Original" if necessary
5141 alignPanel.setOverviewTitle(this);
5144 * switch panels and set Overview title (if there is one
5145 * because it was opened automatically)
5147 alignPanel = alignPanels.get(index);
5148 alignPanel.setOverviewTitle(this);
5150 viewport = alignPanel.av;
5151 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5152 setMenusFromViewport(viewport);
5153 if (featureSettings != null && featureSettings.isOpen()
5154 && featureSettings.fr.getViewport() != viewport)
5156 if (viewport.isShowSequenceFeatures())
5158 // refresh the featureSettings to reflect UI change
5159 showFeatureSettingsUI();
5163 // close feature settings for this view.
5164 featureSettings.close();
5171 * 'focus' any colour slider that is open to the selected viewport
5173 if (viewport.getConservationSelected())
5175 SliderPanel.setConservationSlider(alignPanel,
5176 viewport.getResidueShading(), alignPanel.getViewName());
5180 SliderPanel.hideConservationSlider();
5182 if (viewport.getAbovePIDThreshold())
5184 SliderPanel.setPIDSliderSource(alignPanel,
5185 viewport.getResidueShading(), alignPanel.getViewName());
5189 SliderPanel.hidePIDSlider();
5193 * If there is a frame linked to this one in a SplitPane, switch it to the
5194 * same view tab index. No infinite recursion of calls should happen, since
5195 * tabSelectionChanged() should not get invoked on setting the selected
5196 * index to an unchanged value. Guard against setting an invalid index
5197 * before the new view peer tab has been created.
5199 final AlignViewportI peer = viewport.getCodingComplement();
5202 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5203 .getAlignPanel().alignFrame;
5204 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5206 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5212 * On right mouse click on view tab, prompt for and set new view name.
5215 public void tabbedPane_mousePressed(MouseEvent e)
5217 if (e.isPopupTrigger())
5219 String msg = MessageManager.getString("label.enter_view_name");
5220 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5221 String reply = JvOptionPane.showInputDialog(msg, ttl);
5225 viewport.setViewName(reply);
5226 // TODO warn if reply is in getExistingViewNames()?
5227 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5232 public AlignViewport getCurrentView()
5238 * Open the dialog for regex description parsing.
5241 protected void extractScores_actionPerformed(ActionEvent e)
5243 ParseProperties pp = new jalview.analysis.ParseProperties(
5244 viewport.getAlignment());
5245 // TODO: verify regex and introduce GUI dialog for version 2.5
5246 // if (pp.getScoresFromDescription("col", "score column ",
5247 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5249 if (pp.getScoresFromDescription("description column",
5250 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5252 buildSortByAnnotationScoresMenu();
5260 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5264 protected void showDbRefs_actionPerformed(ActionEvent e)
5266 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5272 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5276 protected void showNpFeats_actionPerformed(ActionEvent e)
5278 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5282 * find the viewport amongst the tabs in this alignment frame and close that
5287 public boolean closeView(AlignViewportI av)
5291 this.closeMenuItem_actionPerformed(false);
5294 Component[] comp = tabbedPane.getComponents();
5295 for (int i = 0; comp != null && i < comp.length; i++)
5297 if (comp[i] instanceof AlignmentPanel)
5299 if (((AlignmentPanel) comp[i]).av == av)
5302 closeView((AlignmentPanel) comp[i]);
5310 protected void build_fetchdbmenu(JMenu webService)
5312 // Temporary hack - DBRef Fetcher always top level ws entry.
5313 // TODO We probably want to store a sequence database checklist in
5314 // preferences and have checkboxes.. rather than individual sources selected
5316 final JMenu rfetch = new JMenu(
5317 MessageManager.getString("action.fetch_db_references"));
5318 rfetch.setToolTipText(MessageManager.getString(
5319 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5320 webService.add(rfetch);
5322 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5323 MessageManager.getString("option.trim_retrieved_seqs"));
5324 trimrs.setToolTipText(
5325 MessageManager.getString("label.trim_retrieved_sequences"));
5327 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5328 trimrs.addActionListener(new ActionListener()
5331 public void actionPerformed(ActionEvent e)
5333 trimrs.setSelected(trimrs.isSelected());
5334 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5335 Boolean.valueOf(trimrs.isSelected()).toString());
5339 JMenuItem fetchr = new JMenuItem(
5340 MessageManager.getString("label.standard_databases"));
5341 fetchr.setToolTipText(
5342 MessageManager.getString("label.fetch_embl_uniprot"));
5343 fetchr.addActionListener(new ActionListener()
5347 public void actionPerformed(ActionEvent e)
5349 new Thread(new Runnable()
5354 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5355 .getAlignment().isNucleotide();
5356 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5357 alignPanel.av.getSequenceSelection(),
5358 alignPanel.alignFrame, null,
5359 alignPanel.alignFrame.featureSettings, isNucleotide);
5360 dbRefFetcher.addListener(new FetchFinishedListenerI()
5363 public void finished()
5366 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5367 .getFeatureSettingsModels())
5370 alignPanel.av.mergeFeaturesStyle(srcSettings);
5372 AlignFrame.this.setMenusForViewport();
5375 dbRefFetcher.fetchDBRefs(false);
5383 new Thread(new Runnable()
5388 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5389 .getSequenceFetcherSingleton();
5390 javax.swing.SwingUtilities.invokeLater(new Runnable()
5395 String[] dbclasses = sf.getNonAlignmentSources();
5396 List<DbSourceProxy> otherdb;
5397 JMenu dfetch = new JMenu();
5398 JMenu ifetch = new JMenu();
5399 JMenuItem fetchr = null;
5400 int comp = 0, icomp = 0, mcomp = 15;
5401 String mname = null;
5403 for (String dbclass : dbclasses)
5405 otherdb = sf.getSourceProxy(dbclass);
5406 // add a single entry for this class, or submenu allowing 'fetch
5408 if (otherdb == null || otherdb.size() < 1)
5414 mname = "From " + dbclass;
5416 if (otherdb.size() == 1)
5418 final DbSourceProxy[] dassource = otherdb
5419 .toArray(new DbSourceProxy[0]);
5420 DbSourceProxy src = otherdb.get(0);
5421 fetchr = new JMenuItem(src.getDbSource());
5422 fetchr.addActionListener(new ActionListener()
5426 public void actionPerformed(ActionEvent e)
5428 new Thread(new Runnable()
5434 boolean isNucleotide = alignPanel.alignFrame
5435 .getViewport().getAlignment()
5437 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5438 alignPanel.av.getSequenceSelection(),
5439 alignPanel.alignFrame, dassource,
5440 alignPanel.alignFrame.featureSettings,
5443 .addListener(new FetchFinishedListenerI()
5446 public void finished()
5448 FeatureSettingsModelI srcSettings = dassource[0]
5449 .getFeatureColourScheme();
5450 alignPanel.av.mergeFeaturesStyle(
5452 AlignFrame.this.setMenusForViewport();
5455 dbRefFetcher.fetchDBRefs(false);
5461 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5462 MessageManager.formatMessage(
5463 "label.fetch_retrieve_from", new Object[]
5464 { src.getDbName() })));
5470 final DbSourceProxy[] dassource = otherdb
5471 .toArray(new DbSourceProxy[0]);
5473 DbSourceProxy src = otherdb.get(0);
5474 fetchr = new JMenuItem(MessageManager
5475 .formatMessage("label.fetch_all_param", new Object[]
5476 { src.getDbSource() }));
5477 fetchr.addActionListener(new ActionListener()
5480 public void actionPerformed(ActionEvent e)
5482 new Thread(new Runnable()
5488 boolean isNucleotide = alignPanel.alignFrame
5489 .getViewport().getAlignment()
5491 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5492 alignPanel.av.getSequenceSelection(),
5493 alignPanel.alignFrame, dassource,
5494 alignPanel.alignFrame.featureSettings,
5497 .addListener(new FetchFinishedListenerI()
5500 public void finished()
5502 AlignFrame.this.setMenusForViewport();
5505 dbRefFetcher.fetchDBRefs(false);
5511 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5512 MessageManager.formatMessage(
5513 "label.fetch_retrieve_from_all_sources",
5515 { Integer.valueOf(otherdb.size())
5517 src.getDbSource(), src.getDbName() })));
5520 // and then build the rest of the individual menus
5521 ifetch = new JMenu(MessageManager.formatMessage(
5522 "label.source_from_db_source", new Object[]
5523 { src.getDbSource() }));
5525 String imname = null;
5527 for (DbSourceProxy sproxy : otherdb)
5529 String dbname = sproxy.getDbName();
5530 String sname = dbname.length() > 5
5531 ? dbname.substring(0, 5) + "..."
5533 String msname = dbname.length() > 10
5534 ? dbname.substring(0, 10) + "..."
5538 imname = MessageManager
5539 .formatMessage("label.from_msname", new Object[]
5542 fetchr = new JMenuItem(msname);
5543 final DbSourceProxy[] dassrc = { sproxy };
5544 fetchr.addActionListener(new ActionListener()
5548 public void actionPerformed(ActionEvent e)
5550 new Thread(new Runnable()
5556 boolean isNucleotide = alignPanel.alignFrame
5557 .getViewport().getAlignment()
5559 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5560 alignPanel.av.getSequenceSelection(),
5561 alignPanel.alignFrame, dassrc,
5562 alignPanel.alignFrame.featureSettings,
5565 .addListener(new FetchFinishedListenerI()
5568 public void finished()
5570 AlignFrame.this.setMenusForViewport();
5573 dbRefFetcher.fetchDBRefs(false);
5579 fetchr.setToolTipText(
5580 "<html>" + MessageManager.formatMessage(
5581 "label.fetch_retrieve_from", new Object[]
5585 if (++icomp >= mcomp || i == (otherdb.size()))
5587 ifetch.setText(MessageManager.formatMessage(
5588 "label.source_to_target", imname, sname));
5590 ifetch = new JMenu();
5598 if (comp >= mcomp || dbi >= (dbclasses.length))
5600 dfetch.setText(MessageManager.formatMessage(
5601 "label.source_to_target", mname, dbclass));
5603 dfetch = new JMenu();
5616 * Left justify the whole alignment.
5619 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5621 AlignmentI al = viewport.getAlignment();
5623 viewport.firePropertyChange("alignment", null, al);
5627 * Right justify the whole alignment.
5630 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5632 AlignmentI al = viewport.getAlignment();
5634 viewport.firePropertyChange("alignment", null, al);
5638 public void setShowSeqFeatures(boolean b)
5640 showSeqFeatures.setSelected(b);
5641 viewport.setShowSequenceFeatures(b);
5648 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5649 * awt.event.ActionEvent)
5652 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5654 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5655 alignPanel.paintAlignment(false, false);
5662 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5666 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5668 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5669 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5677 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5678 * .event.ActionEvent)
5681 protected void showGroupConservation_actionPerformed(ActionEvent e)
5683 viewport.setShowGroupConservation(showGroupConservation.getState());
5684 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5691 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5692 * .event.ActionEvent)
5695 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5697 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5698 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5705 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5706 * .event.ActionEvent)
5709 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5711 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5712 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5716 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5718 showSequenceLogo.setState(true);
5719 viewport.setShowSequenceLogo(true);
5720 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5721 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5725 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5727 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5734 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5735 * .event.ActionEvent)
5738 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5740 if (avc.makeGroupsFromSelection())
5742 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5743 alignPanel.updateAnnotation();
5744 alignPanel.paintAlignment(true,
5745 viewport.needToUpdateStructureViews());
5749 public void clearAlignmentSeqRep()
5751 // TODO refactor alignmentseqrep to controller
5752 if (viewport.getAlignment().hasSeqrep())
5754 viewport.getAlignment().setSeqrep(null);
5755 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5756 alignPanel.updateAnnotation();
5757 alignPanel.paintAlignment(true, true);
5762 protected void createGroup_actionPerformed(ActionEvent e)
5764 if (avc.createGroup())
5766 if (applyAutoAnnotationSettings.isSelected())
5768 alignPanel.updateAnnotation(true, false);
5770 alignPanel.alignmentChanged();
5775 protected void unGroup_actionPerformed(ActionEvent e)
5779 alignPanel.alignmentChanged();
5784 * make the given alignmentPanel the currently selected tab
5786 * @param alignmentPanel
5788 public void setDisplayedView(AlignmentPanel alignmentPanel)
5790 if (!viewport.getSequenceSetId()
5791 .equals(alignmentPanel.av.getSequenceSetId()))
5793 throw new Error(MessageManager.getString(
5794 "error.implementation_error_cannot_show_view_alignment_frame"));
5796 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5797 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5799 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5804 * Action on selection of menu options to Show or Hide annotations.
5807 * @param forSequences
5808 * update sequence-related annotations
5809 * @param forAlignment
5810 * update non-sequence-related annotations
5813 public void setAnnotationsVisibility(boolean visible,
5814 boolean forSequences, boolean forAlignment)
5816 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5817 .getAlignmentAnnotation();
5822 for (AlignmentAnnotation aa : anns)
5825 * don't display non-positional annotations on an alignment
5827 if (aa.annotations == null)
5831 boolean apply = (aa.sequenceRef == null && forAlignment)
5832 || (aa.sequenceRef != null && forSequences);
5835 aa.visible = visible;
5838 alignPanel.validateAnnotationDimensions(true);
5839 alignPanel.alignmentChanged();
5843 * Store selected annotation sort order for the view and repaint.
5846 protected void sortAnnotations_actionPerformed()
5848 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5850 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5851 alignPanel.paintAlignment(false, false);
5856 * @return alignment panels in this alignment frame
5858 public List<? extends AlignmentViewPanel> getAlignPanels()
5860 // alignPanels is never null
5861 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5866 * Open a new alignment window, with the cDNA associated with this (protein)
5867 * alignment, aligned as is the protein.
5869 protected void viewAsCdna_actionPerformed()
5871 // TODO no longer a menu action - refactor as required
5872 final AlignmentI alignment = getViewport().getAlignment();
5873 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5874 if (mappings == null)
5878 List<SequenceI> cdnaSeqs = new ArrayList<>();
5879 for (SequenceI aaSeq : alignment.getSequences())
5881 for (AlignedCodonFrame acf : mappings)
5883 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5887 * There is a cDNA mapping for this protein sequence - add to new
5888 * alignment. It will share the same dataset sequence as other mapped
5889 * cDNA (no new mappings need to be created).
5891 final Sequence newSeq = new Sequence(dnaSeq);
5892 newSeq.setDatasetSequence(dnaSeq);
5893 cdnaSeqs.add(newSeq);
5897 if (cdnaSeqs.size() == 0)
5899 // show a warning dialog no mapped cDNA
5902 AlignmentI cdna = new Alignment(
5903 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5904 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5905 AlignFrame.DEFAULT_HEIGHT);
5906 cdna.alignAs(alignment);
5907 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5909 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5910 AlignFrame.DEFAULT_HEIGHT);
5914 * Set visibility of dna/protein complement view (available when shown in a
5920 protected void showComplement_actionPerformed(boolean show)
5922 SplitContainerI sf = getSplitViewContainer();
5925 sf.setComplementVisible(this, show);
5930 * Generate the reverse (optionally complemented) of the selected sequences,
5931 * and add them to the alignment
5934 protected void showReverse_actionPerformed(boolean complement)
5936 AlignmentI al = null;
5939 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5940 al = dna.reverseCdna(complement);
5941 viewport.addAlignment(al, "");
5942 addHistoryItem(new EditCommand(
5943 MessageManager.getString("label.add_sequences"), Action.PASTE,
5944 al.getSequencesArray(), 0, al.getWidth(),
5945 viewport.getAlignment()));
5946 } catch (Exception ex)
5948 jalview.bin.Console.errPrintln(ex.getMessage());
5954 * Try to run a script in the Groovy console, having first ensured that this
5955 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5956 * be targeted at this alignment.
5959 protected void runGroovy_actionPerformed()
5961 Jalview.setCurrentAlignFrame(this);
5962 groovy.ui.Console console = Desktop.getGroovyConsole();
5963 if (console != null)
5967 console.runScript();
5968 } catch (Exception ex)
5970 jalview.bin.Console.errPrintln((ex.toString()));
5971 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5972 MessageManager.getString("label.couldnt_run_groovy_script"),
5973 MessageManager.getString("label.groovy_support_failed"),
5974 JvOptionPane.ERROR_MESSAGE);
5980 .errPrintln("Can't run Groovy script as console not found");
5985 * Hides columns containing (or not containing) a specified feature, provided
5986 * that would not leave all columns hidden
5988 * @param featureType
5989 * @param columnsContaining
5992 public boolean hideFeatureColumns(String featureType,
5993 boolean columnsContaining)
5995 boolean notForHiding = avc.markColumnsContainingFeatures(
5996 columnsContaining, false, false, featureType);
5999 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
6000 false, featureType))
6002 getViewport().hideSelectedColumns();
6010 protected void selectHighlightedColumns_actionPerformed(
6011 ActionEvent actionEvent)
6013 // include key modifier check in case user selects from menu
6014 avc.markHighlightedColumns(
6015 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
6016 (actionEvent.getModifiers() & (ActionEvent.META_MASK
6017 | ActionEvent.CTRL_MASK)) != 0);
6021 protected void copyHighlightedColumns_actionPerformed(
6022 ActionEvent actionEvent)
6024 avc.copyHighlightedRegionsToClipboard();
6028 * Rebuilds the Colour menu, including any user-defined colours which have
6029 * been loaded either on startup or during the session
6031 public void buildColourMenu()
6033 colourMenu.removeAll();
6035 colourMenu.add(applyToAllGroups);
6036 colourMenu.add(textColour);
6037 colourMenu.addSeparator();
6039 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
6040 viewport.getAlignment(), false);
6042 colourMenu.add(annotationColour);
6043 bg.add(annotationColour);
6044 colourMenu.addSeparator();
6045 colourMenu.add(conservationMenuItem);
6046 colourMenu.add(modifyConservation);
6047 colourMenu.add(abovePIDThreshold);
6048 colourMenu.add(modifyPID);
6050 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
6051 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
6055 * Open a dialog (if not already open) that allows the user to select and
6056 * calculate PCA or Tree analysis
6058 protected void openTreePcaDialog()
6060 if (alignPanel.getCalculationDialog() == null)
6062 new CalculationChooser(AlignFrame.this);
6067 protected void loadVcf_actionPerformed()
6069 JalviewFileChooser chooser = new JalviewFileChooser(
6070 Cache.getProperty("LAST_DIRECTORY"));
6071 chooser.setFileView(new JalviewFileView());
6072 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
6073 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
6074 final AlignFrame us = this;
6075 chooser.setResponseHandler(0, () -> {
6076 String choice = chooser.getSelectedFile().getPath();
6077 Cache.setProperty("LAST_DIRECTORY", choice);
6078 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
6079 new VCFLoader(choice).loadVCF(seqs, us);
6081 chooser.showOpenDialog(null);
6085 private Rectangle lastFeatureSettingsBounds = null;
6088 public void setFeatureSettingsGeometry(Rectangle bounds)
6090 lastFeatureSettingsBounds = bounds;
6094 public Rectangle getFeatureSettingsGeometry()
6096 return lastFeatureSettingsBounds;
6101 class PrintThread extends Thread
6105 public PrintThread(AlignmentPanel ap)
6110 static PageFormat pf;
6115 PrinterJob printJob = PrinterJob.getPrinterJob();
6119 printJob.setPrintable(ap, pf);
6123 printJob.setPrintable(ap);
6126 if (printJob.printDialog())
6131 } catch (Exception PrintException)
6133 PrintException.printStackTrace();