2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
62 import java.util.concurrent.Callable;
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.vcf.VCFLoader;
145 import jalview.jbgui.GAlignFrame;
146 import jalview.project.Jalview2XML;
147 import jalview.schemes.ColourSchemeI;
148 import jalview.schemes.ColourSchemes;
149 import jalview.schemes.ResidueColourScheme;
150 import jalview.schemes.TCoffeeColourScheme;
151 import jalview.util.HttpUtils;
152 import jalview.util.ImageMaker.TYPE;
153 import jalview.util.MessageManager;
154 import jalview.util.Platform;
155 import jalview.viewmodel.AlignmentViewport;
156 import jalview.viewmodel.ViewportRanges;
157 import jalview.ws.DBRefFetcher;
158 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
159 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
160 import jalview.ws.jws1.Discoverer;
161 import jalview.ws.jws2.Jws2Discoverer;
162 import jalview.ws.jws2.jabaws2.Jws2Instance;
163 import jalview.ws.seqfetcher.DbSourceProxy;
169 * @version $Revision$
171 @SuppressWarnings("serial")
172 public class AlignFrame extends GAlignFrame implements DropTargetListener,
173 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
176 public static final int DEFAULT_WIDTH = 700;
178 public static final int DEFAULT_HEIGHT = 500;
181 * The currently displayed panel (selected tabbed view if more than one)
183 public AlignmentPanel alignPanel;
185 AlignViewport viewport;
187 public AlignViewControllerI avc;
189 List<AlignmentPanel> alignPanels = new ArrayList<>();
192 * Last format used to load or save alignments in this window
194 FileFormatI currentFileFormat = null;
197 * Current filename for this alignment
199 String fileName = null;
204 * Creates a new AlignFrame object with specific width and height.
210 public AlignFrame(AlignmentI al, int width, int height)
212 this(al, null, width, height);
216 * Creates a new AlignFrame object with specific width, height and
222 * @param sequenceSetId
224 public AlignFrame(AlignmentI al, int width, int height,
225 String sequenceSetId)
227 this(al, null, width, height, sequenceSetId);
231 * Creates a new AlignFrame object with specific width, height and
237 * @param sequenceSetId
240 public AlignFrame(AlignmentI al, int width, int height,
241 String sequenceSetId, String viewId)
243 this(al, null, width, height, sequenceSetId, viewId);
247 * new alignment window with hidden columns
251 * @param hiddenColumns
252 * ColumnSelection or null
254 * Width of alignment frame
258 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
261 this(al, hiddenColumns, width, height, null);
265 * Create alignment frame for al with hiddenColumns, a specific width and
266 * height, and specific sequenceId
269 * @param hiddenColumns
272 * @param sequenceSetId
275 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
276 int height, String sequenceSetId)
278 this(al, hiddenColumns, width, height, sequenceSetId, null);
282 * Create alignment frame for al with hiddenColumns, a specific width and
283 * height, and specific sequenceId
286 * @param hiddenColumns
289 * @param sequenceSetId
294 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
295 int height, String sequenceSetId, String viewId)
297 setSize(width, height);
299 if (al.getDataset() == null)
304 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
306 alignPanel = new AlignmentPanel(this, viewport);
308 addAlignmentPanel(alignPanel, true);
312 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
313 HiddenColumns hiddenColumns, int width, int height)
315 setSize(width, height);
317 if (al.getDataset() == null)
322 viewport = new AlignViewport(al, hiddenColumns);
324 if (hiddenSeqs != null && hiddenSeqs.length > 0)
326 viewport.hideSequence(hiddenSeqs);
328 alignPanel = new AlignmentPanel(this, viewport);
329 addAlignmentPanel(alignPanel, true);
334 * Make a new AlignFrame from existing alignmentPanels
341 public AlignFrame(AlignmentPanel ap)
345 addAlignmentPanel(ap, false);
350 * initalise the alignframe from the underlying viewport data and the
357 // setBackground(Color.white); // BH 2019
359 if (!Jalview.isHeadlessMode())
361 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
364 avc = new jalview.controller.AlignViewController(this, viewport,
366 if (viewport.getAlignmentConservationAnnotation() == null)
368 // BLOSUM62Colour.setEnabled(false);
369 conservationMenuItem.setEnabled(false);
370 modifyConservation.setEnabled(false);
371 // PIDColour.setEnabled(false);
372 // abovePIDThreshold.setEnabled(false);
373 // modifyPID.setEnabled(false);
376 String sortby = Cache.getDefault("SORT_ALIGNMENT", "No sort");
378 if (sortby.equals("Id"))
380 sortIDMenuItem_actionPerformed(null);
382 else if (sortby.equals("Pairwise Identity"))
384 sortPairwiseMenuItem_actionPerformed(null);
388 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
390 setMenusFromViewport(viewport);
391 buildSortByAnnotationScoresMenu();
392 calculateTree.addActionListener(new ActionListener()
396 public void actionPerformed(ActionEvent e)
403 if (Desktop.desktop != null)
405 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
406 if (!Platform.isJS())
408 addServiceListeners();
413 if (viewport.getWrapAlignment())
415 wrapMenuItem_actionPerformed(null);
418 if (Cache.getDefault("SHOW_OVERVIEW", false))
420 this.overviewMenuItem_actionPerformed(null);
425 final List<AlignmentViewPanel> selviews = new ArrayList<>();
426 final List<AlignmentPanel> origview = new ArrayList<>();
427 final String menuLabel = MessageManager
428 .getString("label.copy_format_from");
429 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
430 new ViewSetProvider()
434 public AlignmentPanel[] getAllAlignmentPanels()
437 origview.add(alignPanel);
438 // make an array of all alignment panels except for this one
439 List<AlignmentPanel> aps = new ArrayList<>(
440 Arrays.asList(Desktop.getAlignmentPanels(null)));
441 aps.remove(AlignFrame.this.alignPanel);
442 return aps.toArray(new AlignmentPanel[aps.size()]);
444 }, selviews, new ItemListener()
448 public void itemStateChanged(ItemEvent e)
450 if (origview.size() > 0)
452 final AlignmentPanel ap = origview.get(0);
455 * Copy the ViewStyle of the selected panel to 'this one'.
456 * Don't change value of 'scaleProteinAsCdna' unless copying
459 ViewStyleI vs = selviews.get(0).getAlignViewport()
461 boolean fromSplitFrame = selviews.get(0)
462 .getAlignViewport().getCodingComplement() != null;
465 vs.setScaleProteinAsCdna(ap.getAlignViewport()
466 .getViewStyle().isScaleProteinAsCdna());
468 ap.getAlignViewport().setViewStyle(vs);
471 * Also rescale ViewStyle of SplitFrame complement if there is
472 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
473 * the whole ViewStyle (allow cDNA protein to have different
476 AlignViewportI complement = ap.getAlignViewport()
477 .getCodingComplement();
478 if (complement != null && vs.isScaleProteinAsCdna())
480 AlignFrame af = Desktop.getAlignFrameFor(complement);
481 ((SplitFrame) af.getSplitViewContainer())
483 af.setMenusForViewport();
487 ap.setSelected(true);
488 ap.alignFrame.setMenusForViewport();
493 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase(Locale.ROOT)
494 .indexOf("devel") > -1
495 || Cache.getDefault("VERSION", "DEVELOPMENT")
496 .toLowerCase(Locale.ROOT).indexOf("test") > -1)
498 formatMenu.add(vsel);
500 addFocusListener(new FocusAdapter()
503 public void focusGained(FocusEvent e)
505 Jalview.setCurrentAlignFrame(AlignFrame.this);
512 * Change the filename and format for the alignment, and enable the 'reload'
513 * button functionality.
520 public void setFileName(String file, FileFormatI format)
523 setFileFormat(format);
524 reload.setEnabled(true);
528 * JavaScript will have this, maybe others. More dependable than a file name
529 * and maintains a reference to the actual bytes loaded.
533 public void setFileObject(File file)
535 this.fileObject = file;
539 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
542 void addKeyListener()
544 addKeyListener(new KeyAdapter()
547 public void keyPressed(KeyEvent evt)
549 if (viewport.cursorMode
550 && ((evt.getKeyCode() >= KeyEvent.VK_0
551 && evt.getKeyCode() <= KeyEvent.VK_9)
552 || (evt.getKeyCode() >= KeyEvent.VK_NUMPAD0
553 && evt.getKeyCode() <= KeyEvent.VK_NUMPAD9))
554 && Character.isDigit(evt.getKeyChar()))
556 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
559 switch (evt.getKeyCode())
562 case 27: // escape key
563 deselectAllSequenceMenuItem_actionPerformed(null);
567 case KeyEvent.VK_DOWN:
568 if (evt.isAltDown() || !viewport.cursorMode)
570 moveSelectedSequences(false);
572 if (viewport.cursorMode)
574 alignPanel.getSeqPanel().moveCursor(0, 1, evt.isShiftDown());
579 if (evt.isAltDown() || !viewport.cursorMode)
581 moveSelectedSequences(true);
583 if (viewport.cursorMode)
585 alignPanel.getSeqPanel().moveCursor(0, -1, evt.isShiftDown());
590 case KeyEvent.VK_LEFT:
591 if (evt.isAltDown() || !viewport.cursorMode)
593 slideSequences(false,
594 alignPanel.getSeqPanel().getKeyboardNo1());
598 alignPanel.getSeqPanel().moveCursor(-1, 0, evt.isShiftDown());
603 case KeyEvent.VK_RIGHT:
604 if (evt.isAltDown() || !viewport.cursorMode)
606 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
610 alignPanel.getSeqPanel().moveCursor(1, 0, evt.isShiftDown());
614 case KeyEvent.VK_SPACE:
615 if (viewport.cursorMode)
617 alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
618 || evt.isShiftDown() || evt.isAltDown());
622 // case KeyEvent.VK_A:
623 // if (viewport.cursorMode)
625 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
626 // //System.out.println("A");
630 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
631 * System.out.println("closing bracket"); } break;
633 case KeyEvent.VK_DELETE:
634 case KeyEvent.VK_BACK_SPACE:
635 if (!viewport.cursorMode)
637 cut_actionPerformed();
641 alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
642 || evt.isShiftDown() || evt.isAltDown());
648 if (viewport.cursorMode)
650 alignPanel.getSeqPanel().setCursorRow();
654 if (viewport.cursorMode && !evt.isControlDown())
656 alignPanel.getSeqPanel().setCursorColumn();
660 if (viewport.cursorMode)
662 alignPanel.getSeqPanel().setCursorPosition();
666 case KeyEvent.VK_ENTER:
667 case KeyEvent.VK_COMMA:
668 if (viewport.cursorMode)
670 alignPanel.getSeqPanel().setCursorRowAndColumn();
675 if (viewport.cursorMode)
677 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
681 if (viewport.cursorMode)
683 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
688 viewport.cursorMode = !viewport.cursorMode;
689 setStatus(MessageManager
690 .formatMessage("label.keyboard_editing_mode", new String[]
691 { (viewport.cursorMode ? "on" : "off") }));
692 if (viewport.cursorMode)
694 ViewportRanges ranges = viewport.getRanges();
695 alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
697 alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
700 alignPanel.getSeqPanel().seqCanvas.repaint();
706 Help.showHelpWindow();
707 } catch (Exception ex)
709 ex.printStackTrace();
714 boolean toggleSeqs = !evt.isControlDown();
715 boolean toggleCols = !evt.isShiftDown();
716 toggleHiddenRegions(toggleSeqs, toggleCols);
721 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
722 boolean modifyExisting = true; // always modify, don't clear
723 // evt.isShiftDown();
724 boolean invertHighlighted = evt.isAltDown();
725 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
729 case KeyEvent.VK_PAGE_UP:
730 viewport.getRanges().pageUp();
732 case KeyEvent.VK_PAGE_DOWN:
733 viewport.getRanges().pageDown();
739 public void keyReleased(KeyEvent evt)
741 switch (evt.getKeyCode())
743 case KeyEvent.VK_LEFT:
744 if (evt.isAltDown() || !viewport.cursorMode)
746 viewport.firePropertyChange("alignment", null,
747 viewport.getAlignment().getSequences());
751 case KeyEvent.VK_RIGHT:
752 if (evt.isAltDown() || !viewport.cursorMode)
754 viewport.firePropertyChange("alignment", null,
755 viewport.getAlignment().getSequences());
763 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
765 ap.alignFrame = this;
766 avc = new jalview.controller.AlignViewController(this, viewport,
771 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
773 int aSize = alignPanels.size();
775 tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
777 if (aSize == 1 && ap.av.getViewName() == null)
779 this.getContentPane().add(ap, BorderLayout.CENTER);
785 setInitialTabVisible();
788 expandViews.setEnabled(true);
789 gatherViews.setEnabled(true);
790 tabbedPane.addTab(ap.av.getViewName(), ap);
792 ap.setVisible(false);
797 if (ap.av.isPadGaps())
799 ap.av.getAlignment().padGaps();
801 ap.av.updateConservation(ap);
802 ap.av.updateConsensus(ap);
803 ap.av.updateStrucConsensus(ap);
807 public void setInitialTabVisible()
809 expandViews.setEnabled(true);
810 gatherViews.setEnabled(true);
811 tabbedPane.setVisible(true);
812 AlignmentPanel first = alignPanels.get(0);
813 tabbedPane.addTab(first.av.getViewName(), first);
814 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
817 public AlignViewport getViewport()
822 /* Set up intrinsic listeners for dynamically generated GUI bits. */
823 private void addServiceListeners()
825 final java.beans.PropertyChangeListener thisListener;
826 Desktop.instance.addJalviewPropertyChangeListener("services",
827 thisListener = new java.beans.PropertyChangeListener()
830 public void propertyChange(PropertyChangeEvent evt)
832 // // System.out.println("Discoverer property change.");
833 // if (evt.getPropertyName().equals("services"))
835 SwingUtilities.invokeLater(new Runnable()
842 "Rebuild WS Menu for service change");
843 BuildWebServiceMenu();
850 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
853 public void internalFrameClosed(
854 javax.swing.event.InternalFrameEvent evt)
856 // System.out.println("deregistering discoverer listener");
857 Desktop.instance.removeJalviewPropertyChangeListener("services",
859 closeMenuItem_actionPerformed(true);
862 // Finally, build the menu once to get current service state
863 new Thread(new Runnable()
868 BuildWebServiceMenu();
874 * Configure menu items that vary according to whether the alignment is
875 * nucleotide or protein
877 public void setGUINucleotide()
879 AlignmentI al = getViewport().getAlignment();
880 boolean nucleotide = al.isNucleotide();
882 loadVcf.setVisible(nucleotide);
883 showTranslation.setVisible(nucleotide);
884 showReverse.setVisible(nucleotide);
885 showReverseComplement.setVisible(nucleotide);
886 conservationMenuItem.setEnabled(!nucleotide);
888 .setEnabled(!nucleotide && conservationMenuItem.isSelected());
889 showGroupConservation.setEnabled(!nucleotide);
891 showComplementMenuItem
892 .setText(nucleotide ? MessageManager.getString("label.protein")
893 : MessageManager.getString("label.nucleotide"));
897 * set up menus for the current viewport. This may be called after any
898 * operation that affects the data in the current view (selection changed,
899 * etc) to update the menus to reflect the new state.
902 public void setMenusForViewport()
904 setMenusFromViewport(viewport);
908 * Need to call this method when tabs are selected for multiple views, or when
909 * loading from Jalview2XML.java
914 public void setMenusFromViewport(AlignViewport av)
916 padGapsMenuitem.setSelected(av.isPadGaps());
917 colourTextMenuItem.setSelected(av.isShowColourText());
918 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
919 modifyPID.setEnabled(abovePIDThreshold.isSelected());
920 conservationMenuItem.setSelected(av.getConservationSelected());
921 modifyConservation.setEnabled(conservationMenuItem.isSelected());
922 seqLimits.setSelected(av.getShowJVSuffix());
923 idRightAlign.setSelected(av.isRightAlignIds());
924 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
925 renderGapsMenuItem.setSelected(av.isRenderGaps());
926 wrapMenuItem.setSelected(av.getWrapAlignment());
927 scaleAbove.setVisible(av.getWrapAlignment());
928 scaleLeft.setVisible(av.getWrapAlignment());
929 scaleRight.setVisible(av.getWrapAlignment());
930 annotationPanelMenuItem.setState(av.isShowAnnotation());
932 * Show/hide annotations only enabled if annotation panel is shown
934 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
935 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
936 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
937 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
938 viewBoxesMenuItem.setSelected(av.getShowBoxes());
939 viewTextMenuItem.setSelected(av.getShowText());
940 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
941 showGroupConsensus.setSelected(av.isShowGroupConsensus());
942 showGroupConservation.setSelected(av.isShowGroupConservation());
943 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
944 showSequenceLogo.setSelected(av.isShowSequenceLogo());
945 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
947 ColourMenuHelper.setColourSelected(colourMenu,
948 av.getGlobalColourScheme());
950 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
951 hiddenMarkers.setState(av.getShowHiddenMarkers());
952 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
953 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
954 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
955 autoCalculate.setSelected(av.autoCalculateConsensus);
956 sortByTree.setSelected(av.sortByTree);
957 listenToViewSelections.setSelected(av.followSelection);
959 showProducts.setEnabled(canShowProducts());
960 setGroovyEnabled(Desktop.getGroovyConsole() != null);
966 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
970 public void setGroovyEnabled(boolean b)
972 runGroovy.setEnabled(b);
975 private IProgressIndicator progressBar;
980 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
983 public void setProgressBar(String message, long id)
985 if (!Platform.isHeadless())
986 progressBar.setProgressBar(message, id);
990 public void registerHandler(final long id,
991 final IProgressIndicatorHandler handler)
993 progressBar.registerHandler(id, handler);
998 * @return true if any progress bars are still active
1001 public boolean operationInProgress()
1003 return progressBar.operationInProgress();
1007 * Sets the text of the status bar. Note that setting a null or empty value
1008 * will cause the status bar to be hidden, with possibly undesirable flicker
1009 * of the screen layout.
1012 public void setStatus(String text)
1014 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1018 * Added so Castor Mapping file can obtain Jalview Version
1020 public String getVersion()
1022 return Cache.getProperty("VERSION");
1025 public FeatureRenderer getFeatureRenderer()
1027 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1031 public void fetchSequence_actionPerformed()
1033 new SequenceFetcher(this);
1037 public void addFromFile_actionPerformed(ActionEvent e)
1039 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1043 public void reload_actionPerformed(ActionEvent e)
1045 if (fileName != null)
1047 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1048 // originating file's format
1049 // TODO: work out how to recover feature settings for correct view(s) when
1050 // file is reloaded.
1051 if (FileFormat.Jalview.equals(currentFileFormat))
1053 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1054 for (int i = 0; i < frames.length; i++)
1056 if (frames[i] instanceof AlignFrame && frames[i] != this
1057 && ((AlignFrame) frames[i]).fileName != null
1058 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1062 frames[i].setSelected(true);
1063 Desktop.instance.closeAssociatedWindows();
1064 } catch (java.beans.PropertyVetoException ex)
1070 Desktop.instance.closeAssociatedWindows();
1072 FileLoader loader = new FileLoader();
1073 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1074 ? DataSourceType.URL
1075 : DataSourceType.FILE;
1076 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1080 Rectangle bounds = this.getBounds();
1082 FileLoader loader = new FileLoader();
1084 AlignFrame newframe = null;
1086 if (fileObject == null)
1089 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1090 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1091 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1096 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1097 DataSourceType.FILE, currentFileFormat);
1100 newframe.setBounds(bounds);
1101 if (featureSettings != null && featureSettings.isShowing())
1103 final Rectangle fspos = featureSettings.frame.getBounds();
1104 // TODO: need a 'show feature settings' function that takes bounds -
1105 // need to refactor Desktop.addFrame
1106 newframe.featureSettings_actionPerformed(null);
1107 final FeatureSettings nfs = newframe.featureSettings;
1108 SwingUtilities.invokeLater(new Runnable()
1113 nfs.frame.setBounds(fspos);
1116 this.featureSettings.close();
1117 this.featureSettings = null;
1119 this.closeMenuItem_actionPerformed(true);
1125 public void addFromText_actionPerformed(ActionEvent e)
1128 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1132 public void addFromURL_actionPerformed(ActionEvent e)
1134 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1138 public void save_actionPerformed(ActionEvent e)
1140 if (fileName == null || (currentFileFormat == null)
1141 || HttpUtils.startsWithHttpOrHttps(fileName))
1143 saveAs_actionPerformed();
1147 saveAlignment(fileName, currentFileFormat);
1152 * Saves the alignment to a file with a name chosen by the user, if necessary
1153 * warning if a file would be overwritten
1156 public void saveAs_actionPerformed()
1158 String format = currentFileFormat == null ? null
1159 : currentFileFormat.getName();
1160 JalviewFileChooser chooser = JalviewFileChooser
1161 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1163 chooser.setFileView(new JalviewFileView());
1164 chooser.setDialogTitle(
1165 MessageManager.getString("label.save_alignment_to_file"));
1166 chooser.setToolTipText(MessageManager.getString("action.save"));
1168 int value = chooser.showSaveDialog(this);
1170 if (value != JalviewFileChooser.APPROVE_OPTION)
1174 currentFileFormat = chooser.getSelectedFormat();
1175 // todo is this (2005) test now obsolete - value is never null?
1176 while (currentFileFormat == null)
1178 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1180 .getString("label.select_file_format_before_saving"),
1181 MessageManager.getString("label.file_format_not_specified"),
1182 JvOptionPane.WARNING_MESSAGE);
1183 currentFileFormat = chooser.getSelectedFormat();
1184 value = chooser.showSaveDialog(this);
1185 if (value != JalviewFileChooser.APPROVE_OPTION)
1191 fileName = chooser.getSelectedFile().getPath();
1193 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1194 Cache.setProperty("LAST_DIRECTORY", fileName);
1195 saveAlignment(fileName, currentFileFormat);
1198 boolean lastSaveSuccessful = false;
1200 FileFormatI lastFormatSaved;
1202 String lastFilenameSaved;
1205 * Raise a dialog or status message for the last call to saveAlignment.
1207 * @return true if last call to saveAlignment(file, format) was successful.
1209 public boolean isSaveAlignmentSuccessful()
1212 if (!lastSaveSuccessful)
1214 if (!Platform.isHeadless())
1216 JvOptionPane.showInternalMessageDialog(this, MessageManager
1217 .formatMessage("label.couldnt_save_file", new Object[]
1218 { lastFilenameSaved }),
1219 MessageManager.getString("label.error_saving_file"),
1220 JvOptionPane.WARNING_MESSAGE);
1224 Console.error(MessageManager
1225 .formatMessage("label.couldnt_save_file", new Object[]
1226 { lastFilenameSaved }));
1232 setStatus(MessageManager.formatMessage(
1233 "label.successfully_saved_to_file_in_format", new Object[]
1234 { lastFilenameSaved, lastFormatSaved }));
1237 return lastSaveSuccessful;
1241 * Saves the alignment to the specified file path, in the specified format,
1242 * which may be an alignment format, or Jalview project format. If the
1243 * alignment has hidden regions, or the format is one capable of including
1244 * non-sequence data (features, annotations, groups), then the user may be
1245 * prompted to specify what to include in the output.
1250 public void saveAlignment(String file, FileFormatI format)
1252 lastSaveSuccessful = true;
1253 lastFilenameSaved = file;
1254 lastFormatSaved = format;
1256 if (FileFormat.Jalview.equals(format))
1258 String shortName = title;
1259 if (shortName.indexOf(File.separatorChar) > -1)
1261 shortName = shortName
1262 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1264 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1267 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1268 if (lastSaveSuccessful)
1270 this.getViewport().setSavedUpToDate(true);
1273 statusBar.setText(MessageManager.formatMessage(
1274 "label.successfully_saved_to_file_in_format", new Object[]
1280 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1281 Callable<Void> cancelAction = () -> {
1282 lastSaveSuccessful = false;
1285 Callable<Void> outputAction = () -> {
1286 // todo defer this to inside formatSequences (or later)
1287 AlignmentExportData exportData = viewport.getAlignExportData(options);
1288 String output = new FormatAdapter(alignPanel, options)
1289 .formatSequences(format, exportData.getAlignment(),
1290 exportData.getOmitHidden(),
1291 exportData.getStartEndPostions(),
1292 viewport.getAlignment().getHiddenColumns());
1295 lastSaveSuccessful = false;
1299 // create backupfiles object and get new temp filename destination
1300 boolean doBackup = BackupFiles.getEnabled();
1301 BackupFiles backupfiles = null;
1304 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1305 backupfiles = new BackupFiles(file);
1309 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1311 Console.trace("ALIGNFRAME setting PrintWriter");
1312 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1314 if (backupfiles != null)
1316 Console.trace("ALIGNFRAME about to write to temp file "
1317 + backupfiles.getTempFilePath());
1321 Console.trace("ALIGNFRAME about to close file");
1323 Console.trace("ALIGNFRAME closed file");
1324 AlignFrame.this.setTitle(file);
1325 statusBar.setText(MessageManager.formatMessage(
1326 "label.successfully_saved_to_file_in_format", new Object[]
1327 { fileName, format.getName() }));
1328 lastSaveSuccessful = true;
1329 } catch (IOException e)
1331 lastSaveSuccessful = false;
1333 "ALIGNFRAME Something happened writing the temp file");
1334 Console.error(e.getMessage());
1335 Console.debug(Cache.getStackTraceString(e));
1336 } catch (Exception ex)
1338 lastSaveSuccessful = false;
1340 "ALIGNFRAME Something unexpected happened writing the temp file");
1341 Console.error(ex.getMessage());
1342 Console.debug(Cache.getStackTraceString(ex));
1347 backupfiles.setWriteSuccess(lastSaveSuccessful);
1348 Console.debug("ALIGNFRAME writing temp file was "
1349 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1350 // do the backup file roll and rename the temp file to actual file
1351 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1352 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1353 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1354 + (lastSaveSuccessful ? "" : "un") + "successfully");
1357 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1358 if (lastSaveSuccessful)
1360 AlignFrame.this.getViewport().setSavedUpToDate(true);
1367 * show dialog with export options if applicable; else just do it
1369 if (AlignExportOptions.isNeeded(viewport, format))
1371 AlignExportOptions choices = new AlignExportOptions(
1372 alignPanel.getAlignViewport(), format, options);
1373 choices.setResponseAction(0, outputAction);
1374 choices.setResponseAction(1, cancelAction);
1375 choices.showDialog();
1381 outputAction.call();
1382 } catch (Exception e)
1384 // TODO Auto-generated catch block
1385 e.printStackTrace();
1391 * Outputs the alignment to textbox in the requested format, if necessary
1392 * first prompting the user for whether to include hidden regions or
1395 * @param fileFormatName
1398 protected void outputText_actionPerformed(String fileFormatName)
1400 FileFormatI fileFormat = FileFormats.getInstance()
1401 .forName(fileFormatName);
1402 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1403 Callable<Void> outputAction = () -> {
1404 // todo defer this to inside formatSequences (or later)
1405 AlignmentExportData exportData = viewport.getAlignExportData(options);
1406 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1407 cap.setForInput(null);
1410 FileFormatI format = fileFormat;
1411 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1412 format, exportData.getAlignment(),
1413 exportData.getOmitHidden(),
1414 exportData.getStartEndPostions(),
1415 viewport.getAlignment().getHiddenColumns()));
1416 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1417 "label.alignment_output_command", new Object[]
1418 { fileFormat.getName() }), 600, 500);
1419 } catch (OutOfMemoryError oom)
1421 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1429 * show dialog with export options if applicable; else just do it
1431 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1433 AlignExportOptions choices = new AlignExportOptions(
1434 alignPanel.getAlignViewport(), fileFormat, options);
1435 choices.setResponseAction(0, outputAction);
1436 choices.showDialog();
1442 outputAction.call();
1443 } catch (Exception e)
1445 e.printStackTrace();
1457 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1459 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1460 htmlSVG.exportHTML(null);
1464 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1466 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1467 bjs.exportHTML(null);
1470 public void createImageMap(File file, String image)
1472 alignPanel.makePNGImageMap(file, image);
1476 * Creates a PNG image of the alignment and writes it to the given file. If
1477 * the file is null, the user is prompted to choose a file.
1482 public void createPNG(File f)
1484 createPNG(f, null, 0.0f, 0, 0);
1487 public void createPNG(File f, String renderer, float bitmapscale,
1488 int bitmapwidth, int bitmapheight)
1490 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, bitmapscale,
1491 bitmapwidth, bitmapheight);
1495 * Creates an EPS image of the alignment and writes it to the given file. If
1496 * the file is null, the user is prompted to choose a file.
1501 public void createEPS(File f)
1506 public void createEPS(File f, String renderer)
1508 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1512 * Creates an SVG image of the alignment and writes it to the given file. If
1513 * the file is null, the user is prompted to choose a file.
1518 public void createSVG(File f)
1523 public void createSVG(File f, String renderer)
1525 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1529 public void pageSetup_actionPerformed(ActionEvent e)
1531 PrinterJob printJob = PrinterJob.getPrinterJob();
1532 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1542 public void printMenuItem_actionPerformed(ActionEvent e)
1544 // Putting in a thread avoids Swing painting problems
1545 PrintThread thread = new PrintThread(alignPanel);
1550 public void exportFeatures_actionPerformed(ActionEvent e)
1552 new AnnotationExporter(alignPanel).exportFeatures();
1556 public void exportAnnotations_actionPerformed(ActionEvent e)
1558 new AnnotationExporter(alignPanel).exportAnnotations();
1562 public void associatedData_actionPerformed(ActionEvent e)
1564 final JalviewFileChooser chooser = new JalviewFileChooser(
1565 Cache.getProperty("LAST_DIRECTORY"));
1566 chooser.setFileView(new JalviewFileView());
1567 String tooltip = MessageManager
1568 .getString("label.load_jalview_annotations");
1569 chooser.setDialogTitle(tooltip);
1570 chooser.setToolTipText(tooltip);
1571 chooser.setResponseHandler(0, () -> {
1572 String choice = chooser.getSelectedFile().getPath();
1573 Cache.setProperty("LAST_DIRECTORY", choice);
1574 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1578 chooser.showOpenDialog(this);
1582 * Close the current view or all views in the alignment frame. If the frame
1583 * only contains one view then the alignment will be removed from memory.
1585 * @param closeAllTabs
1588 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1590 if (alignPanels != null && alignPanels.size() < 2)
1592 closeAllTabs = true;
1597 if (alignPanels != null)
1601 if (this.isClosed())
1603 // really close all the windows - otherwise wait till
1604 // setClosed(true) is called
1605 for (int i = 0; i < alignPanels.size(); i++)
1607 AlignmentPanel ap = alignPanels.get(i);
1614 closeView(alignPanel);
1619 if (featureSettings != null && featureSettings.isOpen())
1621 featureSettings.close();
1622 featureSettings = null;
1625 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1626 * be called recursively, with the frame now in 'closed' state
1628 this.setClosed(true);
1630 } catch (Exception ex)
1632 ex.printStackTrace();
1637 * Close the specified panel and close up tabs appropriately.
1639 * @param panelToClose
1641 public void closeView(AlignmentPanel panelToClose)
1643 int index = tabbedPane.getSelectedIndex();
1644 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1645 alignPanels.remove(panelToClose);
1646 panelToClose.closePanel();
1647 panelToClose = null;
1649 tabbedPane.removeTabAt(closedindex);
1650 tabbedPane.validate();
1652 if (index > closedindex || index == tabbedPane.getTabCount())
1654 // modify currently selected tab index if necessary.
1658 this.tabSelectionChanged(index);
1664 void updateEditMenuBar()
1667 if (viewport.getHistoryList().size() > 0)
1669 undoMenuItem.setEnabled(true);
1670 CommandI command = viewport.getHistoryList().peek();
1671 undoMenuItem.setText(MessageManager
1672 .formatMessage("label.undo_command", new Object[]
1673 { command.getDescription() }));
1677 undoMenuItem.setEnabled(false);
1678 undoMenuItem.setText(MessageManager.getString("action.undo"));
1681 if (viewport.getRedoList().size() > 0)
1683 redoMenuItem.setEnabled(true);
1685 CommandI command = viewport.getRedoList().peek();
1686 redoMenuItem.setText(MessageManager
1687 .formatMessage("label.redo_command", new Object[]
1688 { command.getDescription() }));
1692 redoMenuItem.setEnabled(false);
1693 redoMenuItem.setText(MessageManager.getString("action.redo"));
1698 public void addHistoryItem(CommandI command)
1700 if (command.getSize() > 0)
1702 viewport.addToHistoryList(command);
1703 viewport.clearRedoList();
1704 updateEditMenuBar();
1705 viewport.updateHiddenColumns();
1706 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1707 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1708 // viewport.getColumnSelection()
1709 // .getHiddenColumns().size() > 0);
1715 * @return alignment objects for all views
1717 AlignmentI[] getViewAlignments()
1719 if (alignPanels != null)
1721 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1723 for (AlignmentPanel ap : alignPanels)
1725 als[i++] = ap.av.getAlignment();
1729 if (viewport != null)
1731 return new AlignmentI[] { viewport.getAlignment() };
1743 protected void undoMenuItem_actionPerformed(ActionEvent e)
1745 if (viewport.getHistoryList().isEmpty())
1749 CommandI command = viewport.getHistoryList().pop();
1750 viewport.addToRedoList(command);
1751 command.undoCommand(getViewAlignments());
1753 AlignmentViewport originalSource = getOriginatingSource(command);
1754 updateEditMenuBar();
1756 if (originalSource != null)
1758 if (originalSource != viewport)
1761 "Implementation worry: mismatch of viewport origin for undo");
1763 originalSource.updateHiddenColumns();
1764 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1766 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1767 // viewport.getColumnSelection()
1768 // .getHiddenColumns().size() > 0);
1769 originalSource.firePropertyChange("alignment", null,
1770 originalSource.getAlignment().getSequences());
1781 protected void redoMenuItem_actionPerformed(ActionEvent e)
1783 if (viewport.getRedoList().size() < 1)
1788 CommandI command = viewport.getRedoList().pop();
1789 viewport.addToHistoryList(command);
1790 command.doCommand(getViewAlignments());
1792 AlignmentViewport originalSource = getOriginatingSource(command);
1793 updateEditMenuBar();
1795 if (originalSource != null)
1798 if (originalSource != viewport)
1801 "Implementation worry: mismatch of viewport origin for redo");
1803 originalSource.updateHiddenColumns();
1804 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1806 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1807 // viewport.getColumnSelection()
1808 // .getHiddenColumns().size() > 0);
1809 originalSource.firePropertyChange("alignment", null,
1810 originalSource.getAlignment().getSequences());
1814 AlignmentViewport getOriginatingSource(CommandI command)
1816 AlignmentViewport originalSource = null;
1817 // For sequence removal and addition, we need to fire
1818 // the property change event FROM the viewport where the
1819 // original alignment was altered
1820 AlignmentI al = null;
1821 if (command instanceof EditCommand)
1823 EditCommand editCommand = (EditCommand) command;
1824 al = editCommand.getAlignment();
1825 List<Component> comps = PaintRefresher.components
1826 .get(viewport.getSequenceSetId());
1828 for (Component comp : comps)
1830 if (comp instanceof AlignmentPanel)
1832 if (al == ((AlignmentPanel) comp).av.getAlignment())
1834 originalSource = ((AlignmentPanel) comp).av;
1841 if (originalSource == null)
1843 // The original view is closed, we must validate
1844 // the current view against the closed view first
1847 PaintRefresher.validateSequences(al, viewport.getAlignment());
1850 originalSource = viewport;
1853 return originalSource;
1857 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1858 * or the sequence under cursor in keyboard mode
1863 public void moveSelectedSequences(boolean up)
1865 SequenceGroup sg = viewport.getSelectionGroup();
1869 if (viewport.cursorMode)
1871 sg = new SequenceGroup();
1872 sg.addSequence(viewport.getAlignment().getSequenceAt(
1873 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1881 if (sg.getSize() < 1)
1886 // TODO: JAL-3733 - add an event to the undo buffer for this !
1888 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1889 viewport.getHiddenRepSequences(), up);
1890 alignPanel.paintAlignment(true, false);
1893 synchronized void slideSequences(boolean right, int size)
1895 List<SequenceI> sg = new ArrayList<>();
1896 if (viewport.cursorMode)
1898 sg.add(viewport.getAlignment()
1899 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1901 else if (viewport.getSelectionGroup() != null
1902 && viewport.getSelectionGroup().getSize() != viewport
1903 .getAlignment().getHeight())
1905 sg = viewport.getSelectionGroup()
1906 .getSequences(viewport.getHiddenRepSequences());
1914 List<SequenceI> invertGroup = new ArrayList<>();
1916 for (SequenceI seq : viewport.getAlignment().getSequences())
1918 if (!sg.contains(seq))
1920 invertGroup.add(seq);
1924 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1926 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1927 for (int i = 0; i < invertGroup.size(); i++)
1929 seqs2[i] = invertGroup.get(i);
1932 SlideSequencesCommand ssc;
1935 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1936 viewport.getGapCharacter());
1940 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1941 viewport.getGapCharacter());
1944 int groupAdjustment = 0;
1945 if (ssc.getGapsInsertedBegin() && right)
1947 if (viewport.cursorMode)
1949 alignPanel.getSeqPanel().moveCursor(size, 0);
1953 groupAdjustment = size;
1956 else if (!ssc.getGapsInsertedBegin() && !right)
1958 if (viewport.cursorMode)
1960 alignPanel.getSeqPanel().moveCursor(-size, 0);
1964 groupAdjustment = -size;
1968 if (groupAdjustment != 0)
1970 viewport.getSelectionGroup().setStartRes(
1971 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1972 viewport.getSelectionGroup().setEndRes(
1973 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1977 * just extend the last slide command if compatible; but not if in
1978 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1980 boolean appendHistoryItem = false;
1981 Deque<CommandI> historyList = viewport.getHistoryList();
1982 boolean inSplitFrame = getSplitViewContainer() != null;
1983 if (!inSplitFrame && historyList != null && historyList.size() > 0
1984 && historyList.peek() instanceof SlideSequencesCommand)
1986 appendHistoryItem = ssc.appendSlideCommand(
1987 (SlideSequencesCommand) historyList.peek());
1990 if (!appendHistoryItem)
1992 addHistoryItem(ssc);
2005 protected void copy_actionPerformed()
2007 if (viewport.getSelectionGroup() == null)
2011 // TODO: preserve the ordering of displayed alignment annotation in any
2012 // internal paste (particularly sequence associated annotation)
2013 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2014 String[] omitHidden = null;
2016 if (viewport.hasHiddenColumns())
2018 omitHidden = viewport.getViewAsString(true);
2021 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2022 seqs, omitHidden, null);
2024 StringSelection ss = new StringSelection(output);
2028 jalview.gui.Desktop.internalCopy = true;
2029 // Its really worth setting the clipboard contents
2030 // to empty before setting the large StringSelection!!
2031 Toolkit.getDefaultToolkit().getSystemClipboard()
2032 .setContents(new StringSelection(""), null);
2034 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2036 } catch (OutOfMemoryError er)
2038 new OOMWarning("copying region", er);
2042 HiddenColumns hiddenColumns = null;
2043 if (viewport.hasHiddenColumns())
2045 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2046 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2048 // create new HiddenColumns object with copy of hidden regions
2049 // between startRes and endRes, offset by startRes
2050 hiddenColumns = new HiddenColumns(
2051 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2052 hiddenCutoff, hiddenOffset);
2055 Desktop.jalviewClipboard = new Object[] { seqs,
2056 viewport.getAlignment().getDataset(), hiddenColumns };
2057 setStatus(MessageManager.formatMessage(
2058 "label.copied_sequences_to_clipboard", new Object[]
2059 { Integer.valueOf(seqs.length).toString() }));
2069 protected void pasteNew_actionPerformed(ActionEvent e)
2081 protected void pasteThis_actionPerformed(ActionEvent e)
2087 * Paste contents of Jalview clipboard
2089 * @param newAlignment
2090 * true to paste to a new alignment, otherwise add to this.
2092 void paste(boolean newAlignment)
2094 boolean externalPaste = true;
2097 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2098 Transferable contents = c.getContents(this);
2100 if (contents == null)
2109 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2110 if (str.length() < 1)
2115 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2117 } catch (OutOfMemoryError er)
2119 new OOMWarning("Out of memory pasting sequences!!", er);
2123 SequenceI[] sequences;
2124 boolean annotationAdded = false;
2125 AlignmentI alignment = null;
2127 if (Desktop.jalviewClipboard != null)
2129 // The clipboard was filled from within Jalview, we must use the
2131 // And dataset from the copied alignment
2132 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2133 // be doubly sure that we create *new* sequence objects.
2134 sequences = new SequenceI[newseq.length];
2135 for (int i = 0; i < newseq.length; i++)
2137 sequences[i] = new Sequence(newseq[i]);
2139 alignment = new Alignment(sequences);
2140 externalPaste = false;
2144 // parse the clipboard as an alignment.
2145 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2147 sequences = alignment.getSequencesArray();
2151 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2157 if (Desktop.jalviewClipboard != null)
2159 // dataset is inherited
2160 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2164 // new dataset is constructed
2165 alignment.setDataset(null);
2167 alwidth = alignment.getWidth() + 1;
2171 AlignmentI pastedal = alignment; // preserve pasted alignment object
2172 // Add pasted sequences and dataset into existing alignment.
2173 alignment = viewport.getAlignment();
2174 alwidth = alignment.getWidth() + 1;
2175 // decide if we need to import sequences from an existing dataset
2176 boolean importDs = Desktop.jalviewClipboard != null
2177 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2178 // importDs==true instructs us to copy over new dataset sequences from
2179 // an existing alignment
2180 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2182 // minimum dataset set
2184 for (int i = 0; i < sequences.length; i++)
2188 newDs.addElement(null);
2190 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2192 if (importDs && ds != null)
2194 if (!newDs.contains(ds))
2196 newDs.setElementAt(ds, i);
2197 ds = new Sequence(ds);
2198 // update with new dataset sequence
2199 sequences[i].setDatasetSequence(ds);
2203 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2208 // copy and derive new dataset sequence
2209 sequences[i] = sequences[i].deriveSequence();
2210 alignment.getDataset()
2211 .addSequence(sequences[i].getDatasetSequence());
2212 // TODO: avoid creation of duplicate dataset sequences with a
2213 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2215 alignment.addSequence(sequences[i]); // merges dataset
2219 newDs.clear(); // tidy up
2221 if (alignment.getAlignmentAnnotation() != null)
2223 for (AlignmentAnnotation alan : alignment
2224 .getAlignmentAnnotation())
2226 if (alan.graphGroup > fgroup)
2228 fgroup = alan.graphGroup;
2232 if (pastedal.getAlignmentAnnotation() != null)
2234 // Add any annotation attached to alignment.
2235 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2236 for (int i = 0; i < alann.length; i++)
2238 annotationAdded = true;
2239 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2241 AlignmentAnnotation newann = new AlignmentAnnotation(
2243 if (newann.graphGroup > -1)
2245 if (newGraphGroups.size() <= newann.graphGroup
2246 || newGraphGroups.get(newann.graphGroup) == null)
2248 for (int q = newGraphGroups
2249 .size(); q <= newann.graphGroup; q++)
2251 newGraphGroups.add(q, null);
2253 newGraphGroups.set(newann.graphGroup,
2254 Integer.valueOf(++fgroup));
2256 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2260 newann.padAnnotation(alwidth);
2261 alignment.addAnnotation(newann);
2271 addHistoryItem(new EditCommand(
2272 MessageManager.getString("label.add_sequences"),
2273 Action.PASTE, sequences, 0, alignment.getWidth(),
2276 // Add any annotations attached to sequences
2277 for (int i = 0; i < sequences.length; i++)
2279 if (sequences[i].getAnnotation() != null)
2281 AlignmentAnnotation newann;
2282 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2284 annotationAdded = true;
2285 newann = sequences[i].getAnnotation()[a];
2286 newann.adjustForAlignment();
2287 newann.padAnnotation(alwidth);
2288 if (newann.graphGroup > -1)
2290 if (newann.graphGroup > -1)
2292 if (newGraphGroups.size() <= newann.graphGroup
2293 || newGraphGroups.get(newann.graphGroup) == null)
2295 for (int q = newGraphGroups
2296 .size(); q <= newann.graphGroup; q++)
2298 newGraphGroups.add(q, null);
2300 newGraphGroups.set(newann.graphGroup,
2301 Integer.valueOf(++fgroup));
2303 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2307 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
2311 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2319 // propagate alignment changed.
2320 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2321 if (annotationAdded)
2323 // Duplicate sequence annotation in all views.
2324 AlignmentI[] alview = this.getViewAlignments();
2325 for (int i = 0; i < sequences.length; i++)
2327 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2332 for (int avnum = 0; avnum < alview.length; avnum++)
2334 if (alview[avnum] != alignment)
2336 // duplicate in a view other than the one with input focus
2337 int avwidth = alview[avnum].getWidth() + 1;
2338 // this relies on sann being preserved after we
2339 // modify the sequence's annotation array for each duplication
2340 for (int a = 0; a < sann.length; a++)
2342 AlignmentAnnotation newann = new AlignmentAnnotation(
2344 sequences[i].addAlignmentAnnotation(newann);
2345 newann.padAnnotation(avwidth);
2346 alview[avnum].addAnnotation(newann); // annotation was
2347 // duplicated earlier
2348 // TODO JAL-1145 graphGroups are not updated for sequence
2349 // annotation added to several views. This may cause
2351 alview[avnum].setAnnotationIndex(newann, a);
2356 buildSortByAnnotationScoresMenu();
2358 viewport.firePropertyChange("alignment", null,
2359 alignment.getSequences());
2360 if (alignPanels != null)
2362 for (AlignmentPanel ap : alignPanels)
2364 ap.validateAnnotationDimensions(false);
2369 alignPanel.validateAnnotationDimensions(false);
2375 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2377 String newtitle = new String("Copied sequences");
2379 if (Desktop.jalviewClipboard != null
2380 && Desktop.jalviewClipboard[2] != null)
2382 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2383 af.viewport.setHiddenColumns(hc);
2386 // >>>This is a fix for the moment, until a better solution is
2388 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2389 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2390 .getFeatureRenderer());
2392 // TODO: maintain provenance of an alignment, rather than just make the
2393 // title a concatenation of operations.
2396 if (title.startsWith("Copied sequences"))
2402 newtitle = newtitle.concat("- from " + title);
2407 newtitle = new String("Pasted sequences");
2410 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2415 } catch (Exception ex)
2417 ex.printStackTrace();
2418 System.out.println("Exception whilst pasting: " + ex);
2419 // could be anything being pasted in here
2425 protected void expand_newalign(ActionEvent e)
2429 AlignmentI alignment = AlignmentUtils
2430 .expandContext(getViewport().getAlignment(), -1);
2431 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2433 String newtitle = new String("Flanking alignment");
2435 if (Desktop.jalviewClipboard != null
2436 && Desktop.jalviewClipboard[2] != null)
2438 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2439 af.viewport.setHiddenColumns(hc);
2442 // >>>This is a fix for the moment, until a better solution is
2444 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2445 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2446 .getFeatureRenderer());
2448 // TODO: maintain provenance of an alignment, rather than just make the
2449 // title a concatenation of operations.
2451 if (title.startsWith("Copied sequences"))
2457 newtitle = newtitle.concat("- from " + title);
2461 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2463 } catch (Exception ex)
2465 ex.printStackTrace();
2466 System.out.println("Exception whilst pasting: " + ex);
2467 // could be anything being pasted in here
2468 } catch (OutOfMemoryError oom)
2470 new OOMWarning("Viewing flanking region of alignment", oom);
2475 * Action Cut (delete and copy) the selected region
2478 protected void cut_actionPerformed()
2480 copy_actionPerformed();
2481 delete_actionPerformed();
2485 * Performs menu option to Delete the currently selected region
2488 protected void delete_actionPerformed()
2491 SequenceGroup sg = viewport.getSelectionGroup();
2497 Callable okAction = () -> {
2498 SequenceI[] cut = sg.getSequences()
2499 .toArray(new SequenceI[sg.getSize()]);
2501 addHistoryItem(new EditCommand(
2502 MessageManager.getString("label.cut_sequences"), Action.CUT,
2503 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2504 viewport.getAlignment()));
2506 viewport.setSelectionGroup(null);
2507 viewport.sendSelection();
2508 viewport.getAlignment().deleteGroup(sg);
2510 viewport.firePropertyChange("alignment", null,
2511 viewport.getAlignment().getSequences());
2512 if (viewport.getAlignment().getHeight() < 1)
2516 AlignFrame.this.setClosed(true);
2517 } catch (Exception ex)
2525 * If the cut affects all sequences, prompt for confirmation
2527 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2529 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2530 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2531 if (wholeHeight && wholeWidth)
2533 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2534 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2535 Object[] options = new Object[] {
2536 MessageManager.getString("action.ok"),
2537 MessageManager.getString("action.cancel") };
2538 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2539 MessageManager.getString("label.delete_all"),
2540 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2541 options, options[0]);
2548 } catch (Exception e)
2550 e.printStackTrace();
2562 protected void deleteGroups_actionPerformed(ActionEvent e)
2564 if (avc.deleteGroups())
2566 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2567 alignPanel.updateAnnotation();
2568 alignPanel.paintAlignment(true, true);
2579 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2581 SequenceGroup sg = new SequenceGroup(
2582 viewport.getAlignment().getSequences());
2584 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2585 viewport.setSelectionGroup(sg);
2586 viewport.isSelectionGroupChanged(true);
2587 viewport.sendSelection();
2588 // JAL-2034 - should delegate to
2589 // alignPanel to decide if overview needs
2591 alignPanel.paintAlignment(false, false);
2592 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2602 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2604 if (viewport.cursorMode)
2606 alignPanel.getSeqPanel().keyboardNo1 = null;
2607 alignPanel.getSeqPanel().keyboardNo2 = null;
2609 viewport.setSelectionGroup(null);
2610 viewport.getColumnSelection().clear();
2611 viewport.setSearchResults(null);
2612 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2613 // JAL-2034 - should delegate to
2614 // alignPanel to decide if overview needs
2616 alignPanel.paintAlignment(false, false);
2617 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2618 viewport.sendSelection();
2628 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2630 SequenceGroup sg = viewport.getSelectionGroup();
2634 selectAllSequenceMenuItem_actionPerformed(null);
2639 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2641 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2643 // JAL-2034 - should delegate to
2644 // alignPanel to decide if overview needs
2647 alignPanel.paintAlignment(true, false);
2648 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2649 viewport.sendSelection();
2653 public void invertColSel_actionPerformed(ActionEvent e)
2655 viewport.invertColumnSelection();
2656 alignPanel.paintAlignment(true, false);
2657 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2658 viewport.sendSelection();
2668 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2670 trimAlignment(true);
2680 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2682 trimAlignment(false);
2685 void trimAlignment(boolean trimLeft)
2687 ColumnSelection colSel = viewport.getColumnSelection();
2690 if (!colSel.isEmpty())
2694 column = colSel.getMin();
2698 column = colSel.getMax();
2702 if (viewport.getSelectionGroup() != null)
2704 seqs = viewport.getSelectionGroup()
2705 .getSequencesAsArray(viewport.getHiddenRepSequences());
2709 seqs = viewport.getAlignment().getSequencesArray();
2712 TrimRegionCommand trimRegion;
2715 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2716 column, viewport.getAlignment());
2717 viewport.getRanges().setStartRes(0);
2721 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2722 column, viewport.getAlignment());
2725 setStatus(MessageManager.formatMessage("label.removed_columns",
2727 { Integer.valueOf(trimRegion.getSize()).toString() }));
2729 addHistoryItem(trimRegion);
2731 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2733 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2734 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2736 viewport.getAlignment().deleteGroup(sg);
2740 viewport.firePropertyChange("alignment", null,
2741 viewport.getAlignment().getSequences());
2752 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2754 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2757 if (viewport.getSelectionGroup() != null)
2759 seqs = viewport.getSelectionGroup()
2760 .getSequencesAsArray(viewport.getHiddenRepSequences());
2761 start = viewport.getSelectionGroup().getStartRes();
2762 end = viewport.getSelectionGroup().getEndRes();
2766 seqs = viewport.getAlignment().getSequencesArray();
2769 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2770 "Remove Gapped Columns", seqs, start, end,
2771 viewport.getAlignment());
2773 addHistoryItem(removeGapCols);
2775 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2777 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2779 // This is to maintain viewport position on first residue
2780 // of first sequence
2781 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2782 ViewportRanges ranges = viewport.getRanges();
2783 int startRes = seq.findPosition(ranges.getStartRes());
2784 // ShiftList shifts;
2785 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2786 // edit.alColumnChanges=shifts.getInverse();
2787 // if (viewport.hasHiddenColumns)
2788 // viewport.getColumnSelection().compensateForEdits(shifts);
2789 ranges.setStartRes(seq.findIndex(startRes) - 1);
2790 viewport.firePropertyChange("alignment", null,
2791 viewport.getAlignment().getSequences());
2802 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2804 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2807 if (viewport.getSelectionGroup() != null)
2809 seqs = viewport.getSelectionGroup()
2810 .getSequencesAsArray(viewport.getHiddenRepSequences());
2811 start = viewport.getSelectionGroup().getStartRes();
2812 end = viewport.getSelectionGroup().getEndRes();
2816 seqs = viewport.getAlignment().getSequencesArray();
2819 // This is to maintain viewport position on first residue
2820 // of first sequence
2821 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2822 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2824 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2825 viewport.getAlignment()));
2827 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2829 viewport.firePropertyChange("alignment", null,
2830 viewport.getAlignment().getSequences());
2841 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2843 viewport.setPadGaps(padGapsMenuitem.isSelected());
2844 viewport.firePropertyChange("alignment", null,
2845 viewport.getAlignment().getSequences());
2849 * Opens a Finder dialog
2854 public void findMenuItem_actionPerformed(ActionEvent e)
2856 new Finder(alignPanel, false, null);
2860 * Create a new view of the current alignment.
2863 public void newView_actionPerformed(ActionEvent e)
2865 newView(null, true);
2869 * Creates and shows a new view of the current alignment.
2872 * title of newly created view; if null, one will be generated
2873 * @param copyAnnotation
2874 * if true then duplicate all annnotation, groups and settings
2875 * @return new alignment panel, already displayed.
2877 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2880 * Create a new AlignmentPanel (with its own, new Viewport)
2882 AlignmentPanel newap = new jalview.project.Jalview2XML()
2883 .copyAlignPanel(alignPanel);
2884 if (!copyAnnotation)
2887 * remove all groups and annotation except for the automatic stuff
2889 newap.av.getAlignment().deleteAllGroups();
2890 newap.av.getAlignment().deleteAllAnnotations(false);
2893 newap.av.setGatherViewsHere(false);
2895 if (viewport.getViewName() == null)
2897 viewport.setViewName(
2898 MessageManager.getString("label.view_name_original"));
2902 * Views share the same edits undo and redo stacks
2904 newap.av.setHistoryList(viewport.getHistoryList());
2905 newap.av.setRedoList(viewport.getRedoList());
2908 * copy any visualisation settings that are not saved in the project
2910 newap.av.setColourAppliesToAllGroups(
2911 viewport.getColourAppliesToAllGroups());
2914 * Views share the same mappings; need to deregister any new mappings
2915 * created by copyAlignPanel, and register the new reference to the shared
2918 newap.av.replaceMappings(viewport.getAlignment());
2921 * start up cDNA consensus (if applicable) now mappings are in place
2923 if (newap.av.initComplementConsensus())
2925 newap.refresh(true); // adjust layout of annotations
2928 newap.av.setViewName(getNewViewName(viewTitle));
2930 addAlignmentPanel(newap, true);
2931 newap.alignmentChanged();
2933 if (alignPanels.size() == 2)
2935 viewport.setGatherViewsHere(true);
2937 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2943 * Make a new name for the view, ensuring it is unique within the current
2944 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2945 * these now use viewId. Unique view names are still desirable for usability.)
2950 protected String getNewViewName(String viewTitle)
2952 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2953 boolean addFirstIndex = false;
2954 if (viewTitle == null || viewTitle.trim().length() == 0)
2956 viewTitle = MessageManager.getString("action.view");
2957 addFirstIndex = true;
2961 index = 1;// we count from 1 if given a specific name
2963 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2965 List<Component> comps = PaintRefresher.components
2966 .get(viewport.getSequenceSetId());
2968 List<String> existingNames = getExistingViewNames(comps);
2970 while (existingNames.contains(newViewName))
2972 newViewName = viewTitle + " " + (++index);
2978 * Returns a list of distinct view names found in the given list of
2979 * components. View names are held on the viewport of an AlignmentPanel.
2984 protected List<String> getExistingViewNames(List<Component> comps)
2986 List<String> existingNames = new ArrayList<>();
2987 for (Component comp : comps)
2989 if (comp instanceof AlignmentPanel)
2991 AlignmentPanel ap = (AlignmentPanel) comp;
2992 if (!existingNames.contains(ap.av.getViewName()))
2994 existingNames.add(ap.av.getViewName());
2998 return existingNames;
3002 * Explode tabbed views into separate windows.
3005 public void expandViews_actionPerformed(ActionEvent e)
3007 Desktop.explodeViews(this);
3011 * Gather views in separate windows back into a tabbed presentation.
3014 public void gatherViews_actionPerformed(ActionEvent e)
3016 Desktop.instance.gatherViews(this);
3026 public void font_actionPerformed(ActionEvent e)
3028 new FontChooser(alignPanel);
3038 protected void seqLimit_actionPerformed(ActionEvent e)
3040 viewport.setShowJVSuffix(seqLimits.isSelected());
3042 alignPanel.getIdPanel().getIdCanvas()
3043 .setPreferredSize(alignPanel.calculateIdWidth());
3044 alignPanel.paintAlignment(true, false);
3048 public void idRightAlign_actionPerformed(ActionEvent e)
3050 viewport.setRightAlignIds(idRightAlign.isSelected());
3051 alignPanel.paintAlignment(false, false);
3055 public void centreColumnLabels_actionPerformed(ActionEvent e)
3057 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3058 alignPanel.paintAlignment(false, false);
3064 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3067 protected void followHighlight_actionPerformed()
3070 * Set the 'follow' flag on the Viewport (and scroll to position if now
3073 final boolean state = this.followHighlightMenuItem.getState();
3074 viewport.setFollowHighlight(state);
3077 alignPanel.scrollToPosition(viewport.getSearchResults());
3088 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3090 viewport.setColourText(colourTextMenuItem.isSelected());
3091 alignPanel.paintAlignment(false, false);
3101 public void wrapMenuItem_actionPerformed(ActionEvent e)
3103 scaleAbove.setVisible(wrapMenuItem.isSelected());
3104 scaleLeft.setVisible(wrapMenuItem.isSelected());
3105 scaleRight.setVisible(wrapMenuItem.isSelected());
3106 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3107 alignPanel.updateLayout();
3111 public void showAllSeqs_actionPerformed(ActionEvent e)
3113 viewport.showAllHiddenSeqs();
3117 public void showAllColumns_actionPerformed(ActionEvent e)
3119 viewport.showAllHiddenColumns();
3120 alignPanel.paintAlignment(true, true);
3121 viewport.sendSelection();
3125 public void hideSelSequences_actionPerformed(ActionEvent e)
3127 viewport.hideAllSelectedSeqs();
3131 * called by key handler and the hide all/show all menu items
3136 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3139 boolean hide = false;
3140 SequenceGroup sg = viewport.getSelectionGroup();
3141 if (!toggleSeqs && !toggleCols)
3143 // Hide everything by the current selection - this is a hack - we do the
3144 // invert and then hide
3145 // first check that there will be visible columns after the invert.
3146 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3147 && sg.getStartRes() <= sg.getEndRes()))
3149 // now invert the sequence set, if required - empty selection implies
3150 // that no hiding is required.
3153 invertSequenceMenuItem_actionPerformed(null);
3154 sg = viewport.getSelectionGroup();
3158 viewport.expandColSelection(sg, true);
3159 // finally invert the column selection and get the new sequence
3161 invertColSel_actionPerformed(null);
3168 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3170 hideSelSequences_actionPerformed(null);
3173 else if (!(toggleCols && viewport.hasSelectedColumns()))
3175 showAllSeqs_actionPerformed(null);
3181 if (viewport.hasSelectedColumns())
3183 hideSelColumns_actionPerformed(null);
3186 viewport.setSelectionGroup(sg);
3191 showAllColumns_actionPerformed(null);
3200 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3201 * event.ActionEvent)
3204 public void hideAllButSelection_actionPerformed(ActionEvent e)
3206 toggleHiddenRegions(false, false);
3207 viewport.sendSelection();
3214 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3218 public void hideAllSelection_actionPerformed(ActionEvent e)
3220 SequenceGroup sg = viewport.getSelectionGroup();
3221 viewport.expandColSelection(sg, false);
3222 viewport.hideAllSelectedSeqs();
3223 viewport.hideSelectedColumns();
3224 alignPanel.updateLayout();
3225 alignPanel.paintAlignment(true, true);
3226 viewport.sendSelection();
3233 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3237 public void showAllhidden_actionPerformed(ActionEvent e)
3239 viewport.showAllHiddenColumns();
3240 viewport.showAllHiddenSeqs();
3241 alignPanel.paintAlignment(true, true);
3242 viewport.sendSelection();
3246 public void hideSelColumns_actionPerformed(ActionEvent e)
3248 viewport.hideSelectedColumns();
3249 alignPanel.updateLayout();
3250 alignPanel.paintAlignment(true, true);
3251 viewport.sendSelection();
3255 public void hiddenMarkers_actionPerformed(ActionEvent e)
3257 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3268 protected void scaleAbove_actionPerformed(ActionEvent e)
3270 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3271 alignPanel.updateLayout();
3272 alignPanel.paintAlignment(true, false);
3282 protected void scaleLeft_actionPerformed(ActionEvent e)
3284 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3285 alignPanel.updateLayout();
3286 alignPanel.paintAlignment(true, false);
3296 protected void scaleRight_actionPerformed(ActionEvent e)
3298 viewport.setScaleRightWrapped(scaleRight.isSelected());
3299 alignPanel.updateLayout();
3300 alignPanel.paintAlignment(true, false);
3310 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3312 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3313 alignPanel.paintAlignment(false, false);
3323 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3325 viewport.setShowText(viewTextMenuItem.isSelected());
3326 alignPanel.paintAlignment(false, false);
3336 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3338 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3339 alignPanel.paintAlignment(false, false);
3342 public FeatureSettings featureSettings;
3345 public FeatureSettingsControllerI getFeatureSettingsUI()
3347 return featureSettings;
3351 public void featureSettings_actionPerformed(ActionEvent e)
3353 showFeatureSettingsUI();
3357 public FeatureSettingsControllerI showFeatureSettingsUI()
3359 if (featureSettings != null)
3361 featureSettings.closeOldSettings();
3362 featureSettings = null;
3364 if (!showSeqFeatures.isSelected())
3366 // make sure features are actually displayed
3367 showSeqFeatures.setSelected(true);
3368 showSeqFeatures_actionPerformed(null);
3370 featureSettings = new FeatureSettings(this);
3371 return featureSettings;
3375 * Set or clear 'Show Sequence Features'
3381 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3383 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3384 alignPanel.paintAlignment(true, true);
3388 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3389 * the annotations panel as a whole.
3391 * The options to show/hide all annotations should be enabled when the panel
3392 * is shown, and disabled when the panel is hidden.
3397 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3399 final boolean setVisible = annotationPanelMenuItem.isSelected();
3400 viewport.setShowAnnotation(setVisible);
3401 this.showAllSeqAnnotations.setEnabled(setVisible);
3402 this.hideAllSeqAnnotations.setEnabled(setVisible);
3403 this.showAllAlAnnotations.setEnabled(setVisible);
3404 this.hideAllAlAnnotations.setEnabled(setVisible);
3405 alignPanel.updateLayout();
3409 public void alignmentProperties()
3412 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3415 String content = MessageManager.formatMessage("label.html_content",
3417 { contents.toString() });
3420 if (Platform.isJS())
3422 JLabel textLabel = new JLabel();
3423 textLabel.setText(content);
3424 textLabel.setBackground(Color.WHITE);
3426 pane = new JPanel(new BorderLayout());
3427 ((JPanel) pane).setOpaque(true);
3428 pane.setBackground(Color.WHITE);
3429 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3438 JEditorPane editPane = new JEditorPane("text/html", "");
3439 editPane.setEditable(false);
3440 editPane.setText(content);
3444 JInternalFrame frame = new JInternalFrame();
3446 frame.getContentPane().add(new JScrollPane(pane));
3448 Desktop.addInternalFrame(frame, MessageManager
3449 .formatMessage("label.alignment_properties", new Object[]
3450 { getTitle() }), 500, 400);
3454 * Opens an Overview panel for the alignment, unless one is open already
3459 public void overviewMenuItem_actionPerformed(ActionEvent e)
3461 boolean showHiddenRegions = Cache
3462 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3463 openOverviewPanel(showHiddenRegions);
3466 public OverviewPanel openOverviewPanel(boolean showHidden)
3468 if (alignPanel.overviewPanel != null)
3470 return alignPanel.overviewPanel;
3472 JInternalFrame frame = new JInternalFrame();
3473 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3475 frame.setContentPane(overview);
3476 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3477 frame.getHeight(), true, true);
3478 frame.setFrameIcon(null);
3480 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3481 final AlignmentPanel thePanel = this.alignPanel;
3482 frame.addInternalFrameListener(
3483 new javax.swing.event.InternalFrameAdapter()
3486 public void internalFrameClosed(
3487 javax.swing.event.InternalFrameEvent evt)
3490 thePanel.setOverviewPanel(null);
3493 if (getKeyListeners().length > 0)
3495 frame.addKeyListener(getKeyListeners()[0]);
3498 alignPanel.setOverviewPanel(overview);
3499 alignPanel.setOverviewTitle(this);
3505 public void textColour_actionPerformed()
3507 new TextColourChooser().chooseColour(alignPanel, null);
3511 * public void covariationColour_actionPerformed() {
3513 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3517 public void annotationColour_actionPerformed()
3519 new AnnotationColourChooser(viewport, alignPanel);
3523 public void annotationColumn_actionPerformed(ActionEvent e)
3525 new AnnotationColumnChooser(viewport, alignPanel);
3529 * Action on the user checking or unchecking the option to apply the selected
3530 * colour scheme to all groups. If unchecked, groups may have their own
3531 * independent colour schemes.
3536 public void applyToAllGroups_actionPerformed(boolean selected)
3538 viewport.setColourAppliesToAllGroups(selected);
3542 * Action on user selecting a colour from the colour menu
3545 * the name (not the menu item label!) of the colour scheme
3548 public void changeColour_actionPerformed(String name)
3551 * 'User Defined' opens a panel to configure or load a
3552 * user-defined colour scheme
3554 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3556 new UserDefinedColours(alignPanel);
3561 * otherwise set the chosen colour scheme (or null for 'None')
3563 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3564 viewport, viewport.getAlignment(),
3565 viewport.getHiddenRepSequences());
3570 * Actions on setting or changing the alignment colour scheme
3575 public void changeColour(ColourSchemeI cs)
3577 // TODO: pull up to controller method
3578 ColourMenuHelper.setColourSelected(colourMenu, cs);
3580 viewport.setGlobalColourScheme(cs);
3582 alignPanel.paintAlignment(true, true);
3586 * Show the PID threshold slider panel
3589 protected void modifyPID_actionPerformed()
3591 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3592 alignPanel.getViewName());
3593 SliderPanel.showPIDSlider();
3597 * Show the Conservation slider panel
3600 protected void modifyConservation_actionPerformed()
3602 SliderPanel.setConservationSlider(alignPanel,
3603 viewport.getResidueShading(), alignPanel.getViewName());
3604 SliderPanel.showConservationSlider();
3608 * Action on selecting or deselecting (Colour) By Conservation
3611 public void conservationMenuItem_actionPerformed(boolean selected)
3613 modifyConservation.setEnabled(selected);
3614 viewport.setConservationSelected(selected);
3615 viewport.getResidueShading().setConservationApplied(selected);
3617 changeColour(viewport.getGlobalColourScheme());
3620 modifyConservation_actionPerformed();
3624 SliderPanel.hideConservationSlider();
3629 * Action on selecting or deselecting (Colour) Above PID Threshold
3632 public void abovePIDThreshold_actionPerformed(boolean selected)
3634 modifyPID.setEnabled(selected);
3635 viewport.setAbovePIDThreshold(selected);
3638 viewport.getResidueShading().setThreshold(0,
3639 viewport.isIgnoreGapsConsensus());
3642 changeColour(viewport.getGlobalColourScheme());
3645 modifyPID_actionPerformed();
3649 SliderPanel.hidePIDSlider();
3660 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3662 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3663 AlignmentSorter.sortByPID(viewport.getAlignment(),
3664 viewport.getAlignment().getSequenceAt(0));
3665 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3666 viewport.getAlignment()));
3667 alignPanel.paintAlignment(true, false);
3677 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3679 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3680 AlignmentSorter.sortByID(viewport.getAlignment());
3682 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3683 alignPanel.paintAlignment(true, false);
3693 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3695 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3696 AlignmentSorter.sortByLength(viewport.getAlignment());
3697 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3698 viewport.getAlignment()));
3699 alignPanel.paintAlignment(true, false);
3709 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3711 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3712 AlignmentSorter.sortByGroup(viewport.getAlignment());
3713 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3714 viewport.getAlignment()));
3716 alignPanel.paintAlignment(true, false);
3726 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3728 new RedundancyPanel(alignPanel, this);
3738 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3740 if ((viewport.getSelectionGroup() == null)
3741 || (viewport.getSelectionGroup().getSize() < 2))
3743 JvOptionPane.showInternalMessageDialog(this,
3744 MessageManager.getString(
3745 "label.you_must_select_least_two_sequences"),
3746 MessageManager.getString("label.invalid_selection"),
3747 JvOptionPane.WARNING_MESSAGE);
3751 JInternalFrame frame = new JInternalFrame();
3752 frame.setContentPane(new PairwiseAlignPanel(viewport));
3753 Desktop.addInternalFrame(frame,
3754 MessageManager.getString("action.pairwise_alignment"), 600,
3760 public void autoCalculate_actionPerformed(ActionEvent e)
3762 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3763 if (viewport.autoCalculateConsensus)
3765 viewport.firePropertyChange("alignment", null,
3766 viewport.getAlignment().getSequences());
3771 public void sortByTreeOption_actionPerformed(ActionEvent e)
3773 viewport.sortByTree = sortByTree.isSelected();
3777 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3779 viewport.followSelection = listenToViewSelections.isSelected();
3783 * Constructs a tree panel and adds it to the desktop
3786 * tree type (NJ or AV)
3788 * name of score model used to compute the tree
3790 * parameters for the distance or similarity calculation
3792 void newTreePanel(String type, String modelName,
3793 SimilarityParamsI options)
3795 String frameTitle = "";
3798 boolean onSelection = false;
3799 if (viewport.getSelectionGroup() != null
3800 && viewport.getSelectionGroup().getSize() > 0)
3802 SequenceGroup sg = viewport.getSelectionGroup();
3804 /* Decide if the selection is a column region */
3805 for (SequenceI _s : sg.getSequences())
3807 if (_s.getLength() < sg.getEndRes())
3809 JvOptionPane.showMessageDialog(Desktop.desktop,
3810 MessageManager.getString(
3811 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3812 MessageManager.getString(
3813 "label.sequences_selection_not_aligned"),
3814 JvOptionPane.WARNING_MESSAGE);
3823 if (viewport.getAlignment().getHeight() < 2)
3829 tp = new TreePanel(alignPanel, type, modelName, options);
3830 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3832 frameTitle += " from ";
3834 if (viewport.getViewName() != null)
3836 frameTitle += viewport.getViewName() + " of ";
3839 frameTitle += this.title;
3841 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3852 public void addSortByOrderMenuItem(String title,
3853 final AlignmentOrder order)
3855 final JMenuItem item = new JMenuItem(MessageManager
3856 .formatMessage("action.by_title_param", new Object[]
3859 item.addActionListener(new java.awt.event.ActionListener()
3862 public void actionPerformed(ActionEvent e)
3864 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3866 // TODO: JBPNote - have to map order entries to curent SequenceI
3868 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3870 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3871 viewport.getAlignment()));
3873 alignPanel.paintAlignment(true, false);
3879 * Add a new sort by annotation score menu item
3882 * the menu to add the option to
3884 * the label used to retrieve scores for each sequence on the
3887 public void addSortByAnnotScoreMenuItem(JMenu sort,
3888 final String scoreLabel)
3890 final JMenuItem item = new JMenuItem(scoreLabel);
3892 item.addActionListener(new java.awt.event.ActionListener()
3895 public void actionPerformed(ActionEvent e)
3897 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3898 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3899 viewport.getAlignment());// ,viewport.getSelectionGroup());
3900 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3901 viewport.getAlignment()));
3902 alignPanel.paintAlignment(true, false);
3908 * last hash for alignment's annotation array - used to minimise cost of
3911 protected int _annotationScoreVectorHash;
3914 * search the alignment and rebuild the sort by annotation score submenu the
3915 * last alignment annotation vector hash is stored to minimize cost of
3916 * rebuilding in subsequence calls.
3920 public void buildSortByAnnotationScoresMenu()
3922 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3927 if (viewport.getAlignment().getAlignmentAnnotation()
3928 .hashCode() != _annotationScoreVectorHash)
3930 sortByAnnotScore.removeAll();
3931 // almost certainly a quicker way to do this - but we keep it simple
3932 Hashtable<String, String> scoreSorts = new Hashtable<>();
3933 AlignmentAnnotation aann[];
3934 for (SequenceI sqa : viewport.getAlignment().getSequences())
3936 aann = sqa.getAnnotation();
3937 for (int i = 0; aann != null && i < aann.length; i++)
3939 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3941 scoreSorts.put(aann[i].label, aann[i].label);
3945 Enumeration<String> labels = scoreSorts.keys();
3946 while (labels.hasMoreElements())
3948 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3950 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3953 _annotationScoreVectorHash = viewport.getAlignment()
3954 .getAlignmentAnnotation().hashCode();
3959 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3960 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3961 * call. Listeners are added to remove the menu item when the treePanel is
3962 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3966 public void buildTreeSortMenu()
3968 sortByTreeMenu.removeAll();
3970 List<Component> comps = PaintRefresher.components
3971 .get(viewport.getSequenceSetId());
3972 List<TreePanel> treePanels = new ArrayList<>();
3973 for (Component comp : comps)
3975 if (comp instanceof TreePanel)
3977 treePanels.add((TreePanel) comp);
3981 if (treePanels.size() < 1)
3983 sortByTreeMenu.setVisible(false);
3987 sortByTreeMenu.setVisible(true);
3989 for (final TreePanel tp : treePanels)
3991 final JMenuItem item = new JMenuItem(tp.getTitle());
3992 item.addActionListener(new java.awt.event.ActionListener()
3995 public void actionPerformed(ActionEvent e)
3997 tp.sortByTree_actionPerformed();
3998 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4003 sortByTreeMenu.add(item);
4007 public boolean sortBy(AlignmentOrder alorder, String undoname)
4009 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4010 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4011 if (undoname != null)
4013 addHistoryItem(new OrderCommand(undoname, oldOrder,
4014 viewport.getAlignment()));
4016 alignPanel.paintAlignment(true, false);
4021 * Work out whether the whole set of sequences or just the selected set will
4022 * be submitted for multiple alignment.
4025 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4027 // Now, check we have enough sequences
4028 AlignmentView msa = null;
4030 if ((viewport.getSelectionGroup() != null)
4031 && (viewport.getSelectionGroup().getSize() > 1))
4033 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4034 // some common interface!
4036 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4037 * SequenceI[sz = seqs.getSize(false)];
4039 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4040 * seqs.getSequenceAt(i); }
4042 msa = viewport.getAlignmentView(true);
4044 else if (viewport.getSelectionGroup() != null
4045 && viewport.getSelectionGroup().getSize() == 1)
4047 int option = JvOptionPane.showConfirmDialog(this,
4048 MessageManager.getString("warn.oneseq_msainput_selection"),
4049 MessageManager.getString("label.invalid_selection"),
4050 JvOptionPane.OK_CANCEL_OPTION);
4051 if (option == JvOptionPane.OK_OPTION)
4053 msa = viewport.getAlignmentView(false);
4058 msa = viewport.getAlignmentView(false);
4064 * Decides what is submitted to a secondary structure prediction service: the
4065 * first sequence in the alignment, or in the current selection, or, if the
4066 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4067 * region or the whole alignment. (where the first sequence in the set is the
4068 * one that the prediction will be for).
4070 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4072 AlignmentView seqs = null;
4074 if ((viewport.getSelectionGroup() != null)
4075 && (viewport.getSelectionGroup().getSize() > 0))
4077 seqs = viewport.getAlignmentView(true);
4081 seqs = viewport.getAlignmentView(false);
4083 // limit sequences - JBPNote in future - could spawn multiple prediction
4085 // TODO: viewport.getAlignment().isAligned is a global state - the local
4086 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4087 if (!viewport.getAlignment().isAligned(false))
4089 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4090 // TODO: if seqs.getSequences().length>1 then should really have warned
4104 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4106 // Pick the tree file
4107 JalviewFileChooser chooser = new JalviewFileChooser(
4108 Cache.getProperty("LAST_DIRECTORY"));
4109 chooser.setFileView(new JalviewFileView());
4110 chooser.setDialogTitle(
4111 MessageManager.getString("label.select_newick_like_tree_file"));
4112 chooser.setToolTipText(
4113 MessageManager.getString("label.load_tree_file"));
4115 chooser.setResponseHandler(0, () -> {
4116 String filePath = chooser.getSelectedFile().getPath();
4117 Cache.setProperty("LAST_DIRECTORY", filePath);
4118 NewickFile fin = null;
4121 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4122 DataSourceType.FILE));
4123 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4124 } catch (Exception ex)
4126 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4127 MessageManager.getString("label.problem_reading_tree_file"),
4128 JvOptionPane.WARNING_MESSAGE);
4129 ex.printStackTrace();
4131 if (fin != null && fin.hasWarningMessage())
4133 JvOptionPane.showMessageDialog(Desktop.desktop,
4134 fin.getWarningMessage(),
4136 .getString("label.possible_problem_with_tree_file"),
4137 JvOptionPane.WARNING_MESSAGE);
4141 chooser.showOpenDialog(this);
4144 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4146 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4149 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4150 int h, int x, int y)
4152 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4156 * Add a treeviewer for the tree extracted from a Newick file object to the
4157 * current alignment view
4164 * Associated alignment input data (or null)
4173 * @return TreePanel handle
4175 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4176 AlignmentView input, int w, int h, int x, int y)
4178 TreePanel tp = null;
4184 if (nf.getTree() != null)
4186 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4192 tp.setLocation(x, y);
4195 Desktop.addInternalFrame(tp, treeTitle, w, h);
4197 } catch (Exception ex)
4199 ex.printStackTrace();
4205 public void showContactMapTree(AlignmentAnnotation aa,
4209 int w = 400, h = 500;
4213 NewickFile fin = new NewickFile(
4214 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4215 String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree"
4216 + aa.sequenceRef != null
4217 ? (" for " + aa.sequenceRef.getDisplayId(false))
4220 showColumnWiseTree(fin, aa, title, w, h, x, y);
4221 } catch (Throwable xx)
4223 Console.error("Unexpected exception showing tree for contact matrix",
4228 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4229 String treeTitle, int w, int h, int x, int y)
4234 if (nf.getTree() == null)
4238 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4244 tp.setLocation(x, y);
4247 Desktop.addInternalFrame(tp, title, w, h);
4249 } catch (Throwable xx)
4251 Console.error("Unexpected exception showing tree for contact matrix",
4257 private boolean buildingMenu = false;
4260 * Generates menu items and listener event actions for web service clients
4263 public void BuildWebServiceMenu()
4265 while (buildingMenu)
4269 System.err.println("Waiting for building menu to finish.");
4271 } catch (Exception e)
4275 final AlignFrame me = this;
4276 buildingMenu = true;
4277 new Thread(new Runnable()
4282 final List<JMenuItem> legacyItems = new ArrayList<>();
4285 // System.err.println("Building ws menu again "
4286 // + Thread.currentThread());
4287 // TODO: add support for context dependent disabling of services based
4289 // alignment and current selection
4290 // TODO: add additional serviceHandle parameter to specify abstract
4292 // class independently of AbstractName
4293 // TODO: add in rediscovery GUI function to restart discoverer
4294 // TODO: group services by location as well as function and/or
4296 // object broker mechanism.
4297 final Vector<JMenu> wsmenu = new Vector<>();
4298 final IProgressIndicator af = me;
4301 * do not i18n these strings - they are hard-coded in class
4302 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4303 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4305 final JMenu msawsmenu = new JMenu("Alignment");
4306 final JMenu secstrmenu = new JMenu(
4307 "Secondary Structure Prediction");
4308 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4309 final JMenu analymenu = new JMenu("Analysis");
4310 final JMenu dismenu = new JMenu("Protein Disorder");
4311 // JAL-940 - only show secondary structure prediction services from
4312 // the legacy server
4313 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4315 Discoverer.services != null && (Discoverer.services.size() > 0))
4317 // TODO: refactor to allow list of AbstractName/Handler bindings to
4319 // stored or retrieved from elsewhere
4320 // No MSAWS used any more:
4321 // Vector msaws = null; // (Vector)
4322 // Discoverer.services.get("MsaWS");
4323 Vector<ServiceHandle> secstrpr = Discoverer.services
4325 if (secstrpr != null)
4327 // Add any secondary structure prediction services
4328 for (int i = 0, j = secstrpr.size(); i < j; i++)
4330 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4331 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4332 .getServiceClient(sh);
4333 int p = secstrmenu.getItemCount();
4334 impl.attachWSMenuEntry(secstrmenu, me);
4335 int q = secstrmenu.getItemCount();
4336 for (int litm = p; litm < q; litm++)
4338 legacyItems.add(secstrmenu.getItem(litm));
4344 // Add all submenus in the order they should appear on the web
4346 wsmenu.add(msawsmenu);
4347 wsmenu.add(secstrmenu);
4348 wsmenu.add(dismenu);
4349 wsmenu.add(analymenu);
4350 // No search services yet
4351 // wsmenu.add(seqsrchmenu);
4353 javax.swing.SwingUtilities.invokeLater(new Runnable()
4360 webService.removeAll();
4361 // first, add discovered services onto the webservices menu
4362 if (wsmenu.size() > 0)
4364 for (int i = 0, j = wsmenu.size(); i < j; i++)
4366 webService.add(wsmenu.get(i));
4371 webService.add(me.webServiceNoServices);
4373 // TODO: move into separate menu builder class.
4375 // logic for 2.11.1.4 is
4376 // always look to see if there is a discover. if there isn't
4377 // we can't show any Jws2 services
4378 // if there are services available, show them - regardless of
4379 // the 'show JWS2 preference'
4380 // if the discoverer is running then say so
4381 // otherwise offer to trigger discovery if 'show JWS2' is not
4383 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4384 if (jws2servs != null)
4386 if (jws2servs.hasServices())
4388 jws2servs.attachWSMenuEntry(webService, me);
4389 for (Jws2Instance sv : jws2servs.getServices())
4391 if (sv.description.toLowerCase(Locale.ROOT)
4394 for (JMenuItem jmi : legacyItems)
4396 jmi.setVisible(false);
4402 if (jws2servs.isRunning())
4404 JMenuItem tm = new JMenuItem(
4405 "Still discovering JABA Services");
4406 tm.setEnabled(false);
4409 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4411 JMenuItem enableJws2 = new JMenuItem(
4412 "Discover Web Services");
4413 enableJws2.setToolTipText(
4414 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4415 enableJws2.setEnabled(true);
4416 enableJws2.addActionListener(new ActionListener()
4420 public void actionPerformed(ActionEvent e)
4422 // start service discoverer, but ignore preference
4423 Desktop.instance.startServiceDiscovery(false,
4427 webService.add(enableJws2);
4431 build_urlServiceMenu(me.webService);
4432 build_fetchdbmenu(webService);
4433 for (JMenu item : wsmenu)
4435 if (item.getItemCount() == 0)
4437 item.setEnabled(false);
4441 item.setEnabled(true);
4444 } catch (Exception e)
4447 "Exception during web service menu building process.",
4452 } catch (Exception e)
4455 buildingMenu = false;
4462 * construct any groupURL type service menu entries.
4466 protected void build_urlServiceMenu(JMenu webService)
4468 // TODO: remove this code when 2.7 is released
4469 // DEBUG - alignmentView
4471 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4472 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4474 * @Override public void actionPerformed(ActionEvent e) {
4475 * jalview.datamodel.AlignmentView
4476 * .testSelectionViews(af.viewport.getAlignment(),
4477 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4479 * }); webService.add(testAlView);
4481 // TODO: refactor to RestClient discoverer and merge menu entries for
4482 // rest-style services with other types of analysis/calculation service
4483 // SHmmr test client - still being implemented.
4484 // DEBUG - alignmentView
4486 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4489 client.attachWSMenuEntry(
4490 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4496 * Searches the alignment sequences for xRefs and builds the Show
4497 * Cross-References menu (formerly called Show Products), with database
4498 * sources for which cross-references are found (protein sources for a
4499 * nucleotide alignment and vice versa)
4501 * @return true if Show Cross-references menu should be enabled
4503 public boolean canShowProducts()
4505 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4506 AlignmentI dataset = viewport.getAlignment().getDataset();
4508 showProducts.removeAll();
4509 final boolean dna = viewport.getAlignment().isNucleotide();
4511 if (seqs == null || seqs.length == 0)
4513 // nothing to see here.
4517 boolean showp = false;
4520 List<String> ptypes = new CrossRef(seqs, dataset)
4521 .findXrefSourcesForSequences(dna);
4523 for (final String source : ptypes)
4526 final AlignFrame af = this;
4527 JMenuItem xtype = new JMenuItem(source);
4528 xtype.addActionListener(new ActionListener()
4531 public void actionPerformed(ActionEvent e)
4533 showProductsFor(af.viewport.getSequenceSelection(), dna,
4537 showProducts.add(xtype);
4539 showProducts.setVisible(showp);
4540 showProducts.setEnabled(showp);
4541 } catch (Exception e)
4544 "canShowProducts threw an exception - please report to help@jalview.org",
4552 * Finds and displays cross-references for the selected sequences (protein
4553 * products for nucleotide sequences, dna coding sequences for peptides).
4556 * the sequences to show cross-references for
4558 * true if from a nucleotide alignment (so showing proteins)
4560 * the database to show cross-references for
4562 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4563 final String source)
4565 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4570 * Construct and display a new frame containing the translation of this
4571 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4574 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4576 AlignmentI al = null;
4579 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4581 al = dna.translateCdna(codeTable);
4582 } catch (Exception ex)
4584 Console.error("Exception during translation. Please report this !",
4586 final String msg = MessageManager.getString(
4587 "label.error_when_translating_sequences_submit_bug_report");
4588 final String errorTitle = MessageManager
4589 .getString("label.implementation_error")
4590 + MessageManager.getString("label.translation_failed");
4591 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4592 JvOptionPane.ERROR_MESSAGE);
4595 if (al == null || al.getHeight() == 0)
4597 final String msg = MessageManager.getString(
4598 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4599 final String errorTitle = MessageManager
4600 .getString("label.translation_failed");
4601 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4602 JvOptionPane.WARNING_MESSAGE);
4606 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4607 af.setFileFormat(this.currentFileFormat);
4608 final String newTitle = MessageManager
4609 .formatMessage("label.translation_of_params", new Object[]
4610 { this.getTitle(), codeTable.getId() });
4611 af.setTitle(newTitle);
4612 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4614 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4615 viewport.openSplitFrame(af, new Alignment(seqs));
4619 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4626 * Set the file format
4630 public void setFileFormat(FileFormatI format)
4632 this.currentFileFormat = format;
4636 * Try to load a features file onto the alignment.
4639 * contents or path to retrieve file or a File object
4641 * access mode of file (see jalview.io.AlignFile)
4642 * @return true if features file was parsed correctly.
4644 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4647 return avc.parseFeaturesFile(file, sourceType,
4648 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4653 public void refreshFeatureUI(boolean enableIfNecessary)
4655 // note - currently this is only still here rather than in the controller
4656 // because of the featureSettings hard reference that is yet to be
4658 if (enableIfNecessary)
4660 viewport.setShowSequenceFeatures(true);
4661 showSeqFeatures.setSelected(true);
4667 public void dragEnter(DropTargetDragEvent evt)
4672 public void dragExit(DropTargetEvent evt)
4677 public void dragOver(DropTargetDragEvent evt)
4682 public void dropActionChanged(DropTargetDragEvent evt)
4687 public void drop(DropTargetDropEvent evt)
4689 // JAL-1552 - acceptDrop required before getTransferable call for
4690 // Java's Transferable for native dnd
4691 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4692 Transferable t = evt.getTransferable();
4694 final AlignFrame thisaf = this;
4695 final List<Object> files = new ArrayList<>();
4696 List<DataSourceType> protocols = new ArrayList<>();
4700 Desktop.transferFromDropTarget(files, protocols, evt, t);
4701 } catch (Exception e)
4703 e.printStackTrace();
4707 new Thread(new Runnable()
4714 // check to see if any of these files have names matching sequences
4717 SequenceIdMatcher idm = new SequenceIdMatcher(
4718 viewport.getAlignment().getSequencesArray());
4720 * Object[] { String,SequenceI}
4722 ArrayList<Object[]> filesmatched = new ArrayList<>();
4723 ArrayList<Object> filesnotmatched = new ArrayList<>();
4724 for (int i = 0; i < files.size(); i++)
4727 Object file = files.get(i);
4728 String fileName = file.toString();
4730 DataSourceType protocol = (file instanceof File
4731 ? DataSourceType.FILE
4732 : FormatAdapter.checkProtocol(fileName));
4733 if (protocol == DataSourceType.FILE)
4736 if (file instanceof File)
4739 Platform.cacheFileData(fl);
4743 fl = new File(fileName);
4745 pdbfn = fl.getName();
4747 else if (protocol == DataSourceType.URL)
4749 URL url = new URL(fileName);
4750 pdbfn = url.getFile();
4752 if (pdbfn.length() > 0)
4754 // attempt to find a match in the alignment
4755 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4756 int l = 0, c = pdbfn.indexOf(".");
4757 while (mtch == null && c != -1)
4762 } while ((c = pdbfn.indexOf(".", l)) > l);
4765 pdbfn = pdbfn.substring(0, l);
4767 mtch = idm.findAllIdMatches(pdbfn);
4774 type = new IdentifyFile().identify(file, protocol);
4775 } catch (Exception ex)
4779 if (type != null && type.isStructureFile())
4781 filesmatched.add(new Object[] { file, protocol, mtch });
4785 // File wasn't named like one of the sequences or wasn't a PDB
4787 filesnotmatched.add(file);
4791 if (filesmatched.size() > 0)
4793 boolean autoAssociate = Cache
4794 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4797 String msg = MessageManager.formatMessage(
4798 "label.automatically_associate_structure_files_with_sequences_same_name",
4800 { Integer.valueOf(filesmatched.size())
4802 String ttl = MessageManager.getString(
4803 "label.automatically_associate_structure_files_by_name");
4804 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4805 ttl, JvOptionPane.YES_NO_OPTION);
4806 autoAssociate = choice == JvOptionPane.YES_OPTION;
4810 for (Object[] fm : filesmatched)
4812 // try and associate
4813 // TODO: may want to set a standard ID naming formalism for
4814 // associating PDB files which have no IDs.
4815 for (SequenceI toassoc : (SequenceI[]) fm[2])
4817 PDBEntry pe = new AssociatePdbFileWithSeq()
4818 .associatePdbWithSeq(fm[0].toString(),
4819 (DataSourceType) fm[1], toassoc, false,
4823 System.err.println("Associated file : "
4824 + (fm[0].toString()) + " with "
4825 + toassoc.getDisplayId(true));
4829 // TODO: do we need to update overview ? only if features are
4831 alignPanel.paintAlignment(true, false);
4837 * add declined structures as sequences
4839 for (Object[] o : filesmatched)
4841 filesnotmatched.add(o[0]);
4845 if (filesnotmatched.size() > 0)
4847 if (assocfiles > 0 && (Cache.getDefault(
4848 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4849 || JvOptionPane.showConfirmDialog(thisaf,
4850 "<html>" + MessageManager.formatMessage(
4851 "label.ignore_unmatched_dropped_files_info",
4854 filesnotmatched.size())
4857 MessageManager.getString(
4858 "label.ignore_unmatched_dropped_files"),
4859 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4863 for (Object fn : filesnotmatched)
4865 loadJalviewDataFile(fn, null, null, null);
4869 } catch (Exception ex)
4871 ex.printStackTrace();
4879 * Attempt to load a "dropped" file or URL string, by testing in turn for
4881 * <li>an Annotation file</li>
4882 * <li>a JNet file</li>
4883 * <li>a features file</li>
4884 * <li>else try to interpret as an alignment file</li>
4888 * either a filename or a URL string.
4890 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4891 FileFormatI format, SequenceI assocSeq)
4893 // BH 2018 was String file
4896 if (sourceType == null)
4898 sourceType = FormatAdapter.checkProtocol(file);
4900 // if the file isn't identified, or not positively identified as some
4901 // other filetype (PFAM is default unidentified alignment file type) then
4902 // try to parse as annotation.
4903 boolean isAnnotation = (format == null
4904 || FileFormat.Pfam.equals(format))
4905 ? new AnnotationFile().annotateAlignmentView(viewport,
4911 // first see if its a T-COFFEE score file
4912 TCoffeeScoreFile tcf = null;
4915 tcf = new TCoffeeScoreFile(file, sourceType);
4918 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4922 new TCoffeeColourScheme(viewport.getAlignment()));
4923 isAnnotation = true;
4924 setStatus(MessageManager.getString(
4925 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4929 // some problem - if no warning its probable that the ID matching
4930 // process didn't work
4931 JvOptionPane.showMessageDialog(Desktop.desktop,
4932 tcf.getWarningMessage() == null
4933 ? MessageManager.getString(
4934 "label.check_file_matches_sequence_ids_alignment")
4935 : tcf.getWarningMessage(),
4936 MessageManager.getString(
4937 "label.problem_reading_tcoffee_score_file"),
4938 JvOptionPane.WARNING_MESSAGE);
4945 } catch (Exception x)
4948 "Exception when processing data source as T-COFFEE score file",
4954 // try to see if its a JNet 'concise' style annotation file *before*
4956 // try to parse it as a features file
4959 format = new IdentifyFile().identify(file, sourceType);
4961 if (FileFormat.ScoreMatrix == format)
4963 ScoreMatrixFile sm = new ScoreMatrixFile(
4964 new FileParse(file, sourceType));
4966 // todo: i18n this message
4967 setStatus(MessageManager.formatMessage(
4968 "label.successfully_loaded_matrix",
4969 sm.getMatrixName()));
4971 else if (FileFormat.Jnet.equals(format))
4973 JPredFile predictions = new JPredFile(file, sourceType);
4974 new JnetAnnotationMaker();
4975 JnetAnnotationMaker.add_annotation(predictions,
4976 viewport.getAlignment(), 0, false);
4977 viewport.getAlignment().setupJPredAlignment();
4978 isAnnotation = true;
4980 // else if (IdentifyFile.FeaturesFile.equals(format))
4981 else if (FileFormat.Features.equals(format))
4983 if (parseFeaturesFile(file, sourceType))
4985 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
4986 if (splitFrame != null)
4988 splitFrame.repaint();
4992 alignPanel.paintAlignment(true, true);
4998 new FileLoader().LoadFile(viewport, file, sourceType, format);
5005 alignPanel.adjustAnnotationHeight();
5006 viewport.updateSequenceIdColours();
5007 buildSortByAnnotationScoresMenu();
5008 alignPanel.paintAlignment(true, true);
5010 } catch (Exception ex)
5012 ex.printStackTrace();
5013 } catch (OutOfMemoryError oom)
5018 } catch (Exception x)
5023 + (sourceType != null
5024 ? (sourceType == DataSourceType.PASTE
5026 : "using " + sourceType + " from "
5030 ? "(parsing as '" + format + "' file)"
5032 oom, Desktop.desktop);
5037 * Method invoked by the ChangeListener on the tabbed pane, in other words
5038 * when a different tabbed pane is selected by the user or programmatically.
5041 public void tabSelectionChanged(int index)
5046 * update current Overview window title (if there is one)
5047 * to add view name "Original" if necessary
5049 alignPanel.setOverviewTitle(this);
5052 * switch panels and set Overview title (if there is one
5053 * because it was opened automatically)
5055 alignPanel = alignPanels.get(index);
5056 alignPanel.setOverviewTitle(this);
5058 viewport = alignPanel.av;
5059 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5060 setMenusFromViewport(viewport);
5061 if (featureSettings != null && featureSettings.isOpen()
5062 && featureSettings.fr.getViewport() != viewport)
5064 if (viewport.isShowSequenceFeatures())
5066 // refresh the featureSettings to reflect UI change
5067 showFeatureSettingsUI();
5071 // close feature settings for this view.
5072 featureSettings.close();
5079 * 'focus' any colour slider that is open to the selected viewport
5081 if (viewport.getConservationSelected())
5083 SliderPanel.setConservationSlider(alignPanel,
5084 viewport.getResidueShading(), alignPanel.getViewName());
5088 SliderPanel.hideConservationSlider();
5090 if (viewport.getAbovePIDThreshold())
5092 SliderPanel.setPIDSliderSource(alignPanel,
5093 viewport.getResidueShading(), alignPanel.getViewName());
5097 SliderPanel.hidePIDSlider();
5101 * If there is a frame linked to this one in a SplitPane, switch it to the
5102 * same view tab index. No infinite recursion of calls should happen, since
5103 * tabSelectionChanged() should not get invoked on setting the selected
5104 * index to an unchanged value. Guard against setting an invalid index
5105 * before the new view peer tab has been created.
5107 final AlignViewportI peer = viewport.getCodingComplement();
5110 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5111 .getAlignPanel().alignFrame;
5112 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5114 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5120 * On right mouse click on view tab, prompt for and set new view name.
5123 public void tabbedPane_mousePressed(MouseEvent e)
5125 if (e.isPopupTrigger())
5127 String msg = MessageManager.getString("label.enter_view_name");
5128 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5129 String reply = JvOptionPane.showInputDialog(msg, ttl);
5133 viewport.setViewName(reply);
5134 // TODO warn if reply is in getExistingViewNames()?
5135 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5140 public AlignViewport getCurrentView()
5146 * Open the dialog for regex description parsing.
5149 protected void extractScores_actionPerformed(ActionEvent e)
5151 ParseProperties pp = new jalview.analysis.ParseProperties(
5152 viewport.getAlignment());
5153 // TODO: verify regex and introduce GUI dialog for version 2.5
5154 // if (pp.getScoresFromDescription("col", "score column ",
5155 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5157 if (pp.getScoresFromDescription("description column",
5158 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5160 buildSortByAnnotationScoresMenu();
5168 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5172 protected void showDbRefs_actionPerformed(ActionEvent e)
5174 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5180 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5184 protected void showNpFeats_actionPerformed(ActionEvent e)
5186 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5190 * find the viewport amongst the tabs in this alignment frame and close that
5195 public boolean closeView(AlignViewportI av)
5199 this.closeMenuItem_actionPerformed(false);
5202 Component[] comp = tabbedPane.getComponents();
5203 for (int i = 0; comp != null && i < comp.length; i++)
5205 if (comp[i] instanceof AlignmentPanel)
5207 if (((AlignmentPanel) comp[i]).av == av)
5210 closeView((AlignmentPanel) comp[i]);
5218 protected void build_fetchdbmenu(JMenu webService)
5220 // Temporary hack - DBRef Fetcher always top level ws entry.
5221 // TODO We probably want to store a sequence database checklist in
5222 // preferences and have checkboxes.. rather than individual sources selected
5224 final JMenu rfetch = new JMenu(
5225 MessageManager.getString("action.fetch_db_references"));
5226 rfetch.setToolTipText(MessageManager.getString(
5227 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5228 webService.add(rfetch);
5230 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5231 MessageManager.getString("option.trim_retrieved_seqs"));
5232 trimrs.setToolTipText(
5233 MessageManager.getString("label.trim_retrieved_sequences"));
5235 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5236 trimrs.addActionListener(new ActionListener()
5239 public void actionPerformed(ActionEvent e)
5241 trimrs.setSelected(trimrs.isSelected());
5242 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5243 Boolean.valueOf(trimrs.isSelected()).toString());
5247 JMenuItem fetchr = new JMenuItem(
5248 MessageManager.getString("label.standard_databases"));
5249 fetchr.setToolTipText(
5250 MessageManager.getString("label.fetch_embl_uniprot"));
5251 fetchr.addActionListener(new ActionListener()
5255 public void actionPerformed(ActionEvent e)
5257 new Thread(new Runnable()
5262 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5263 .getAlignment().isNucleotide();
5264 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5265 alignPanel.av.getSequenceSelection(),
5266 alignPanel.alignFrame, null,
5267 alignPanel.alignFrame.featureSettings, isNucleotide);
5268 dbRefFetcher.addListener(new FetchFinishedListenerI()
5271 public void finished()
5274 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5275 .getFeatureSettingsModels())
5278 alignPanel.av.mergeFeaturesStyle(srcSettings);
5280 AlignFrame.this.setMenusForViewport();
5283 dbRefFetcher.fetchDBRefs(false);
5291 new Thread(new Runnable()
5296 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5297 .getSequenceFetcherSingleton();
5298 javax.swing.SwingUtilities.invokeLater(new Runnable()
5303 String[] dbclasses = sf.getNonAlignmentSources();
5304 List<DbSourceProxy> otherdb;
5305 JMenu dfetch = new JMenu();
5306 JMenu ifetch = new JMenu();
5307 JMenuItem fetchr = null;
5308 int comp = 0, icomp = 0, mcomp = 15;
5309 String mname = null;
5311 for (String dbclass : dbclasses)
5313 otherdb = sf.getSourceProxy(dbclass);
5314 // add a single entry for this class, or submenu allowing 'fetch
5316 if (otherdb == null || otherdb.size() < 1)
5322 mname = "From " + dbclass;
5324 if (otherdb.size() == 1)
5326 final DbSourceProxy[] dassource = otherdb
5327 .toArray(new DbSourceProxy[0]);
5328 DbSourceProxy src = otherdb.get(0);
5329 fetchr = new JMenuItem(src.getDbSource());
5330 fetchr.addActionListener(new ActionListener()
5334 public void actionPerformed(ActionEvent e)
5336 new Thread(new Runnable()
5342 boolean isNucleotide = alignPanel.alignFrame
5343 .getViewport().getAlignment()
5345 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5346 alignPanel.av.getSequenceSelection(),
5347 alignPanel.alignFrame, dassource,
5348 alignPanel.alignFrame.featureSettings,
5351 .addListener(new FetchFinishedListenerI()
5354 public void finished()
5356 FeatureSettingsModelI srcSettings = dassource[0]
5357 .getFeatureColourScheme();
5358 alignPanel.av.mergeFeaturesStyle(
5360 AlignFrame.this.setMenusForViewport();
5363 dbRefFetcher.fetchDBRefs(false);
5369 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5370 MessageManager.formatMessage(
5371 "label.fetch_retrieve_from", new Object[]
5372 { src.getDbName() })));
5378 final DbSourceProxy[] dassource = otherdb
5379 .toArray(new DbSourceProxy[0]);
5381 DbSourceProxy src = otherdb.get(0);
5382 fetchr = new JMenuItem(MessageManager
5383 .formatMessage("label.fetch_all_param", new Object[]
5384 { src.getDbSource() }));
5385 fetchr.addActionListener(new ActionListener()
5388 public void actionPerformed(ActionEvent e)
5390 new Thread(new Runnable()
5396 boolean isNucleotide = alignPanel.alignFrame
5397 .getViewport().getAlignment()
5399 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5400 alignPanel.av.getSequenceSelection(),
5401 alignPanel.alignFrame, dassource,
5402 alignPanel.alignFrame.featureSettings,
5405 .addListener(new FetchFinishedListenerI()
5408 public void finished()
5410 AlignFrame.this.setMenusForViewport();
5413 dbRefFetcher.fetchDBRefs(false);
5419 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5420 MessageManager.formatMessage(
5421 "label.fetch_retrieve_from_all_sources",
5423 { Integer.valueOf(otherdb.size())
5425 src.getDbSource(), src.getDbName() })));
5428 // and then build the rest of the individual menus
5429 ifetch = new JMenu(MessageManager.formatMessage(
5430 "label.source_from_db_source", new Object[]
5431 { src.getDbSource() }));
5433 String imname = null;
5435 for (DbSourceProxy sproxy : otherdb)
5437 String dbname = sproxy.getDbName();
5438 String sname = dbname.length() > 5
5439 ? dbname.substring(0, 5) + "..."
5441 String msname = dbname.length() > 10
5442 ? dbname.substring(0, 10) + "..."
5446 imname = MessageManager
5447 .formatMessage("label.from_msname", new Object[]
5450 fetchr = new JMenuItem(msname);
5451 final DbSourceProxy[] dassrc = { sproxy };
5452 fetchr.addActionListener(new ActionListener()
5456 public void actionPerformed(ActionEvent e)
5458 new Thread(new Runnable()
5464 boolean isNucleotide = alignPanel.alignFrame
5465 .getViewport().getAlignment()
5467 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5468 alignPanel.av.getSequenceSelection(),
5469 alignPanel.alignFrame, dassrc,
5470 alignPanel.alignFrame.featureSettings,
5473 .addListener(new FetchFinishedListenerI()
5476 public void finished()
5478 AlignFrame.this.setMenusForViewport();
5481 dbRefFetcher.fetchDBRefs(false);
5487 fetchr.setToolTipText(
5488 "<html>" + MessageManager.formatMessage(
5489 "label.fetch_retrieve_from", new Object[]
5493 if (++icomp >= mcomp || i == (otherdb.size()))
5495 ifetch.setText(MessageManager.formatMessage(
5496 "label.source_to_target", imname, sname));
5498 ifetch = new JMenu();
5506 if (comp >= mcomp || dbi >= (dbclasses.length))
5508 dfetch.setText(MessageManager.formatMessage(
5509 "label.source_to_target", mname, dbclass));
5511 dfetch = new JMenu();
5524 * Left justify the whole alignment.
5527 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5529 AlignmentI al = viewport.getAlignment();
5531 viewport.firePropertyChange("alignment", null, al);
5535 * Right justify the whole alignment.
5538 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5540 AlignmentI al = viewport.getAlignment();
5542 viewport.firePropertyChange("alignment", null, al);
5546 public void setShowSeqFeatures(boolean b)
5548 showSeqFeatures.setSelected(b);
5549 viewport.setShowSequenceFeatures(b);
5556 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5557 * awt.event.ActionEvent)
5560 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5562 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5563 alignPanel.paintAlignment(false, false);
5570 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5574 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5576 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5577 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5585 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5586 * .event.ActionEvent)
5589 protected void showGroupConservation_actionPerformed(ActionEvent e)
5591 viewport.setShowGroupConservation(showGroupConservation.getState());
5592 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5599 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5600 * .event.ActionEvent)
5603 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5605 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5606 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5613 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5614 * .event.ActionEvent)
5617 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5619 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5620 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5624 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5626 showSequenceLogo.setState(true);
5627 viewport.setShowSequenceLogo(true);
5628 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5629 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5633 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5635 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5642 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5643 * .event.ActionEvent)
5646 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5648 if (avc.makeGroupsFromSelection())
5650 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5651 alignPanel.updateAnnotation();
5652 alignPanel.paintAlignment(true,
5653 viewport.needToUpdateStructureViews());
5657 public void clearAlignmentSeqRep()
5659 // TODO refactor alignmentseqrep to controller
5660 if (viewport.getAlignment().hasSeqrep())
5662 viewport.getAlignment().setSeqrep(null);
5663 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5664 alignPanel.updateAnnotation();
5665 alignPanel.paintAlignment(true, true);
5670 protected void createGroup_actionPerformed(ActionEvent e)
5672 if (avc.createGroup())
5674 if (applyAutoAnnotationSettings.isSelected())
5676 alignPanel.updateAnnotation(true, false);
5678 alignPanel.alignmentChanged();
5683 protected void unGroup_actionPerformed(ActionEvent e)
5687 alignPanel.alignmentChanged();
5692 * make the given alignmentPanel the currently selected tab
5694 * @param alignmentPanel
5696 public void setDisplayedView(AlignmentPanel alignmentPanel)
5698 if (!viewport.getSequenceSetId()
5699 .equals(alignmentPanel.av.getSequenceSetId()))
5701 throw new Error(MessageManager.getString(
5702 "error.implementation_error_cannot_show_view_alignment_frame"));
5704 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5705 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5707 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5712 * Action on selection of menu options to Show or Hide annotations.
5715 * @param forSequences
5716 * update sequence-related annotations
5717 * @param forAlignment
5718 * update non-sequence-related annotations
5721 public void setAnnotationsVisibility(boolean visible,
5722 boolean forSequences, boolean forAlignment)
5724 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5725 .getAlignmentAnnotation();
5730 for (AlignmentAnnotation aa : anns)
5733 * don't display non-positional annotations on an alignment
5735 if (aa.annotations == null)
5739 boolean apply = (aa.sequenceRef == null && forAlignment)
5740 || (aa.sequenceRef != null && forSequences);
5743 aa.visible = visible;
5746 alignPanel.validateAnnotationDimensions(true);
5747 alignPanel.alignmentChanged();
5751 * Store selected annotation sort order for the view and repaint.
5754 protected void sortAnnotations_actionPerformed()
5756 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5758 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5759 alignPanel.paintAlignment(false, false);
5764 * @return alignment panels in this alignment frame
5766 public List<? extends AlignmentViewPanel> getAlignPanels()
5768 // alignPanels is never null
5769 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5774 * Open a new alignment window, with the cDNA associated with this (protein)
5775 * alignment, aligned as is the protein.
5777 protected void viewAsCdna_actionPerformed()
5779 // TODO no longer a menu action - refactor as required
5780 final AlignmentI alignment = getViewport().getAlignment();
5781 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5782 if (mappings == null)
5786 List<SequenceI> cdnaSeqs = new ArrayList<>();
5787 for (SequenceI aaSeq : alignment.getSequences())
5789 for (AlignedCodonFrame acf : mappings)
5791 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5795 * There is a cDNA mapping for this protein sequence - add to new
5796 * alignment. It will share the same dataset sequence as other mapped
5797 * cDNA (no new mappings need to be created).
5799 final Sequence newSeq = new Sequence(dnaSeq);
5800 newSeq.setDatasetSequence(dnaSeq);
5801 cdnaSeqs.add(newSeq);
5805 if (cdnaSeqs.size() == 0)
5807 // show a warning dialog no mapped cDNA
5810 AlignmentI cdna = new Alignment(
5811 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5812 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5813 AlignFrame.DEFAULT_HEIGHT);
5814 cdna.alignAs(alignment);
5815 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5817 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5818 AlignFrame.DEFAULT_HEIGHT);
5822 * Set visibility of dna/protein complement view (available when shown in a
5828 protected void showComplement_actionPerformed(boolean show)
5830 SplitContainerI sf = getSplitViewContainer();
5833 sf.setComplementVisible(this, show);
5838 * Generate the reverse (optionally complemented) of the selected sequences,
5839 * and add them to the alignment
5842 protected void showReverse_actionPerformed(boolean complement)
5844 AlignmentI al = null;
5847 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5848 al = dna.reverseCdna(complement);
5849 viewport.addAlignment(al, "");
5850 addHistoryItem(new EditCommand(
5851 MessageManager.getString("label.add_sequences"), Action.PASTE,
5852 al.getSequencesArray(), 0, al.getWidth(),
5853 viewport.getAlignment()));
5854 } catch (Exception ex)
5856 System.err.println(ex.getMessage());
5862 * Try to run a script in the Groovy console, having first ensured that this
5863 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5864 * be targeted at this alignment.
5867 protected void runGroovy_actionPerformed()
5869 Jalview.setCurrentAlignFrame(this);
5870 groovy.ui.Console console = Desktop.getGroovyConsole();
5871 if (console != null)
5875 console.runScript();
5876 } catch (Exception ex)
5878 System.err.println((ex.toString()));
5879 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5880 MessageManager.getString("label.couldnt_run_groovy_script"),
5881 MessageManager.getString("label.groovy_support_failed"),
5882 JvOptionPane.ERROR_MESSAGE);
5887 System.err.println("Can't run Groovy script as console not found");
5892 * Hides columns containing (or not containing) a specified feature, provided
5893 * that would not leave all columns hidden
5895 * @param featureType
5896 * @param columnsContaining
5899 public boolean hideFeatureColumns(String featureType,
5900 boolean columnsContaining)
5902 boolean notForHiding = avc.markColumnsContainingFeatures(
5903 columnsContaining, false, false, featureType);
5906 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5907 false, featureType))
5909 getViewport().hideSelectedColumns();
5917 protected void selectHighlightedColumns_actionPerformed(
5918 ActionEvent actionEvent)
5920 // include key modifier check in case user selects from menu
5921 avc.markHighlightedColumns(
5922 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5923 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5924 | ActionEvent.CTRL_MASK)) != 0);
5928 protected void copyHighlightedColumns_actionPerformed(
5929 ActionEvent actionEvent)
5931 avc.copyHighlightedRegionsToClipboard();
5935 * Rebuilds the Colour menu, including any user-defined colours which have
5936 * been loaded either on startup or during the session
5938 public void buildColourMenu()
5940 colourMenu.removeAll();
5942 colourMenu.add(applyToAllGroups);
5943 colourMenu.add(textColour);
5944 colourMenu.addSeparator();
5946 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5947 viewport.getAlignment(), false);
5949 colourMenu.add(annotationColour);
5950 bg.add(annotationColour);
5951 colourMenu.addSeparator();
5952 colourMenu.add(conservationMenuItem);
5953 colourMenu.add(modifyConservation);
5954 colourMenu.add(abovePIDThreshold);
5955 colourMenu.add(modifyPID);
5957 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5958 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5962 * Open a dialog (if not already open) that allows the user to select and
5963 * calculate PCA or Tree analysis
5965 protected void openTreePcaDialog()
5967 if (alignPanel.getCalculationDialog() == null)
5969 new CalculationChooser(AlignFrame.this);
5974 protected void loadVcf_actionPerformed()
5976 JalviewFileChooser chooser = new JalviewFileChooser(
5977 Cache.getProperty("LAST_DIRECTORY"));
5978 chooser.setFileView(new JalviewFileView());
5979 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
5980 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
5981 final AlignFrame us = this;
5982 chooser.setResponseHandler(0, () -> {
5983 String choice = chooser.getSelectedFile().getPath();
5984 Cache.setProperty("LAST_DIRECTORY", choice);
5985 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
5986 new VCFLoader(choice).loadVCF(seqs, us);
5989 chooser.showOpenDialog(null);
5993 private Rectangle lastFeatureSettingsBounds = null;
5996 public void setFeatureSettingsGeometry(Rectangle bounds)
5998 lastFeatureSettingsBounds = bounds;
6002 public Rectangle getFeatureSettingsGeometry()
6004 return lastFeatureSettingsBounds;
6009 class PrintThread extends Thread
6013 public PrintThread(AlignmentPanel ap)
6018 static PageFormat pf;
6023 PrinterJob printJob = PrinterJob.getPrinterJob();
6027 printJob.setPrintable(ap, pf);
6031 printJob.setPrintable(ap);
6034 if (printJob.printDialog())
6039 } catch (Exception PrintException)
6041 PrintException.printStackTrace();