2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
63 import javax.swing.ButtonGroup;
64 import javax.swing.JCheckBoxMenuItem;
65 import javax.swing.JComponent;
66 import javax.swing.JEditorPane;
67 import javax.swing.JInternalFrame;
68 import javax.swing.JLabel;
69 import javax.swing.JLayeredPane;
70 import javax.swing.JMenu;
71 import javax.swing.JMenuItem;
72 import javax.swing.JPanel;
73 import javax.swing.JScrollPane;
74 import javax.swing.SwingUtilities;
76 import ext.vamsas.ServiceHandle;
77 import jalview.analysis.AlignmentSorter;
78 import jalview.analysis.AlignmentUtils;
79 import jalview.analysis.CrossRef;
80 import jalview.analysis.Dna;
81 import jalview.analysis.GeneticCodeI;
82 import jalview.analysis.ParseProperties;
83 import jalview.analysis.SequenceIdMatcher;
84 import jalview.api.AlignExportSettingsI;
85 import jalview.api.AlignViewControllerGuiI;
86 import jalview.api.AlignViewControllerI;
87 import jalview.api.AlignViewportI;
88 import jalview.api.AlignmentViewPanel;
89 import jalview.api.FeatureSettingsControllerI;
90 import jalview.api.FeatureSettingsModelI;
91 import jalview.api.SplitContainerI;
92 import jalview.api.ViewStyleI;
93 import jalview.api.analysis.SimilarityParamsI;
94 import jalview.bin.Cache;
95 import jalview.bin.Console;
96 import jalview.bin.Jalview;
97 import jalview.commands.CommandI;
98 import jalview.commands.EditCommand;
99 import jalview.commands.EditCommand.Action;
100 import jalview.commands.OrderCommand;
101 import jalview.commands.RemoveGapColCommand;
102 import jalview.commands.RemoveGapsCommand;
103 import jalview.commands.SlideSequencesCommand;
104 import jalview.commands.TrimRegionCommand;
105 import jalview.datamodel.AlignExportSettingsAdapter;
106 import jalview.datamodel.AlignedCodonFrame;
107 import jalview.datamodel.Alignment;
108 import jalview.datamodel.AlignmentAnnotation;
109 import jalview.datamodel.AlignmentExportData;
110 import jalview.datamodel.AlignmentI;
111 import jalview.datamodel.AlignmentOrder;
112 import jalview.datamodel.AlignmentView;
113 import jalview.datamodel.ColumnSelection;
114 import jalview.datamodel.ContactMatrixI;
115 import jalview.datamodel.HiddenColumns;
116 import jalview.datamodel.PDBEntry;
117 import jalview.datamodel.SeqCigar;
118 import jalview.datamodel.Sequence;
119 import jalview.datamodel.SequenceGroup;
120 import jalview.datamodel.SequenceI;
121 import jalview.gui.ColourMenuHelper.ColourChangeListener;
122 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
123 import jalview.io.AlignmentProperties;
124 import jalview.io.AnnotationFile;
125 import jalview.io.BackupFiles;
126 import jalview.io.BioJsHTMLOutput;
127 import jalview.io.DataSourceType;
128 import jalview.io.FileFormat;
129 import jalview.io.FileFormatI;
130 import jalview.io.FileFormats;
131 import jalview.io.FileLoader;
132 import jalview.io.FileParse;
133 import jalview.io.FormatAdapter;
134 import jalview.io.HtmlSvgOutput;
135 import jalview.io.IdentifyFile;
136 import jalview.io.JPredFile;
137 import jalview.io.JalviewFileChooser;
138 import jalview.io.JalviewFileView;
139 import jalview.io.JnetAnnotationMaker;
140 import jalview.io.NewickFile;
141 import jalview.io.ScoreMatrixFile;
142 import jalview.io.TCoffeeScoreFile;
143 import jalview.io.vcf.VCFLoader;
144 import jalview.jbgui.GAlignFrame;
145 import jalview.project.Jalview2XML;
146 import jalview.schemes.ColourSchemeI;
147 import jalview.schemes.ColourSchemes;
148 import jalview.schemes.ResidueColourScheme;
149 import jalview.schemes.TCoffeeColourScheme;
150 import jalview.util.HttpUtils;
151 import jalview.util.ImageMaker.TYPE;
152 import jalview.util.MessageManager;
153 import jalview.util.Platform;
154 import jalview.util.imagemaker.BitmapImageSizing;
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() && progressBar != null)
986 progressBar.setProgressBar(message, id);
990 public void registerHandler(final long id,
991 final IProgressIndicatorHandler handler)
993 if (progressBar != null)
994 progressBar.registerHandler(id, handler);
999 * @return true if any progress bars are still active
1002 public boolean operationInProgress()
1004 return progressBar == null ? false : progressBar.operationInProgress();
1008 * Sets the text of the status bar. Note that setting a null or empty value
1009 * will cause the status bar to be hidden, with possibly undesirable flicker
1010 * of the screen layout.
1013 public void setStatus(String text)
1015 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1019 * Added so Castor Mapping file can obtain Jalview Version
1021 public String getVersion()
1023 return Cache.getProperty("VERSION");
1026 public FeatureRenderer getFeatureRenderer()
1028 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1032 public void fetchSequence_actionPerformed()
1034 new SequenceFetcher(this);
1038 public void addFromFile_actionPerformed(ActionEvent e)
1040 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1044 public void reload_actionPerformed(ActionEvent e)
1046 if (fileName != null)
1048 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1049 // originating file's format
1050 // TODO: work out how to recover feature settings for correct view(s) when
1051 // file is reloaded.
1052 if (FileFormat.Jalview.equals(currentFileFormat))
1054 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1055 for (int i = 0; i < frames.length; i++)
1057 if (frames[i] instanceof AlignFrame && frames[i] != this
1058 && ((AlignFrame) frames[i]).fileName != null
1059 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1063 frames[i].setSelected(true);
1064 Desktop.instance.closeAssociatedWindows();
1065 } catch (java.beans.PropertyVetoException ex)
1071 Desktop.instance.closeAssociatedWindows();
1073 FileLoader loader = new FileLoader();
1074 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1075 ? DataSourceType.URL
1076 : DataSourceType.FILE;
1077 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1081 Rectangle bounds = this.getBounds();
1083 FileLoader loader = new FileLoader();
1085 AlignFrame newframe = null;
1087 if (fileObject == null)
1090 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1091 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1092 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1097 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1098 DataSourceType.FILE, currentFileFormat);
1101 newframe.setBounds(bounds);
1102 if (featureSettings != null && featureSettings.isShowing())
1104 final Rectangle fspos = featureSettings.frame.getBounds();
1105 // TODO: need a 'show feature settings' function that takes bounds -
1106 // need to refactor Desktop.addFrame
1107 newframe.featureSettings_actionPerformed(null);
1108 final FeatureSettings nfs = newframe.featureSettings;
1109 SwingUtilities.invokeLater(new Runnable()
1114 nfs.frame.setBounds(fspos);
1117 this.featureSettings.close();
1118 this.featureSettings = null;
1120 this.closeMenuItem_actionPerformed(true);
1126 public void addFromText_actionPerformed(ActionEvent e)
1129 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1133 public void addFromURL_actionPerformed(ActionEvent e)
1135 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1139 public void save_actionPerformed(ActionEvent e)
1141 if (fileName == null || (currentFileFormat == null)
1142 || HttpUtils.startsWithHttpOrHttps(fileName))
1144 saveAs_actionPerformed();
1148 saveAlignment(fileName, currentFileFormat);
1153 * Saves the alignment to a file with a name chosen by the user, if necessary
1154 * warning if a file would be overwritten
1157 public void saveAs_actionPerformed()
1159 String format = currentFileFormat == null ? null
1160 : currentFileFormat.getName();
1161 JalviewFileChooser chooser = JalviewFileChooser
1162 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1164 chooser.setFileView(new JalviewFileView());
1165 chooser.setDialogTitle(
1166 MessageManager.getString("label.save_alignment_to_file"));
1167 chooser.setToolTipText(MessageManager.getString("action.save"));
1169 int value = chooser.showSaveDialog(this);
1171 if (value != JalviewFileChooser.APPROVE_OPTION)
1175 currentFileFormat = chooser.getSelectedFormat();
1176 // todo is this (2005) test now obsolete - value is never null?
1177 while (currentFileFormat == null)
1179 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1181 .getString("label.select_file_format_before_saving"),
1182 MessageManager.getString("label.file_format_not_specified"),
1183 JvOptionPane.WARNING_MESSAGE);
1184 currentFileFormat = chooser.getSelectedFormat();
1185 value = chooser.showSaveDialog(this);
1186 if (value != JalviewFileChooser.APPROVE_OPTION)
1192 fileName = chooser.getSelectedFile().getPath();
1194 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1195 Cache.setProperty("LAST_DIRECTORY", fileName);
1196 saveAlignment(fileName, currentFileFormat);
1199 boolean lastSaveSuccessful = false;
1201 FileFormatI lastFormatSaved;
1203 String lastFilenameSaved;
1206 * Raise a dialog or status message for the last call to saveAlignment.
1208 * @return true if last call to saveAlignment(file, format) was successful.
1210 public boolean isSaveAlignmentSuccessful()
1213 if (!lastSaveSuccessful)
1215 if (!Platform.isHeadless())
1217 JvOptionPane.showInternalMessageDialog(this, MessageManager
1218 .formatMessage("label.couldnt_save_file", new Object[]
1219 { lastFilenameSaved }),
1220 MessageManager.getString("label.error_saving_file"),
1221 JvOptionPane.WARNING_MESSAGE);
1225 Console.error(MessageManager
1226 .formatMessage("label.couldnt_save_file", new Object[]
1227 { lastFilenameSaved }));
1233 setStatus(MessageManager.formatMessage(
1234 "label.successfully_saved_to_file_in_format", new Object[]
1235 { lastFilenameSaved, lastFormatSaved }));
1238 return lastSaveSuccessful;
1242 * Saves the alignment to the specified file path, in the specified format,
1243 * which may be an alignment format, or Jalview project format. If the
1244 * alignment has hidden regions, or the format is one capable of including
1245 * non-sequence data (features, annotations, groups), then the user may be
1246 * prompted to specify what to include in the output.
1251 public void saveAlignment(String file, FileFormatI format)
1253 lastSaveSuccessful = true;
1254 lastFilenameSaved = file;
1255 lastFormatSaved = format;
1257 if (FileFormat.Jalview.equals(format))
1259 String shortName = title;
1260 if (shortName.indexOf(File.separatorChar) > -1)
1262 shortName = shortName
1263 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1265 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1268 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1269 if (lastSaveSuccessful)
1271 this.getViewport().setSavedUpToDate(true);
1274 statusBar.setText(MessageManager.formatMessage(
1275 "label.successfully_saved_to_file_in_format", new Object[]
1281 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1282 Runnable cancelAction = () -> {
1283 lastSaveSuccessful = false;
1285 Runnable outputAction = () -> {
1286 // todo defer this to inside formatSequences (or later)
1287 AlignmentExportData exportData = viewport.getAlignExportData(options);
1288 String output = new FormatAdapter(alignPanel, options)
1289 .formatSequences(format, exportData.getAlignment(),
1290 exportData.getOmitHidden(),
1291 exportData.getStartEndPostions(),
1292 viewport.getAlignment().getHiddenColumns());
1295 lastSaveSuccessful = false;
1299 // create backupfiles object and get new temp filename destination
1300 boolean doBackup = BackupFiles.getEnabled();
1301 BackupFiles backupfiles = null;
1304 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1305 backupfiles = new BackupFiles(file);
1309 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1311 Console.trace("ALIGNFRAME setting PrintWriter");
1312 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1314 if (backupfiles != null)
1316 Console.trace("ALIGNFRAME about to write to temp file "
1317 + backupfiles.getTempFilePath());
1321 Console.trace("ALIGNFRAME about to close file");
1323 Console.trace("ALIGNFRAME closed file");
1324 AlignFrame.this.setTitle(file);
1325 statusBar.setText(MessageManager.formatMessage(
1326 "label.successfully_saved_to_file_in_format", new Object[]
1327 { fileName, format.getName() }));
1328 lastSaveSuccessful = true;
1329 } catch (IOException e)
1331 lastSaveSuccessful = false;
1333 "ALIGNFRAME Something happened writing the temp file");
1334 Console.error(e.getMessage());
1335 Console.debug(Cache.getStackTraceString(e));
1336 } catch (Exception ex)
1338 lastSaveSuccessful = false;
1340 "ALIGNFRAME Something unexpected happened writing the temp file");
1341 Console.error(ex.getMessage());
1342 Console.debug(Cache.getStackTraceString(ex));
1347 backupfiles.setWriteSuccess(lastSaveSuccessful);
1348 Console.debug("ALIGNFRAME writing temp file was "
1349 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1350 // do the backup file roll and rename the temp file to actual file
1351 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1352 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1353 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1354 + (lastSaveSuccessful ? "" : "un") + "successfully");
1357 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1358 if (lastSaveSuccessful)
1360 AlignFrame.this.getViewport().setSavedUpToDate(true);
1366 * show dialog with export options if applicable; else just do it
1368 if (AlignExportOptions.isNeeded(viewport, format))
1370 AlignExportOptions choices = new AlignExportOptions(
1371 alignPanel.getAlignViewport(), format, options);
1372 choices.setResponseAction(0, outputAction);
1373 choices.setResponseAction(1, cancelAction);
1374 choices.showDialog();
1381 } catch (Exception e)
1383 // TODO Auto-generated catch block
1384 e.printStackTrace();
1390 * Outputs the alignment to textbox in the requested format, if necessary
1391 * first prompting the user for whether to include hidden regions or
1394 * @param fileFormatName
1397 protected void outputText_actionPerformed(String fileFormatName)
1399 FileFormatI fileFormat = FileFormats.getInstance()
1400 .forName(fileFormatName);
1401 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1402 Runnable outputAction = () -> {
1403 // todo defer this to inside formatSequences (or later)
1404 AlignmentExportData exportData = viewport.getAlignExportData(options);
1405 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1406 cap.setForInput(null);
1409 FileFormatI format = fileFormat;
1410 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1411 format, exportData.getAlignment(),
1412 exportData.getOmitHidden(),
1413 exportData.getStartEndPostions(),
1414 viewport.getAlignment().getHiddenColumns()));
1415 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1416 "label.alignment_output_command", new Object[]
1417 { fileFormat.getName() }), 600, 500);
1418 } catch (OutOfMemoryError oom)
1420 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1427 * show dialog with export options if applicable; else just do it
1429 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1431 AlignExportOptions choices = new AlignExportOptions(
1432 alignPanel.getAlignViewport(), fileFormat, options);
1433 choices.setResponseAction(0, outputAction);
1434 choices.showDialog();
1441 } catch (Exception e)
1443 e.printStackTrace();
1455 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1457 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1458 htmlSVG.exportHTML(null);
1462 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1464 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1465 bjs.exportHTML(null);
1468 public void createImageMap(File file, String image)
1470 alignPanel.makePNGImageMap(file, image);
1474 * Creates a PNG image of the alignment and writes it to the given file. If
1475 * the file is null, the user is prompted to choose a file.
1480 public void createPNG(File f)
1482 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1485 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1487 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1491 * Creates an EPS image of the alignment and writes it to the given file. If
1492 * the file is null, the user is prompted to choose a file.
1497 public void createEPS(File f)
1502 public void createEPS(File f, String renderer)
1504 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1508 * Creates an SVG image of the alignment and writes it to the given file. If
1509 * the file is null, the user is prompted to choose a file.
1514 public void createSVG(File f)
1519 public void createSVG(File f, String renderer)
1521 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1525 public void pageSetup_actionPerformed(ActionEvent e)
1527 PrinterJob printJob = PrinterJob.getPrinterJob();
1528 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1538 public void printMenuItem_actionPerformed(ActionEvent e)
1540 // Putting in a thread avoids Swing painting problems
1541 PrintThread thread = new PrintThread(alignPanel);
1546 public void exportFeatures_actionPerformed(ActionEvent e)
1548 new AnnotationExporter(alignPanel).exportFeatures();
1552 public void exportAnnotations_actionPerformed(ActionEvent e)
1554 new AnnotationExporter(alignPanel).exportAnnotations();
1558 public void associatedData_actionPerformed(ActionEvent e)
1560 final JalviewFileChooser chooser = new JalviewFileChooser(
1561 Cache.getProperty("LAST_DIRECTORY"));
1562 chooser.setFileView(new JalviewFileView());
1563 String tooltip = MessageManager
1564 .getString("label.load_jalview_annotations");
1565 chooser.setDialogTitle(tooltip);
1566 chooser.setToolTipText(tooltip);
1567 chooser.setResponseHandler(0, () -> {
1568 String choice = chooser.getSelectedFile().getPath();
1569 Cache.setProperty("LAST_DIRECTORY", choice);
1570 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1573 chooser.showOpenDialog(this);
1577 * Close the current view or all views in the alignment frame. If the frame
1578 * only contains one view then the alignment will be removed from memory.
1580 * @param closeAllTabs
1583 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1585 if (alignPanels != null && alignPanels.size() < 2)
1587 closeAllTabs = true;
1592 if (alignPanels != null)
1596 if (this.isClosed())
1598 // really close all the windows - otherwise wait till
1599 // setClosed(true) is called
1600 for (int i = 0; i < alignPanels.size(); i++)
1602 AlignmentPanel ap = alignPanels.get(i);
1609 closeView(alignPanel);
1614 if (featureSettings != null && featureSettings.isOpen())
1616 featureSettings.close();
1617 featureSettings = null;
1620 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1621 * be called recursively, with the frame now in 'closed' state
1623 this.setClosed(true);
1625 } catch (Exception ex)
1627 ex.printStackTrace();
1632 * Close the specified panel and close up tabs appropriately.
1634 * @param panelToClose
1636 public void closeView(AlignmentPanel panelToClose)
1638 int index = tabbedPane.getSelectedIndex();
1639 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1640 alignPanels.remove(panelToClose);
1641 panelToClose.closePanel();
1642 panelToClose = null;
1644 tabbedPane.removeTabAt(closedindex);
1645 tabbedPane.validate();
1647 if (index > closedindex || index == tabbedPane.getTabCount())
1649 // modify currently selected tab index if necessary.
1653 this.tabSelectionChanged(index);
1659 void updateEditMenuBar()
1662 if (viewport.getHistoryList().size() > 0)
1664 undoMenuItem.setEnabled(true);
1665 CommandI command = viewport.getHistoryList().peek();
1666 undoMenuItem.setText(MessageManager
1667 .formatMessage("label.undo_command", new Object[]
1668 { command.getDescription() }));
1672 undoMenuItem.setEnabled(false);
1673 undoMenuItem.setText(MessageManager.getString("action.undo"));
1676 if (viewport.getRedoList().size() > 0)
1678 redoMenuItem.setEnabled(true);
1680 CommandI command = viewport.getRedoList().peek();
1681 redoMenuItem.setText(MessageManager
1682 .formatMessage("label.redo_command", new Object[]
1683 { command.getDescription() }));
1687 redoMenuItem.setEnabled(false);
1688 redoMenuItem.setText(MessageManager.getString("action.redo"));
1693 public void addHistoryItem(CommandI command)
1695 if (command.getSize() > 0)
1697 viewport.addToHistoryList(command);
1698 viewport.clearRedoList();
1699 updateEditMenuBar();
1700 viewport.updateHiddenColumns();
1701 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1702 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1703 // viewport.getColumnSelection()
1704 // .getHiddenColumns().size() > 0);
1710 * @return alignment objects for all views
1712 AlignmentI[] getViewAlignments()
1714 if (alignPanels != null)
1716 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1718 for (AlignmentPanel ap : alignPanels)
1720 als[i++] = ap.av.getAlignment();
1724 if (viewport != null)
1726 return new AlignmentI[] { viewport.getAlignment() };
1738 protected void undoMenuItem_actionPerformed(ActionEvent e)
1740 if (viewport.getHistoryList().isEmpty())
1744 CommandI command = viewport.getHistoryList().pop();
1745 viewport.addToRedoList(command);
1746 command.undoCommand(getViewAlignments());
1748 AlignmentViewport originalSource = getOriginatingSource(command);
1749 updateEditMenuBar();
1751 if (originalSource != null)
1753 if (originalSource != viewport)
1756 "Implementation worry: mismatch of viewport origin for undo");
1758 originalSource.updateHiddenColumns();
1759 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1761 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1762 // viewport.getColumnSelection()
1763 // .getHiddenColumns().size() > 0);
1764 originalSource.firePropertyChange("alignment", null,
1765 originalSource.getAlignment().getSequences());
1776 protected void redoMenuItem_actionPerformed(ActionEvent e)
1778 if (viewport.getRedoList().size() < 1)
1783 CommandI command = viewport.getRedoList().pop();
1784 viewport.addToHistoryList(command);
1785 command.doCommand(getViewAlignments());
1787 AlignmentViewport originalSource = getOriginatingSource(command);
1788 updateEditMenuBar();
1790 if (originalSource != null)
1793 if (originalSource != viewport)
1796 "Implementation worry: mismatch of viewport origin for redo");
1798 originalSource.updateHiddenColumns();
1799 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1801 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1802 // viewport.getColumnSelection()
1803 // .getHiddenColumns().size() > 0);
1804 originalSource.firePropertyChange("alignment", null,
1805 originalSource.getAlignment().getSequences());
1809 AlignmentViewport getOriginatingSource(CommandI command)
1811 AlignmentViewport originalSource = null;
1812 // For sequence removal and addition, we need to fire
1813 // the property change event FROM the viewport where the
1814 // original alignment was altered
1815 AlignmentI al = null;
1816 if (command instanceof EditCommand)
1818 EditCommand editCommand = (EditCommand) command;
1819 al = editCommand.getAlignment();
1820 List<Component> comps = PaintRefresher.components
1821 .get(viewport.getSequenceSetId());
1823 for (Component comp : comps)
1825 if (comp instanceof AlignmentPanel)
1827 if (al == ((AlignmentPanel) comp).av.getAlignment())
1829 originalSource = ((AlignmentPanel) comp).av;
1836 if (originalSource == null)
1838 // The original view is closed, we must validate
1839 // the current view against the closed view first
1842 PaintRefresher.validateSequences(al, viewport.getAlignment());
1845 originalSource = viewport;
1848 return originalSource;
1852 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1853 * or the sequence under cursor in keyboard mode
1858 public void moveSelectedSequences(boolean up)
1860 SequenceGroup sg = viewport.getSelectionGroup();
1864 if (viewport.cursorMode)
1866 sg = new SequenceGroup();
1867 sg.addSequence(viewport.getAlignment().getSequenceAt(
1868 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1876 if (sg.getSize() < 1)
1881 // TODO: JAL-3733 - add an event to the undo buffer for this !
1883 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1884 viewport.getHiddenRepSequences(), up);
1885 alignPanel.paintAlignment(true, false);
1888 synchronized void slideSequences(boolean right, int size)
1890 List<SequenceI> sg = new ArrayList<>();
1891 if (viewport.cursorMode)
1893 sg.add(viewport.getAlignment()
1894 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1896 else if (viewport.getSelectionGroup() != null
1897 && viewport.getSelectionGroup().getSize() != viewport
1898 .getAlignment().getHeight())
1900 sg = viewport.getSelectionGroup()
1901 .getSequences(viewport.getHiddenRepSequences());
1909 List<SequenceI> invertGroup = new ArrayList<>();
1911 for (SequenceI seq : viewport.getAlignment().getSequences())
1913 if (!sg.contains(seq))
1915 invertGroup.add(seq);
1919 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1921 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1922 for (int i = 0; i < invertGroup.size(); i++)
1924 seqs2[i] = invertGroup.get(i);
1927 SlideSequencesCommand ssc;
1930 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1931 viewport.getGapCharacter());
1935 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1936 viewport.getGapCharacter());
1939 int groupAdjustment = 0;
1940 if (ssc.getGapsInsertedBegin() && right)
1942 if (viewport.cursorMode)
1944 alignPanel.getSeqPanel().moveCursor(size, 0);
1948 groupAdjustment = size;
1951 else if (!ssc.getGapsInsertedBegin() && !right)
1953 if (viewport.cursorMode)
1955 alignPanel.getSeqPanel().moveCursor(-size, 0);
1959 groupAdjustment = -size;
1963 if (groupAdjustment != 0)
1965 viewport.getSelectionGroup().setStartRes(
1966 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1967 viewport.getSelectionGroup().setEndRes(
1968 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1972 * just extend the last slide command if compatible; but not if in
1973 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1975 boolean appendHistoryItem = false;
1976 Deque<CommandI> historyList = viewport.getHistoryList();
1977 boolean inSplitFrame = getSplitViewContainer() != null;
1978 if (!inSplitFrame && historyList != null && historyList.size() > 0
1979 && historyList.peek() instanceof SlideSequencesCommand)
1981 appendHistoryItem = ssc.appendSlideCommand(
1982 (SlideSequencesCommand) historyList.peek());
1985 if (!appendHistoryItem)
1987 addHistoryItem(ssc);
2000 protected void copy_actionPerformed()
2002 if (viewport.getSelectionGroup() == null)
2006 // TODO: preserve the ordering of displayed alignment annotation in any
2007 // internal paste (particularly sequence associated annotation)
2008 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2009 String[] omitHidden = null;
2011 if (viewport.hasHiddenColumns())
2013 omitHidden = viewport.getViewAsString(true);
2016 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2017 seqs, omitHidden, null);
2019 StringSelection ss = new StringSelection(output);
2023 jalview.gui.Desktop.internalCopy = true;
2024 // Its really worth setting the clipboard contents
2025 // to empty before setting the large StringSelection!!
2026 Toolkit.getDefaultToolkit().getSystemClipboard()
2027 .setContents(new StringSelection(""), null);
2029 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2031 } catch (OutOfMemoryError er)
2033 new OOMWarning("copying region", er);
2037 HiddenColumns hiddenColumns = null;
2038 if (viewport.hasHiddenColumns())
2040 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2041 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2043 // create new HiddenColumns object with copy of hidden regions
2044 // between startRes and endRes, offset by startRes
2045 hiddenColumns = new HiddenColumns(
2046 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2047 hiddenCutoff, hiddenOffset);
2050 Desktop.jalviewClipboard = new Object[] { seqs,
2051 viewport.getAlignment().getDataset(), hiddenColumns };
2052 setStatus(MessageManager.formatMessage(
2053 "label.copied_sequences_to_clipboard", new Object[]
2054 { Integer.valueOf(seqs.length).toString() }));
2064 protected void pasteNew_actionPerformed(ActionEvent e)
2076 protected void pasteThis_actionPerformed(ActionEvent e)
2082 * Paste contents of Jalview clipboard
2084 * @param newAlignment
2085 * true to paste to a new alignment, otherwise add to this.
2087 void paste(boolean newAlignment)
2089 boolean externalPaste = true;
2092 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2093 Transferable contents = c.getContents(this);
2095 if (contents == null)
2104 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2105 if (str.length() < 1)
2110 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2112 } catch (OutOfMemoryError er)
2114 new OOMWarning("Out of memory pasting sequences!!", er);
2118 SequenceI[] sequences;
2119 boolean annotationAdded = false;
2120 AlignmentI alignment = null;
2122 if (Desktop.jalviewClipboard != null)
2124 // The clipboard was filled from within Jalview, we must use the
2126 // And dataset from the copied alignment
2127 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2128 // be doubly sure that we create *new* sequence objects.
2129 sequences = new SequenceI[newseq.length];
2130 for (int i = 0; i < newseq.length; i++)
2132 sequences[i] = new Sequence(newseq[i]);
2134 alignment = new Alignment(sequences);
2135 externalPaste = false;
2139 // parse the clipboard as an alignment.
2140 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2142 sequences = alignment.getSequencesArray();
2146 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2152 if (Desktop.jalviewClipboard != null)
2154 // dataset is inherited
2155 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2159 // new dataset is constructed
2160 alignment.setDataset(null);
2162 alwidth = alignment.getWidth() + 1;
2166 AlignmentI pastedal = alignment; // preserve pasted alignment object
2167 // Add pasted sequences and dataset into existing alignment.
2168 alignment = viewport.getAlignment();
2169 alwidth = alignment.getWidth() + 1;
2170 // decide if we need to import sequences from an existing dataset
2171 boolean importDs = Desktop.jalviewClipboard != null
2172 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2173 // importDs==true instructs us to copy over new dataset sequences from
2174 // an existing alignment
2175 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2177 // minimum dataset set
2179 for (int i = 0; i < sequences.length; i++)
2183 newDs.addElement(null);
2185 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2187 if (importDs && ds != null)
2189 if (!newDs.contains(ds))
2191 newDs.setElementAt(ds, i);
2192 ds = new Sequence(ds);
2193 // update with new dataset sequence
2194 sequences[i].setDatasetSequence(ds);
2198 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2203 // copy and derive new dataset sequence
2204 sequences[i] = sequences[i].deriveSequence();
2205 alignment.getDataset()
2206 .addSequence(sequences[i].getDatasetSequence());
2207 // TODO: avoid creation of duplicate dataset sequences with a
2208 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2210 alignment.addSequence(sequences[i]); // merges dataset
2214 newDs.clear(); // tidy up
2216 if (alignment.getAlignmentAnnotation() != null)
2218 for (AlignmentAnnotation alan : alignment
2219 .getAlignmentAnnotation())
2221 if (alan.graphGroup > fgroup)
2223 fgroup = alan.graphGroup;
2227 if (pastedal.getAlignmentAnnotation() != null)
2229 // Add any annotation attached to alignment.
2230 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2231 for (int i = 0; i < alann.length; i++)
2233 annotationAdded = true;
2234 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2236 AlignmentAnnotation newann = new AlignmentAnnotation(
2238 if (newann.graphGroup > -1)
2240 if (newGraphGroups.size() <= newann.graphGroup
2241 || newGraphGroups.get(newann.graphGroup) == null)
2243 for (int q = newGraphGroups
2244 .size(); q <= newann.graphGroup; q++)
2246 newGraphGroups.add(q, null);
2248 newGraphGroups.set(newann.graphGroup,
2249 Integer.valueOf(++fgroup));
2251 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2255 newann.padAnnotation(alwidth);
2256 alignment.addAnnotation(newann);
2266 addHistoryItem(new EditCommand(
2267 MessageManager.getString("label.add_sequences"),
2268 Action.PASTE, sequences, 0, alignment.getWidth(),
2271 // Add any annotations attached to sequences
2272 for (int i = 0; i < sequences.length; i++)
2274 if (sequences[i].getAnnotation() != null)
2276 AlignmentAnnotation newann;
2277 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2279 annotationAdded = true;
2280 newann = sequences[i].getAnnotation()[a];
2281 newann.adjustForAlignment();
2282 newann.padAnnotation(alwidth);
2283 if (newann.graphGroup > -1)
2285 if (newann.graphGroup > -1)
2287 if (newGraphGroups.size() <= newann.graphGroup
2288 || newGraphGroups.get(newann.graphGroup) == null)
2290 for (int q = newGraphGroups
2291 .size(); q <= newann.graphGroup; q++)
2293 newGraphGroups.add(q, null);
2295 newGraphGroups.set(newann.graphGroup,
2296 Integer.valueOf(++fgroup));
2298 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2302 // annotation was duplicated earlier
2303 alignment.addAnnotation(sequences[i].getAnnotation()[a]);
2304 // take care of contact matrix too
2305 ContactMatrixI cm=sequences[i].getContactMatrixFor(sequences[i].getAnnotation()[a]);
2308 alignment.addContactListFor(sequences[i].getAnnotation()[a], cm);
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 Runnable 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)
2524 * If the cut affects all sequences, prompt for confirmation
2526 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2528 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2529 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2530 if (wholeHeight && wholeWidth)
2532 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2533 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2534 Object[] options = new Object[] {
2535 MessageManager.getString("action.ok"),
2536 MessageManager.getString("action.cancel") };
2537 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2538 MessageManager.getString("label.delete_all"),
2539 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2540 options, options[0]);
2547 } catch (Exception e)
2549 e.printStackTrace();
2561 protected void deleteGroups_actionPerformed(ActionEvent e)
2563 if (avc.deleteGroups())
2565 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2566 alignPanel.updateAnnotation();
2567 alignPanel.paintAlignment(true, true);
2578 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2580 SequenceGroup sg = new SequenceGroup(
2581 viewport.getAlignment().getSequences());
2583 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2584 viewport.setSelectionGroup(sg);
2585 viewport.isSelectionGroupChanged(true);
2586 viewport.sendSelection();
2587 // JAL-2034 - should delegate to
2588 // alignPanel to decide if overview needs
2590 alignPanel.paintAlignment(false, false);
2591 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2601 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2603 if (viewport.cursorMode)
2605 alignPanel.getSeqPanel().keyboardNo1 = null;
2606 alignPanel.getSeqPanel().keyboardNo2 = null;
2608 viewport.setSelectionGroup(null);
2609 viewport.getColumnSelection().clear();
2610 viewport.setSearchResults(null);
2611 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2612 // JAL-2034 - should delegate to
2613 // alignPanel to decide if overview needs
2615 alignPanel.paintAlignment(false, false);
2616 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2617 viewport.sendSelection();
2627 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2629 SequenceGroup sg = viewport.getSelectionGroup();
2633 selectAllSequenceMenuItem_actionPerformed(null);
2638 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2640 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2642 // JAL-2034 - should delegate to
2643 // alignPanel to decide if overview needs
2646 alignPanel.paintAlignment(true, false);
2647 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2648 viewport.sendSelection();
2652 public void invertColSel_actionPerformed(ActionEvent e)
2654 viewport.invertColumnSelection();
2655 alignPanel.paintAlignment(true, false);
2656 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2657 viewport.sendSelection();
2667 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2669 trimAlignment(true);
2679 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2681 trimAlignment(false);
2684 void trimAlignment(boolean trimLeft)
2686 ColumnSelection colSel = viewport.getColumnSelection();
2689 if (!colSel.isEmpty())
2693 column = colSel.getMin();
2697 column = colSel.getMax();
2701 if (viewport.getSelectionGroup() != null)
2703 seqs = viewport.getSelectionGroup()
2704 .getSequencesAsArray(viewport.getHiddenRepSequences());
2708 seqs = viewport.getAlignment().getSequencesArray();
2711 TrimRegionCommand trimRegion;
2714 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2715 column, viewport.getAlignment());
2716 viewport.getRanges().setStartRes(0);
2720 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2721 column, viewport.getAlignment());
2724 setStatus(MessageManager.formatMessage("label.removed_columns",
2726 { Integer.valueOf(trimRegion.getSize()).toString() }));
2728 addHistoryItem(trimRegion);
2730 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2732 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2733 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2735 viewport.getAlignment().deleteGroup(sg);
2739 viewport.firePropertyChange("alignment", null,
2740 viewport.getAlignment().getSequences());
2751 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2753 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2756 if (viewport.getSelectionGroup() != null)
2758 seqs = viewport.getSelectionGroup()
2759 .getSequencesAsArray(viewport.getHiddenRepSequences());
2760 start = viewport.getSelectionGroup().getStartRes();
2761 end = viewport.getSelectionGroup().getEndRes();
2765 seqs = viewport.getAlignment().getSequencesArray();
2768 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2769 "Remove Gapped Columns", seqs, start, end,
2770 viewport.getAlignment());
2772 addHistoryItem(removeGapCols);
2774 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2776 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2778 // This is to maintain viewport position on first residue
2779 // of first sequence
2780 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2781 ViewportRanges ranges = viewport.getRanges();
2782 int startRes = seq.findPosition(ranges.getStartRes());
2783 // ShiftList shifts;
2784 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2785 // edit.alColumnChanges=shifts.getInverse();
2786 // if (viewport.hasHiddenColumns)
2787 // viewport.getColumnSelection().compensateForEdits(shifts);
2788 ranges.setStartRes(seq.findIndex(startRes) - 1);
2789 viewport.firePropertyChange("alignment", null,
2790 viewport.getAlignment().getSequences());
2801 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2803 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2806 if (viewport.getSelectionGroup() != null)
2808 seqs = viewport.getSelectionGroup()
2809 .getSequencesAsArray(viewport.getHiddenRepSequences());
2810 start = viewport.getSelectionGroup().getStartRes();
2811 end = viewport.getSelectionGroup().getEndRes();
2815 seqs = viewport.getAlignment().getSequencesArray();
2818 // This is to maintain viewport position on first residue
2819 // of first sequence
2820 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2821 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2823 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2824 viewport.getAlignment()));
2826 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2828 viewport.firePropertyChange("alignment", null,
2829 viewport.getAlignment().getSequences());
2840 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2842 viewport.setPadGaps(padGapsMenuitem.isSelected());
2843 viewport.firePropertyChange("alignment", null,
2844 viewport.getAlignment().getSequences());
2848 * Opens a Finder dialog
2853 public void findMenuItem_actionPerformed(ActionEvent e)
2855 new Finder(alignPanel, false, null);
2859 * Create a new view of the current alignment.
2862 public void newView_actionPerformed(ActionEvent e)
2864 newView(null, true);
2868 * Creates and shows a new view of the current alignment.
2871 * title of newly created view; if null, one will be generated
2872 * @param copyAnnotation
2873 * if true then duplicate all annnotation, groups and settings
2874 * @return new alignment panel, already displayed.
2876 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2879 * Create a new AlignmentPanel (with its own, new Viewport)
2881 AlignmentPanel newap = new jalview.project.Jalview2XML()
2882 .copyAlignPanel(alignPanel);
2883 if (!copyAnnotation)
2886 * remove all groups and annotation except for the automatic stuff
2888 newap.av.getAlignment().deleteAllGroups();
2889 newap.av.getAlignment().deleteAllAnnotations(false);
2892 newap.av.setGatherViewsHere(false);
2894 if (viewport.getViewName() == null)
2896 viewport.setViewName(
2897 MessageManager.getString("label.view_name_original"));
2901 * Views share the same edits undo and redo stacks
2903 newap.av.setHistoryList(viewport.getHistoryList());
2904 newap.av.setRedoList(viewport.getRedoList());
2907 * copy any visualisation settings that are not saved in the project
2909 newap.av.setColourAppliesToAllGroups(
2910 viewport.getColourAppliesToAllGroups());
2913 * Views share the same mappings; need to deregister any new mappings
2914 * created by copyAlignPanel, and register the new reference to the shared
2917 newap.av.replaceMappings(viewport.getAlignment());
2920 * start up cDNA consensus (if applicable) now mappings are in place
2922 if (newap.av.initComplementConsensus())
2924 newap.refresh(true); // adjust layout of annotations
2927 newap.av.setViewName(getNewViewName(viewTitle));
2929 addAlignmentPanel(newap, true);
2930 newap.alignmentChanged();
2932 if (alignPanels.size() == 2)
2934 viewport.setGatherViewsHere(true);
2936 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2942 * Make a new name for the view, ensuring it is unique within the current
2943 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2944 * these now use viewId. Unique view names are still desirable for usability.)
2949 protected String getNewViewName(String viewTitle)
2951 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2952 boolean addFirstIndex = false;
2953 if (viewTitle == null || viewTitle.trim().length() == 0)
2955 viewTitle = MessageManager.getString("action.view");
2956 addFirstIndex = true;
2960 index = 1;// we count from 1 if given a specific name
2962 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2964 List<Component> comps = PaintRefresher.components
2965 .get(viewport.getSequenceSetId());
2967 List<String> existingNames = getExistingViewNames(comps);
2969 while (existingNames.contains(newViewName))
2971 newViewName = viewTitle + " " + (++index);
2977 * Returns a list of distinct view names found in the given list of
2978 * components. View names are held on the viewport of an AlignmentPanel.
2983 protected List<String> getExistingViewNames(List<Component> comps)
2985 List<String> existingNames = new ArrayList<>();
2986 for (Component comp : comps)
2988 if (comp instanceof AlignmentPanel)
2990 AlignmentPanel ap = (AlignmentPanel) comp;
2991 if (!existingNames.contains(ap.av.getViewName()))
2993 existingNames.add(ap.av.getViewName());
2997 return existingNames;
3001 * Explode tabbed views into separate windows.
3004 public void expandViews_actionPerformed(ActionEvent e)
3006 Desktop.explodeViews(this);
3010 * Gather views in separate windows back into a tabbed presentation.
3013 public void gatherViews_actionPerformed(ActionEvent e)
3015 Desktop.instance.gatherViews(this);
3025 public void font_actionPerformed(ActionEvent e)
3027 new FontChooser(alignPanel);
3037 protected void seqLimit_actionPerformed(ActionEvent e)
3039 viewport.setShowJVSuffix(seqLimits.isSelected());
3041 alignPanel.getIdPanel().getIdCanvas()
3042 .setPreferredSize(alignPanel.calculateIdWidth());
3043 alignPanel.paintAlignment(true, false);
3047 public void idRightAlign_actionPerformed(ActionEvent e)
3049 viewport.setRightAlignIds(idRightAlign.isSelected());
3050 alignPanel.paintAlignment(false, false);
3054 public void centreColumnLabels_actionPerformed(ActionEvent e)
3056 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3057 alignPanel.paintAlignment(false, false);
3063 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3066 protected void followHighlight_actionPerformed()
3069 * Set the 'follow' flag on the Viewport (and scroll to position if now
3072 final boolean state = this.followHighlightMenuItem.getState();
3073 viewport.setFollowHighlight(state);
3076 alignPanel.scrollToPosition(viewport.getSearchResults());
3087 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3089 viewport.setColourText(colourTextMenuItem.isSelected());
3090 alignPanel.paintAlignment(false, false);
3100 public void wrapMenuItem_actionPerformed(ActionEvent e)
3102 scaleAbove.setVisible(wrapMenuItem.isSelected());
3103 scaleLeft.setVisible(wrapMenuItem.isSelected());
3104 scaleRight.setVisible(wrapMenuItem.isSelected());
3105 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3106 alignPanel.updateLayout();
3110 public void showAllSeqs_actionPerformed(ActionEvent e)
3112 viewport.showAllHiddenSeqs();
3116 public void showAllColumns_actionPerformed(ActionEvent e)
3118 viewport.showAllHiddenColumns();
3119 alignPanel.paintAlignment(true, true);
3120 viewport.sendSelection();
3124 public void hideSelSequences_actionPerformed(ActionEvent e)
3126 viewport.hideAllSelectedSeqs();
3130 * called by key handler and the hide all/show all menu items
3135 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3138 boolean hide = false;
3139 SequenceGroup sg = viewport.getSelectionGroup();
3140 if (!toggleSeqs && !toggleCols)
3142 // Hide everything by the current selection - this is a hack - we do the
3143 // invert and then hide
3144 // first check that there will be visible columns after the invert.
3145 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3146 && sg.getStartRes() <= sg.getEndRes()))
3148 // now invert the sequence set, if required - empty selection implies
3149 // that no hiding is required.
3152 invertSequenceMenuItem_actionPerformed(null);
3153 sg = viewport.getSelectionGroup();
3157 viewport.expandColSelection(sg, true);
3158 // finally invert the column selection and get the new sequence
3160 invertColSel_actionPerformed(null);
3167 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3169 hideSelSequences_actionPerformed(null);
3172 else if (!(toggleCols && viewport.hasSelectedColumns()))
3174 showAllSeqs_actionPerformed(null);
3180 if (viewport.hasSelectedColumns())
3182 hideSelColumns_actionPerformed(null);
3185 viewport.setSelectionGroup(sg);
3190 showAllColumns_actionPerformed(null);
3199 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3200 * event.ActionEvent)
3203 public void hideAllButSelection_actionPerformed(ActionEvent e)
3205 toggleHiddenRegions(false, false);
3206 viewport.sendSelection();
3213 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3217 public void hideAllSelection_actionPerformed(ActionEvent e)
3219 SequenceGroup sg = viewport.getSelectionGroup();
3220 viewport.expandColSelection(sg, false);
3221 viewport.hideAllSelectedSeqs();
3222 viewport.hideSelectedColumns();
3223 alignPanel.updateLayout();
3224 alignPanel.paintAlignment(true, true);
3225 viewport.sendSelection();
3232 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3236 public void showAllhidden_actionPerformed(ActionEvent e)
3238 viewport.showAllHiddenColumns();
3239 viewport.showAllHiddenSeqs();
3240 alignPanel.paintAlignment(true, true);
3241 viewport.sendSelection();
3245 public void hideSelColumns_actionPerformed(ActionEvent e)
3247 viewport.hideSelectedColumns();
3248 alignPanel.updateLayout();
3249 alignPanel.paintAlignment(true, true);
3250 viewport.sendSelection();
3254 public void hiddenMarkers_actionPerformed(ActionEvent e)
3256 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3267 protected void scaleAbove_actionPerformed(ActionEvent e)
3269 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3270 alignPanel.updateLayout();
3271 alignPanel.paintAlignment(true, false);
3281 protected void scaleLeft_actionPerformed(ActionEvent e)
3283 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3284 alignPanel.updateLayout();
3285 alignPanel.paintAlignment(true, false);
3295 protected void scaleRight_actionPerformed(ActionEvent e)
3297 viewport.setScaleRightWrapped(scaleRight.isSelected());
3298 alignPanel.updateLayout();
3299 alignPanel.paintAlignment(true, false);
3309 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3311 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3312 alignPanel.paintAlignment(false, false);
3322 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3324 viewport.setShowText(viewTextMenuItem.isSelected());
3325 alignPanel.paintAlignment(false, false);
3335 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3337 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3338 alignPanel.paintAlignment(false, false);
3341 public FeatureSettings featureSettings;
3344 public FeatureSettingsControllerI getFeatureSettingsUI()
3346 return featureSettings;
3350 public void featureSettings_actionPerformed(ActionEvent e)
3352 showFeatureSettingsUI();
3356 public FeatureSettingsControllerI showFeatureSettingsUI()
3358 if (featureSettings != null)
3360 featureSettings.closeOldSettings();
3361 featureSettings = null;
3363 if (!showSeqFeatures.isSelected())
3365 // make sure features are actually displayed
3366 showSeqFeatures.setSelected(true);
3367 showSeqFeatures_actionPerformed(null);
3369 featureSettings = new FeatureSettings(this);
3370 return featureSettings;
3374 * Set or clear 'Show Sequence Features'
3380 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3382 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3383 alignPanel.paintAlignment(true, true);
3387 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3388 * the annotations panel as a whole.
3390 * The options to show/hide all annotations should be enabled when the panel
3391 * is shown, and disabled when the panel is hidden.
3396 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3398 final boolean setVisible = annotationPanelMenuItem.isSelected();
3399 viewport.setShowAnnotation(setVisible);
3400 this.showAllSeqAnnotations.setEnabled(setVisible);
3401 this.hideAllSeqAnnotations.setEnabled(setVisible);
3402 this.showAllAlAnnotations.setEnabled(setVisible);
3403 this.hideAllAlAnnotations.setEnabled(setVisible);
3404 alignPanel.updateLayout();
3408 public void alignmentProperties()
3411 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3414 String content = MessageManager.formatMessage("label.html_content",
3416 { contents.toString() });
3419 if (Platform.isJS())
3421 JLabel textLabel = new JLabel();
3422 textLabel.setText(content);
3423 textLabel.setBackground(Color.WHITE);
3425 pane = new JPanel(new BorderLayout());
3426 ((JPanel) pane).setOpaque(true);
3427 pane.setBackground(Color.WHITE);
3428 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3437 JEditorPane editPane = new JEditorPane("text/html", "");
3438 editPane.setEditable(false);
3439 editPane.setText(content);
3443 JInternalFrame frame = new JInternalFrame();
3445 frame.getContentPane().add(new JScrollPane(pane));
3447 Desktop.addInternalFrame(frame, MessageManager
3448 .formatMessage("label.alignment_properties", new Object[]
3449 { getTitle() }), 500, 400);
3453 * Opens an Overview panel for the alignment, unless one is open already
3458 public void overviewMenuItem_actionPerformed(ActionEvent e)
3460 boolean showHiddenRegions = Cache
3461 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3462 openOverviewPanel(showHiddenRegions);
3465 public OverviewPanel openOverviewPanel(boolean showHidden)
3467 if (alignPanel.overviewPanel != null)
3469 return alignPanel.overviewPanel;
3471 JInternalFrame frame = new JInternalFrame();
3472 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3474 frame.setContentPane(overview);
3475 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3476 frame.getHeight(), true, true);
3477 frame.setFrameIcon(null);
3479 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3480 final AlignmentPanel thePanel = this.alignPanel;
3481 frame.addInternalFrameListener(
3482 new javax.swing.event.InternalFrameAdapter()
3485 public void internalFrameClosed(
3486 javax.swing.event.InternalFrameEvent evt)
3489 thePanel.setOverviewPanel(null);
3492 if (getKeyListeners().length > 0)
3494 frame.addKeyListener(getKeyListeners()[0]);
3497 alignPanel.setOverviewPanel(overview);
3498 alignPanel.setOverviewTitle(this);
3504 public void textColour_actionPerformed()
3506 new TextColourChooser().chooseColour(alignPanel, null);
3510 * public void covariationColour_actionPerformed() {
3512 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3516 public void annotationColour_actionPerformed()
3518 new AnnotationColourChooser(viewport, alignPanel);
3522 public void annotationColumn_actionPerformed(ActionEvent e)
3524 new AnnotationColumnChooser(viewport, alignPanel);
3528 * Action on the user checking or unchecking the option to apply the selected
3529 * colour scheme to all groups. If unchecked, groups may have their own
3530 * independent colour schemes.
3535 public void applyToAllGroups_actionPerformed(boolean selected)
3537 viewport.setColourAppliesToAllGroups(selected);
3541 * Action on user selecting a colour from the colour menu
3544 * the name (not the menu item label!) of the colour scheme
3547 public void changeColour_actionPerformed(String name)
3550 * 'User Defined' opens a panel to configure or load a
3551 * user-defined colour scheme
3553 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3555 new UserDefinedColours(alignPanel);
3560 * otherwise set the chosen colour scheme (or null for 'None')
3562 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3563 viewport, viewport.getAlignment(),
3564 viewport.getHiddenRepSequences());
3569 * Actions on setting or changing the alignment colour scheme
3574 public void changeColour(ColourSchemeI cs)
3576 // TODO: pull up to controller method
3577 ColourMenuHelper.setColourSelected(colourMenu, cs);
3579 viewport.setGlobalColourScheme(cs);
3581 alignPanel.paintAlignment(true, true);
3585 * Show the PID threshold slider panel
3588 protected void modifyPID_actionPerformed()
3590 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3591 alignPanel.getViewName());
3592 SliderPanel.showPIDSlider();
3596 * Show the Conservation slider panel
3599 protected void modifyConservation_actionPerformed()
3601 SliderPanel.setConservationSlider(alignPanel,
3602 viewport.getResidueShading(), alignPanel.getViewName());
3603 SliderPanel.showConservationSlider();
3607 * Action on selecting or deselecting (Colour) By Conservation
3610 public void conservationMenuItem_actionPerformed(boolean selected)
3612 modifyConservation.setEnabled(selected);
3613 viewport.setConservationSelected(selected);
3614 viewport.getResidueShading().setConservationApplied(selected);
3616 changeColour(viewport.getGlobalColourScheme());
3619 modifyConservation_actionPerformed();
3623 SliderPanel.hideConservationSlider();
3628 * Action on selecting or deselecting (Colour) Above PID Threshold
3631 public void abovePIDThreshold_actionPerformed(boolean selected)
3633 modifyPID.setEnabled(selected);
3634 viewport.setAbovePIDThreshold(selected);
3637 viewport.getResidueShading().setThreshold(0,
3638 viewport.isIgnoreGapsConsensus());
3641 changeColour(viewport.getGlobalColourScheme());
3644 modifyPID_actionPerformed();
3648 SliderPanel.hidePIDSlider();
3659 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3661 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3662 AlignmentSorter.sortByPID(viewport.getAlignment(),
3663 viewport.getAlignment().getSequenceAt(0));
3664 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3665 viewport.getAlignment()));
3666 alignPanel.paintAlignment(true, false);
3676 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3678 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3679 AlignmentSorter.sortByID(viewport.getAlignment());
3681 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3682 alignPanel.paintAlignment(true, false);
3692 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3694 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3695 AlignmentSorter.sortByLength(viewport.getAlignment());
3696 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3697 viewport.getAlignment()));
3698 alignPanel.paintAlignment(true, false);
3708 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3710 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3711 AlignmentSorter.sortByGroup(viewport.getAlignment());
3712 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3713 viewport.getAlignment()));
3715 alignPanel.paintAlignment(true, false);
3725 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3727 new RedundancyPanel(alignPanel, this);
3737 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3739 if ((viewport.getSelectionGroup() == null)
3740 || (viewport.getSelectionGroup().getSize() < 2))
3742 JvOptionPane.showInternalMessageDialog(this,
3743 MessageManager.getString(
3744 "label.you_must_select_least_two_sequences"),
3745 MessageManager.getString("label.invalid_selection"),
3746 JvOptionPane.WARNING_MESSAGE);
3750 JInternalFrame frame = new JInternalFrame();
3751 frame.setContentPane(new PairwiseAlignPanel(viewport));
3752 Desktop.addInternalFrame(frame,
3753 MessageManager.getString("action.pairwise_alignment"), 600,
3759 public void autoCalculate_actionPerformed(ActionEvent e)
3761 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3762 if (viewport.autoCalculateConsensus)
3764 viewport.firePropertyChange("alignment", null,
3765 viewport.getAlignment().getSequences());
3770 public void sortByTreeOption_actionPerformed(ActionEvent e)
3772 viewport.sortByTree = sortByTree.isSelected();
3776 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3778 viewport.followSelection = listenToViewSelections.isSelected();
3782 * Constructs a tree panel and adds it to the desktop
3785 * tree type (NJ or AV)
3787 * name of score model used to compute the tree
3789 * parameters for the distance or similarity calculation
3791 void newTreePanel(String type, String modelName,
3792 SimilarityParamsI options)
3794 String frameTitle = "";
3797 boolean onSelection = false;
3798 if (viewport.getSelectionGroup() != null
3799 && viewport.getSelectionGroup().getSize() > 0)
3801 SequenceGroup sg = viewport.getSelectionGroup();
3803 /* Decide if the selection is a column region */
3804 for (SequenceI _s : sg.getSequences())
3806 if (_s.getLength() < sg.getEndRes())
3808 JvOptionPane.showMessageDialog(Desktop.desktop,
3809 MessageManager.getString(
3810 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3811 MessageManager.getString(
3812 "label.sequences_selection_not_aligned"),
3813 JvOptionPane.WARNING_MESSAGE);
3822 if (viewport.getAlignment().getHeight() < 2)
3828 tp = new TreePanel(alignPanel, type, modelName, options);
3829 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3831 frameTitle += " from ";
3833 if (viewport.getViewName() != null)
3835 frameTitle += viewport.getViewName() + " of ";
3838 frameTitle += this.title;
3840 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3851 public void addSortByOrderMenuItem(String title,
3852 final AlignmentOrder order)
3854 final JMenuItem item = new JMenuItem(MessageManager
3855 .formatMessage("action.by_title_param", new Object[]
3858 item.addActionListener(new java.awt.event.ActionListener()
3861 public void actionPerformed(ActionEvent e)
3863 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3865 // TODO: JBPNote - have to map order entries to curent SequenceI
3867 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3869 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3870 viewport.getAlignment()));
3872 alignPanel.paintAlignment(true, false);
3878 * Add a new sort by annotation score menu item
3881 * the menu to add the option to
3883 * the label used to retrieve scores for each sequence on the
3886 public void addSortByAnnotScoreMenuItem(JMenu sort,
3887 final String scoreLabel)
3889 final JMenuItem item = new JMenuItem(scoreLabel);
3891 item.addActionListener(new java.awt.event.ActionListener()
3894 public void actionPerformed(ActionEvent e)
3896 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3897 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3898 viewport.getAlignment());// ,viewport.getSelectionGroup());
3899 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3900 viewport.getAlignment()));
3901 alignPanel.paintAlignment(true, false);
3907 * last hash for alignment's annotation array - used to minimise cost of
3910 protected int _annotationScoreVectorHash;
3913 * search the alignment and rebuild the sort by annotation score submenu the
3914 * last alignment annotation vector hash is stored to minimize cost of
3915 * rebuilding in subsequence calls.
3919 public void buildSortByAnnotationScoresMenu()
3921 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3926 if (viewport.getAlignment().getAlignmentAnnotation()
3927 .hashCode() != _annotationScoreVectorHash)
3929 sortByAnnotScore.removeAll();
3930 // almost certainly a quicker way to do this - but we keep it simple
3931 Hashtable<String, String> scoreSorts = new Hashtable<>();
3932 AlignmentAnnotation aann[];
3933 for (SequenceI sqa : viewport.getAlignment().getSequences())
3935 aann = sqa.getAnnotation();
3936 for (int i = 0; aann != null && i < aann.length; i++)
3938 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3940 scoreSorts.put(aann[i].label, aann[i].label);
3944 Enumeration<String> labels = scoreSorts.keys();
3945 while (labels.hasMoreElements())
3947 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3949 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3952 _annotationScoreVectorHash = viewport.getAlignment()
3953 .getAlignmentAnnotation().hashCode();
3958 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3959 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3960 * call. Listeners are added to remove the menu item when the treePanel is
3961 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3965 public void buildTreeSortMenu()
3967 sortByTreeMenu.removeAll();
3969 List<Component> comps = PaintRefresher.components
3970 .get(viewport.getSequenceSetId());
3971 List<TreePanel> treePanels = new ArrayList<>();
3972 for (Component comp : comps)
3974 if (comp instanceof TreePanel)
3976 treePanels.add((TreePanel) comp);
3980 if (treePanels.size() < 1)
3982 sortByTreeMenu.setVisible(false);
3986 sortByTreeMenu.setVisible(true);
3988 for (final TreePanel tp : treePanels)
3990 final JMenuItem item = new JMenuItem(tp.getTitle());
3991 item.addActionListener(new java.awt.event.ActionListener()
3994 public void actionPerformed(ActionEvent e)
3996 tp.sortByTree_actionPerformed();
3997 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4002 sortByTreeMenu.add(item);
4006 public boolean sortBy(AlignmentOrder alorder, String undoname)
4008 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4009 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4010 if (undoname != null)
4012 addHistoryItem(new OrderCommand(undoname, oldOrder,
4013 viewport.getAlignment()));
4015 alignPanel.paintAlignment(true, false);
4020 * Work out whether the whole set of sequences or just the selected set will
4021 * be submitted for multiple alignment.
4024 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4026 // Now, check we have enough sequences
4027 AlignmentView msa = null;
4029 if ((viewport.getSelectionGroup() != null)
4030 && (viewport.getSelectionGroup().getSize() > 1))
4032 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4033 // some common interface!
4035 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4036 * SequenceI[sz = seqs.getSize(false)];
4038 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4039 * seqs.getSequenceAt(i); }
4041 msa = viewport.getAlignmentView(true);
4043 else if (viewport.getSelectionGroup() != null
4044 && viewport.getSelectionGroup().getSize() == 1)
4046 int option = JvOptionPane.showConfirmDialog(this,
4047 MessageManager.getString("warn.oneseq_msainput_selection"),
4048 MessageManager.getString("label.invalid_selection"),
4049 JvOptionPane.OK_CANCEL_OPTION);
4050 if (option == JvOptionPane.OK_OPTION)
4052 msa = viewport.getAlignmentView(false);
4057 msa = viewport.getAlignmentView(false);
4063 * Decides what is submitted to a secondary structure prediction service: the
4064 * first sequence in the alignment, or in the current selection, or, if the
4065 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4066 * region or the whole alignment. (where the first sequence in the set is the
4067 * one that the prediction will be for).
4069 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4071 AlignmentView seqs = null;
4073 if ((viewport.getSelectionGroup() != null)
4074 && (viewport.getSelectionGroup().getSize() > 0))
4076 seqs = viewport.getAlignmentView(true);
4080 seqs = viewport.getAlignmentView(false);
4082 // limit sequences - JBPNote in future - could spawn multiple prediction
4084 // TODO: viewport.getAlignment().isAligned is a global state - the local
4085 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4086 if (!viewport.getAlignment().isAligned(false))
4088 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4089 // TODO: if seqs.getSequences().length>1 then should really have warned
4103 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4105 // Pick the tree file
4106 JalviewFileChooser chooser = new JalviewFileChooser(
4107 Cache.getProperty("LAST_DIRECTORY"));
4108 chooser.setFileView(new JalviewFileView());
4109 chooser.setDialogTitle(
4110 MessageManager.getString("label.select_newick_like_tree_file"));
4111 chooser.setToolTipText(
4112 MessageManager.getString("label.load_tree_file"));
4114 chooser.setResponseHandler(0, () -> {
4115 String filePath = chooser.getSelectedFile().getPath();
4116 Cache.setProperty("LAST_DIRECTORY", filePath);
4117 NewickFile fin = null;
4120 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4121 DataSourceType.FILE));
4122 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4123 } catch (Exception ex)
4125 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4126 MessageManager.getString("label.problem_reading_tree_file"),
4127 JvOptionPane.WARNING_MESSAGE);
4128 ex.printStackTrace();
4130 if (fin != null && fin.hasWarningMessage())
4132 JvOptionPane.showMessageDialog(Desktop.desktop,
4133 fin.getWarningMessage(),
4135 .getString("label.possible_problem_with_tree_file"),
4136 JvOptionPane.WARNING_MESSAGE);
4139 chooser.showOpenDialog(this);
4142 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
4144 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
4147 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
4148 int h, int x, int y)
4150 return showNewickTree(nf, treeTitle, null, w, h, x, y);
4154 * Add a treeviewer for the tree extracted from a Newick file object to the
4155 * current alignment view
4162 * Associated alignment input data (or null)
4171 * @return TreePanel handle
4173 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
4174 AlignmentView input, int w, int h, int x, int y)
4176 TreePanel tp = null;
4182 if (nf.getTree() != null)
4184 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4190 tp.setLocation(x, y);
4193 Desktop.addInternalFrame(tp, treeTitle, w, h);
4195 } catch (Exception ex)
4197 ex.printStackTrace();
4203 public void showContactMapTree(AlignmentAnnotation aa,
4207 int w = 400, h = 500;
4211 NewickFile fin = new NewickFile(
4212 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4213 String title = cm.getAnnotLabel() + " " + cm.getTreeMethod() + " tree"
4214 + aa.sequenceRef != null
4215 ? (" for " + aa.sequenceRef.getDisplayId(false))
4218 showColumnWiseTree(fin, aa, title, w, h, x, y);
4219 } catch (Throwable xx)
4221 Console.error("Unexpected exception showing tree for contact matrix",
4226 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4227 String treeTitle, int w, int h, int x, int y)
4232 if (nf.getTree() == null)
4236 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4242 tp.setLocation(x, y);
4245 Desktop.addInternalFrame(tp, title, w, h);
4247 } catch (Throwable xx)
4249 Console.error("Unexpected exception showing tree for contact matrix",
4255 private boolean buildingMenu = false;
4258 * Generates menu items and listener event actions for web service clients
4261 public void BuildWebServiceMenu()
4263 while (buildingMenu)
4267 System.err.println("Waiting for building menu to finish.");
4269 } catch (Exception e)
4273 final AlignFrame me = this;
4274 buildingMenu = true;
4275 new Thread(new Runnable()
4280 final List<JMenuItem> legacyItems = new ArrayList<>();
4283 // System.err.println("Building ws menu again "
4284 // + Thread.currentThread());
4285 // TODO: add support for context dependent disabling of services based
4287 // alignment and current selection
4288 // TODO: add additional serviceHandle parameter to specify abstract
4290 // class independently of AbstractName
4291 // TODO: add in rediscovery GUI function to restart discoverer
4292 // TODO: group services by location as well as function and/or
4294 // object broker mechanism.
4295 final Vector<JMenu> wsmenu = new Vector<>();
4296 final IProgressIndicator af = me;
4299 * do not i18n these strings - they are hard-coded in class
4300 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4301 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4303 final JMenu msawsmenu = new JMenu("Alignment");
4304 final JMenu secstrmenu = new JMenu(
4305 "Secondary Structure Prediction");
4306 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4307 final JMenu analymenu = new JMenu("Analysis");
4308 final JMenu dismenu = new JMenu("Protein Disorder");
4309 // JAL-940 - only show secondary structure prediction services from
4310 // the legacy server
4311 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4313 Discoverer.services != null && (Discoverer.services.size() > 0))
4315 // TODO: refactor to allow list of AbstractName/Handler bindings to
4317 // stored or retrieved from elsewhere
4318 // No MSAWS used any more:
4319 // Vector msaws = null; // (Vector)
4320 // Discoverer.services.get("MsaWS");
4321 Vector<ServiceHandle> secstrpr = Discoverer.services
4323 if (secstrpr != null)
4325 // Add any secondary structure prediction services
4326 for (int i = 0, j = secstrpr.size(); i < j; i++)
4328 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4329 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4330 .getServiceClient(sh);
4331 int p = secstrmenu.getItemCount();
4332 impl.attachWSMenuEntry(secstrmenu, me);
4333 int q = secstrmenu.getItemCount();
4334 for (int litm = p; litm < q; litm++)
4336 legacyItems.add(secstrmenu.getItem(litm));
4342 // Add all submenus in the order they should appear on the web
4344 wsmenu.add(msawsmenu);
4345 wsmenu.add(secstrmenu);
4346 wsmenu.add(dismenu);
4347 wsmenu.add(analymenu);
4348 // No search services yet
4349 // wsmenu.add(seqsrchmenu);
4351 javax.swing.SwingUtilities.invokeLater(new Runnable()
4358 webService.removeAll();
4359 // first, add discovered services onto the webservices menu
4360 if (wsmenu.size() > 0)
4362 for (int i = 0, j = wsmenu.size(); i < j; i++)
4364 webService.add(wsmenu.get(i));
4369 webService.add(me.webServiceNoServices);
4371 // TODO: move into separate menu builder class.
4373 // logic for 2.11.1.4 is
4374 // always look to see if there is a discover. if there isn't
4375 // we can't show any Jws2 services
4376 // if there are services available, show them - regardless of
4377 // the 'show JWS2 preference'
4378 // if the discoverer is running then say so
4379 // otherwise offer to trigger discovery if 'show JWS2' is not
4381 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4382 if (jws2servs != null)
4384 if (jws2servs.hasServices())
4386 jws2servs.attachWSMenuEntry(webService, me);
4387 for (Jws2Instance sv : jws2servs.getServices())
4389 if (sv.description.toLowerCase(Locale.ROOT)
4392 for (JMenuItem jmi : legacyItems)
4394 jmi.setVisible(false);
4400 if (jws2servs.isRunning())
4402 JMenuItem tm = new JMenuItem(
4403 "Still discovering JABA Services");
4404 tm.setEnabled(false);
4407 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4409 JMenuItem enableJws2 = new JMenuItem(
4410 "Discover Web Services");
4411 enableJws2.setToolTipText(
4412 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4413 enableJws2.setEnabled(true);
4414 enableJws2.addActionListener(new ActionListener()
4418 public void actionPerformed(ActionEvent e)
4420 // start service discoverer, but ignore preference
4421 Desktop.instance.startServiceDiscovery(false,
4425 webService.add(enableJws2);
4429 build_urlServiceMenu(me.webService);
4430 build_fetchdbmenu(webService);
4431 for (JMenu item : wsmenu)
4433 if (item.getItemCount() == 0)
4435 item.setEnabled(false);
4439 item.setEnabled(true);
4442 } catch (Exception e)
4445 "Exception during web service menu building process.",
4450 } catch (Exception e)
4453 buildingMenu = false;
4460 * construct any groupURL type service menu entries.
4464 protected void build_urlServiceMenu(JMenu webService)
4466 // TODO: remove this code when 2.7 is released
4467 // DEBUG - alignmentView
4469 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4470 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4472 * @Override public void actionPerformed(ActionEvent e) {
4473 * jalview.datamodel.AlignmentView
4474 * .testSelectionViews(af.viewport.getAlignment(),
4475 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4477 * }); webService.add(testAlView);
4479 // TODO: refactor to RestClient discoverer and merge menu entries for
4480 // rest-style services with other types of analysis/calculation service
4481 // SHmmr test client - still being implemented.
4482 // DEBUG - alignmentView
4484 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4487 client.attachWSMenuEntry(
4488 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4494 * Searches the alignment sequences for xRefs and builds the Show
4495 * Cross-References menu (formerly called Show Products), with database
4496 * sources for which cross-references are found (protein sources for a
4497 * nucleotide alignment and vice versa)
4499 * @return true if Show Cross-references menu should be enabled
4501 public boolean canShowProducts()
4503 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4504 AlignmentI dataset = viewport.getAlignment().getDataset();
4506 showProducts.removeAll();
4507 final boolean dna = viewport.getAlignment().isNucleotide();
4509 if (seqs == null || seqs.length == 0)
4511 // nothing to see here.
4515 boolean showp = false;
4518 List<String> ptypes = new CrossRef(seqs, dataset)
4519 .findXrefSourcesForSequences(dna);
4521 for (final String source : ptypes)
4524 final AlignFrame af = this;
4525 JMenuItem xtype = new JMenuItem(source);
4526 xtype.addActionListener(new ActionListener()
4529 public void actionPerformed(ActionEvent e)
4531 showProductsFor(af.viewport.getSequenceSelection(), dna,
4535 showProducts.add(xtype);
4537 showProducts.setVisible(showp);
4538 showProducts.setEnabled(showp);
4539 } catch (Exception e)
4542 "canShowProducts threw an exception - please report to help@jalview.org",
4550 * Finds and displays cross-references for the selected sequences (protein
4551 * products for nucleotide sequences, dna coding sequences for peptides).
4554 * the sequences to show cross-references for
4556 * true if from a nucleotide alignment (so showing proteins)
4558 * the database to show cross-references for
4560 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4561 final String source)
4563 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4568 * Construct and display a new frame containing the translation of this
4569 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4572 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4574 AlignmentI al = null;
4577 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4579 al = dna.translateCdna(codeTable);
4580 } catch (Exception ex)
4582 Console.error("Exception during translation. Please report this !",
4584 final String msg = MessageManager.getString(
4585 "label.error_when_translating_sequences_submit_bug_report");
4586 final String errorTitle = MessageManager
4587 .getString("label.implementation_error")
4588 + MessageManager.getString("label.translation_failed");
4589 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4590 JvOptionPane.ERROR_MESSAGE);
4593 if (al == null || al.getHeight() == 0)
4595 final String msg = MessageManager.getString(
4596 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4597 final String errorTitle = MessageManager
4598 .getString("label.translation_failed");
4599 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4600 JvOptionPane.WARNING_MESSAGE);
4604 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4605 af.setFileFormat(this.currentFileFormat);
4606 final String newTitle = MessageManager
4607 .formatMessage("label.translation_of_params", new Object[]
4608 { this.getTitle(), codeTable.getId() });
4609 af.setTitle(newTitle);
4610 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4612 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4613 viewport.openSplitFrame(af, new Alignment(seqs));
4617 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4624 * Set the file format
4628 public void setFileFormat(FileFormatI format)
4630 this.currentFileFormat = format;
4634 * Try to load a features file onto the alignment.
4637 * contents or path to retrieve file or a File object
4639 * access mode of file (see jalview.io.AlignFile)
4640 * @return true if features file was parsed correctly.
4642 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4645 return avc.parseFeaturesFile(file, sourceType,
4646 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4651 public void refreshFeatureUI(boolean enableIfNecessary)
4653 // note - currently this is only still here rather than in the controller
4654 // because of the featureSettings hard reference that is yet to be
4656 if (enableIfNecessary)
4658 viewport.setShowSequenceFeatures(true);
4659 showSeqFeatures.setSelected(true);
4665 public void dragEnter(DropTargetDragEvent evt)
4670 public void dragExit(DropTargetEvent evt)
4675 public void dragOver(DropTargetDragEvent evt)
4680 public void dropActionChanged(DropTargetDragEvent evt)
4685 public void drop(DropTargetDropEvent evt)
4687 // JAL-1552 - acceptDrop required before getTransferable call for
4688 // Java's Transferable for native dnd
4689 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4690 Transferable t = evt.getTransferable();
4692 final AlignFrame thisaf = this;
4693 final List<Object> files = new ArrayList<>();
4694 List<DataSourceType> protocols = new ArrayList<>();
4698 Desktop.transferFromDropTarget(files, protocols, evt, t);
4699 } catch (Exception e)
4701 e.printStackTrace();
4705 new Thread(new Runnable()
4712 // check to see if any of these files have names matching sequences
4715 SequenceIdMatcher idm = new SequenceIdMatcher(
4716 viewport.getAlignment().getSequencesArray());
4718 * Object[] { String,SequenceI}
4720 ArrayList<Object[]> filesmatched = new ArrayList<>();
4721 ArrayList<Object> filesnotmatched = new ArrayList<>();
4722 for (int i = 0; i < files.size(); i++)
4725 Object file = files.get(i);
4726 String fileName = file.toString();
4728 DataSourceType protocol = (file instanceof File
4729 ? DataSourceType.FILE
4730 : FormatAdapter.checkProtocol(fileName));
4731 if (protocol == DataSourceType.FILE)
4734 if (file instanceof File)
4737 Platform.cacheFileData(fl);
4741 fl = new File(fileName);
4743 pdbfn = fl.getName();
4745 else if (protocol == DataSourceType.URL)
4747 URL url = new URL(fileName);
4748 pdbfn = url.getFile();
4750 if (pdbfn.length() > 0)
4752 // attempt to find a match in the alignment
4753 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4754 int l = 0, c = pdbfn.indexOf(".");
4755 while (mtch == null && c != -1)
4760 } while ((c = pdbfn.indexOf(".", l)) > l);
4763 pdbfn = pdbfn.substring(0, l);
4765 mtch = idm.findAllIdMatches(pdbfn);
4772 type = new IdentifyFile().identify(file, protocol);
4773 } catch (Exception ex)
4777 if (type != null && type.isStructureFile())
4779 filesmatched.add(new Object[] { file, protocol, mtch });
4783 // File wasn't named like one of the sequences or wasn't a PDB
4785 filesnotmatched.add(file);
4789 if (filesmatched.size() > 0)
4791 boolean autoAssociate = Cache
4792 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4795 String msg = MessageManager.formatMessage(
4796 "label.automatically_associate_structure_files_with_sequences_same_name",
4798 { Integer.valueOf(filesmatched.size())
4800 String ttl = MessageManager.getString(
4801 "label.automatically_associate_structure_files_by_name");
4802 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4803 ttl, JvOptionPane.YES_NO_OPTION);
4804 autoAssociate = choice == JvOptionPane.YES_OPTION;
4808 for (Object[] fm : filesmatched)
4810 // try and associate
4811 // TODO: may want to set a standard ID naming formalism for
4812 // associating PDB files which have no IDs.
4813 for (SequenceI toassoc : (SequenceI[]) fm[2])
4815 PDBEntry pe = new AssociatePdbFileWithSeq()
4816 .associatePdbWithSeq(fm[0].toString(),
4817 (DataSourceType) fm[1], toassoc, false,
4821 System.err.println("Associated file : "
4822 + (fm[0].toString()) + " with "
4823 + toassoc.getDisplayId(true));
4827 // TODO: do we need to update overview ? only if features are
4829 alignPanel.paintAlignment(true, false);
4835 * add declined structures as sequences
4837 for (Object[] o : filesmatched)
4839 filesnotmatched.add(o[0]);
4843 if (filesnotmatched.size() > 0)
4845 if (assocfiles > 0 && (Cache.getDefault(
4846 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4847 || JvOptionPane.showConfirmDialog(thisaf,
4848 "<html>" + MessageManager.formatMessage(
4849 "label.ignore_unmatched_dropped_files_info",
4852 filesnotmatched.size())
4855 MessageManager.getString(
4856 "label.ignore_unmatched_dropped_files"),
4857 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4861 for (Object fn : filesnotmatched)
4863 loadJalviewDataFile(fn, null, null, null);
4867 } catch (Exception ex)
4869 ex.printStackTrace();
4877 * Attempt to load a "dropped" file or URL string, by testing in turn for
4879 * <li>an Annotation file</li>
4880 * <li>a JNet file</li>
4881 * <li>a features file</li>
4882 * <li>else try to interpret as an alignment file</li>
4886 * either a filename or a URL string.
4888 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4889 FileFormatI format, SequenceI assocSeq)
4891 // BH 2018 was String file
4894 if (sourceType == null)
4896 sourceType = FormatAdapter.checkProtocol(file);
4898 // if the file isn't identified, or not positively identified as some
4899 // other filetype (PFAM is default unidentified alignment file type) then
4900 // try to parse as annotation.
4901 boolean isAnnotation = (format == null
4902 || FileFormat.Pfam.equals(format))
4903 ? new AnnotationFile().annotateAlignmentView(viewport,
4909 // first see if its a T-COFFEE score file
4910 TCoffeeScoreFile tcf = null;
4913 tcf = new TCoffeeScoreFile(file, sourceType);
4916 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4920 new TCoffeeColourScheme(viewport.getAlignment()));
4921 isAnnotation = true;
4922 setStatus(MessageManager.getString(
4923 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4927 // some problem - if no warning its probable that the ID matching
4928 // process didn't work
4929 JvOptionPane.showMessageDialog(Desktop.desktop,
4930 tcf.getWarningMessage() == null
4931 ? MessageManager.getString(
4932 "label.check_file_matches_sequence_ids_alignment")
4933 : tcf.getWarningMessage(),
4934 MessageManager.getString(
4935 "label.problem_reading_tcoffee_score_file"),
4936 JvOptionPane.WARNING_MESSAGE);
4943 } catch (Exception x)
4946 "Exception when processing data source as T-COFFEE score file",
4952 // try to see if its a JNet 'concise' style annotation file *before*
4954 // try to parse it as a features file
4957 format = new IdentifyFile().identify(file, sourceType);
4959 if (FileFormat.ScoreMatrix == format)
4961 ScoreMatrixFile sm = new ScoreMatrixFile(
4962 new FileParse(file, sourceType));
4964 // todo: i18n this message
4965 setStatus(MessageManager.formatMessage(
4966 "label.successfully_loaded_matrix",
4967 sm.getMatrixName()));
4969 else if (FileFormat.Jnet.equals(format))
4971 JPredFile predictions = new JPredFile(file, sourceType);
4972 new JnetAnnotationMaker();
4973 JnetAnnotationMaker.add_annotation(predictions,
4974 viewport.getAlignment(), 0, false);
4975 viewport.getAlignment().setupJPredAlignment();
4976 isAnnotation = true;
4978 // else if (IdentifyFile.FeaturesFile.equals(format))
4979 else if (FileFormat.Features.equals(format))
4981 if (parseFeaturesFile(file, sourceType))
4983 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
4984 if (splitFrame != null)
4986 splitFrame.repaint();
4990 alignPanel.paintAlignment(true, true);
4996 new FileLoader().LoadFile(viewport, file, sourceType, format);
5003 alignPanel.adjustAnnotationHeight();
5004 viewport.updateSequenceIdColours();
5005 buildSortByAnnotationScoresMenu();
5006 alignPanel.paintAlignment(true, true);
5008 } catch (Exception ex)
5010 ex.printStackTrace();
5011 } catch (OutOfMemoryError oom)
5016 } catch (Exception x)
5021 + (sourceType != null
5022 ? (sourceType == DataSourceType.PASTE
5024 : "using " + sourceType + " from "
5028 ? "(parsing as '" + format + "' file)"
5030 oom, Desktop.desktop);
5035 * Method invoked by the ChangeListener on the tabbed pane, in other words
5036 * when a different tabbed pane is selected by the user or programmatically.
5039 public void tabSelectionChanged(int index)
5044 * update current Overview window title (if there is one)
5045 * to add view name "Original" if necessary
5047 alignPanel.setOverviewTitle(this);
5050 * switch panels and set Overview title (if there is one
5051 * because it was opened automatically)
5053 alignPanel = alignPanels.get(index);
5054 alignPanel.setOverviewTitle(this);
5056 viewport = alignPanel.av;
5057 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5058 setMenusFromViewport(viewport);
5059 if (featureSettings != null && featureSettings.isOpen()
5060 && featureSettings.fr.getViewport() != viewport)
5062 if (viewport.isShowSequenceFeatures())
5064 // refresh the featureSettings to reflect UI change
5065 showFeatureSettingsUI();
5069 // close feature settings for this view.
5070 featureSettings.close();
5077 * 'focus' any colour slider that is open to the selected viewport
5079 if (viewport.getConservationSelected())
5081 SliderPanel.setConservationSlider(alignPanel,
5082 viewport.getResidueShading(), alignPanel.getViewName());
5086 SliderPanel.hideConservationSlider();
5088 if (viewport.getAbovePIDThreshold())
5090 SliderPanel.setPIDSliderSource(alignPanel,
5091 viewport.getResidueShading(), alignPanel.getViewName());
5095 SliderPanel.hidePIDSlider();
5099 * If there is a frame linked to this one in a SplitPane, switch it to the
5100 * same view tab index. No infinite recursion of calls should happen, since
5101 * tabSelectionChanged() should not get invoked on setting the selected
5102 * index to an unchanged value. Guard against setting an invalid index
5103 * before the new view peer tab has been created.
5105 final AlignViewportI peer = viewport.getCodingComplement();
5108 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5109 .getAlignPanel().alignFrame;
5110 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5112 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5118 * On right mouse click on view tab, prompt for and set new view name.
5121 public void tabbedPane_mousePressed(MouseEvent e)
5123 if (e.isPopupTrigger())
5125 String msg = MessageManager.getString("label.enter_view_name");
5126 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5127 String reply = JvOptionPane.showInputDialog(msg, ttl);
5131 viewport.setViewName(reply);
5132 // TODO warn if reply is in getExistingViewNames()?
5133 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5138 public AlignViewport getCurrentView()
5144 * Open the dialog for regex description parsing.
5147 protected void extractScores_actionPerformed(ActionEvent e)
5149 ParseProperties pp = new jalview.analysis.ParseProperties(
5150 viewport.getAlignment());
5151 // TODO: verify regex and introduce GUI dialog for version 2.5
5152 // if (pp.getScoresFromDescription("col", "score column ",
5153 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5155 if (pp.getScoresFromDescription("description column",
5156 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5158 buildSortByAnnotationScoresMenu();
5166 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5170 protected void showDbRefs_actionPerformed(ActionEvent e)
5172 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5178 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5182 protected void showNpFeats_actionPerformed(ActionEvent e)
5184 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5188 * find the viewport amongst the tabs in this alignment frame and close that
5193 public boolean closeView(AlignViewportI av)
5197 this.closeMenuItem_actionPerformed(false);
5200 Component[] comp = tabbedPane.getComponents();
5201 for (int i = 0; comp != null && i < comp.length; i++)
5203 if (comp[i] instanceof AlignmentPanel)
5205 if (((AlignmentPanel) comp[i]).av == av)
5208 closeView((AlignmentPanel) comp[i]);
5216 protected void build_fetchdbmenu(JMenu webService)
5218 // Temporary hack - DBRef Fetcher always top level ws entry.
5219 // TODO We probably want to store a sequence database checklist in
5220 // preferences and have checkboxes.. rather than individual sources selected
5222 final JMenu rfetch = new JMenu(
5223 MessageManager.getString("action.fetch_db_references"));
5224 rfetch.setToolTipText(MessageManager.getString(
5225 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5226 webService.add(rfetch);
5228 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5229 MessageManager.getString("option.trim_retrieved_seqs"));
5230 trimrs.setToolTipText(
5231 MessageManager.getString("label.trim_retrieved_sequences"));
5233 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5234 trimrs.addActionListener(new ActionListener()
5237 public void actionPerformed(ActionEvent e)
5239 trimrs.setSelected(trimrs.isSelected());
5240 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5241 Boolean.valueOf(trimrs.isSelected()).toString());
5245 JMenuItem fetchr = new JMenuItem(
5246 MessageManager.getString("label.standard_databases"));
5247 fetchr.setToolTipText(
5248 MessageManager.getString("label.fetch_embl_uniprot"));
5249 fetchr.addActionListener(new ActionListener()
5253 public void actionPerformed(ActionEvent e)
5255 new Thread(new Runnable()
5260 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5261 .getAlignment().isNucleotide();
5262 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5263 alignPanel.av.getSequenceSelection(),
5264 alignPanel.alignFrame, null,
5265 alignPanel.alignFrame.featureSettings, isNucleotide);
5266 dbRefFetcher.addListener(new FetchFinishedListenerI()
5269 public void finished()
5272 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5273 .getFeatureSettingsModels())
5276 alignPanel.av.mergeFeaturesStyle(srcSettings);
5278 AlignFrame.this.setMenusForViewport();
5281 dbRefFetcher.fetchDBRefs(false);
5289 new Thread(new Runnable()
5294 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5295 .getSequenceFetcherSingleton();
5296 javax.swing.SwingUtilities.invokeLater(new Runnable()
5301 String[] dbclasses = sf.getNonAlignmentSources();
5302 List<DbSourceProxy> otherdb;
5303 JMenu dfetch = new JMenu();
5304 JMenu ifetch = new JMenu();
5305 JMenuItem fetchr = null;
5306 int comp = 0, icomp = 0, mcomp = 15;
5307 String mname = null;
5309 for (String dbclass : dbclasses)
5311 otherdb = sf.getSourceProxy(dbclass);
5312 // add a single entry for this class, or submenu allowing 'fetch
5314 if (otherdb == null || otherdb.size() < 1)
5320 mname = "From " + dbclass;
5322 if (otherdb.size() == 1)
5324 final DbSourceProxy[] dassource = otherdb
5325 .toArray(new DbSourceProxy[0]);
5326 DbSourceProxy src = otherdb.get(0);
5327 fetchr = new JMenuItem(src.getDbSource());
5328 fetchr.addActionListener(new ActionListener()
5332 public void actionPerformed(ActionEvent e)
5334 new Thread(new Runnable()
5340 boolean isNucleotide = alignPanel.alignFrame
5341 .getViewport().getAlignment()
5343 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5344 alignPanel.av.getSequenceSelection(),
5345 alignPanel.alignFrame, dassource,
5346 alignPanel.alignFrame.featureSettings,
5349 .addListener(new FetchFinishedListenerI()
5352 public void finished()
5354 FeatureSettingsModelI srcSettings = dassource[0]
5355 .getFeatureColourScheme();
5356 alignPanel.av.mergeFeaturesStyle(
5358 AlignFrame.this.setMenusForViewport();
5361 dbRefFetcher.fetchDBRefs(false);
5367 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5368 MessageManager.formatMessage(
5369 "label.fetch_retrieve_from", new Object[]
5370 { src.getDbName() })));
5376 final DbSourceProxy[] dassource = otherdb
5377 .toArray(new DbSourceProxy[0]);
5379 DbSourceProxy src = otherdb.get(0);
5380 fetchr = new JMenuItem(MessageManager
5381 .formatMessage("label.fetch_all_param", new Object[]
5382 { src.getDbSource() }));
5383 fetchr.addActionListener(new ActionListener()
5386 public void actionPerformed(ActionEvent e)
5388 new Thread(new Runnable()
5394 boolean isNucleotide = alignPanel.alignFrame
5395 .getViewport().getAlignment()
5397 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5398 alignPanel.av.getSequenceSelection(),
5399 alignPanel.alignFrame, dassource,
5400 alignPanel.alignFrame.featureSettings,
5403 .addListener(new FetchFinishedListenerI()
5406 public void finished()
5408 AlignFrame.this.setMenusForViewport();
5411 dbRefFetcher.fetchDBRefs(false);
5417 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5418 MessageManager.formatMessage(
5419 "label.fetch_retrieve_from_all_sources",
5421 { Integer.valueOf(otherdb.size())
5423 src.getDbSource(), src.getDbName() })));
5426 // and then build the rest of the individual menus
5427 ifetch = new JMenu(MessageManager.formatMessage(
5428 "label.source_from_db_source", new Object[]
5429 { src.getDbSource() }));
5431 String imname = null;
5433 for (DbSourceProxy sproxy : otherdb)
5435 String dbname = sproxy.getDbName();
5436 String sname = dbname.length() > 5
5437 ? dbname.substring(0, 5) + "..."
5439 String msname = dbname.length() > 10
5440 ? dbname.substring(0, 10) + "..."
5444 imname = MessageManager
5445 .formatMessage("label.from_msname", new Object[]
5448 fetchr = new JMenuItem(msname);
5449 final DbSourceProxy[] dassrc = { sproxy };
5450 fetchr.addActionListener(new ActionListener()
5454 public void actionPerformed(ActionEvent e)
5456 new Thread(new Runnable()
5462 boolean isNucleotide = alignPanel.alignFrame
5463 .getViewport().getAlignment()
5465 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5466 alignPanel.av.getSequenceSelection(),
5467 alignPanel.alignFrame, dassrc,
5468 alignPanel.alignFrame.featureSettings,
5471 .addListener(new FetchFinishedListenerI()
5474 public void finished()
5476 AlignFrame.this.setMenusForViewport();
5479 dbRefFetcher.fetchDBRefs(false);
5485 fetchr.setToolTipText(
5486 "<html>" + MessageManager.formatMessage(
5487 "label.fetch_retrieve_from", new Object[]
5491 if (++icomp >= mcomp || i == (otherdb.size()))
5493 ifetch.setText(MessageManager.formatMessage(
5494 "label.source_to_target", imname, sname));
5496 ifetch = new JMenu();
5504 if (comp >= mcomp || dbi >= (dbclasses.length))
5506 dfetch.setText(MessageManager.formatMessage(
5507 "label.source_to_target", mname, dbclass));
5509 dfetch = new JMenu();
5522 * Left justify the whole alignment.
5525 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5527 AlignmentI al = viewport.getAlignment();
5529 viewport.firePropertyChange("alignment", null, al);
5533 * Right justify the whole alignment.
5536 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5538 AlignmentI al = viewport.getAlignment();
5540 viewport.firePropertyChange("alignment", null, al);
5544 public void setShowSeqFeatures(boolean b)
5546 showSeqFeatures.setSelected(b);
5547 viewport.setShowSequenceFeatures(b);
5554 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5555 * awt.event.ActionEvent)
5558 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5560 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5561 alignPanel.paintAlignment(false, false);
5568 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5572 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5574 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5575 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5583 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5584 * .event.ActionEvent)
5587 protected void showGroupConservation_actionPerformed(ActionEvent e)
5589 viewport.setShowGroupConservation(showGroupConservation.getState());
5590 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5597 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5598 * .event.ActionEvent)
5601 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5603 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5604 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5611 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5612 * .event.ActionEvent)
5615 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5617 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5618 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5622 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5624 showSequenceLogo.setState(true);
5625 viewport.setShowSequenceLogo(true);
5626 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5627 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5631 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5633 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5640 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5641 * .event.ActionEvent)
5644 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5646 if (avc.makeGroupsFromSelection())
5648 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5649 alignPanel.updateAnnotation();
5650 alignPanel.paintAlignment(true,
5651 viewport.needToUpdateStructureViews());
5655 public void clearAlignmentSeqRep()
5657 // TODO refactor alignmentseqrep to controller
5658 if (viewport.getAlignment().hasSeqrep())
5660 viewport.getAlignment().setSeqrep(null);
5661 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5662 alignPanel.updateAnnotation();
5663 alignPanel.paintAlignment(true, true);
5668 protected void createGroup_actionPerformed(ActionEvent e)
5670 if (avc.createGroup())
5672 if (applyAutoAnnotationSettings.isSelected())
5674 alignPanel.updateAnnotation(true, false);
5676 alignPanel.alignmentChanged();
5681 protected void unGroup_actionPerformed(ActionEvent e)
5685 alignPanel.alignmentChanged();
5690 * make the given alignmentPanel the currently selected tab
5692 * @param alignmentPanel
5694 public void setDisplayedView(AlignmentPanel alignmentPanel)
5696 if (!viewport.getSequenceSetId()
5697 .equals(alignmentPanel.av.getSequenceSetId()))
5699 throw new Error(MessageManager.getString(
5700 "error.implementation_error_cannot_show_view_alignment_frame"));
5702 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5703 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5705 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5710 * Action on selection of menu options to Show or Hide annotations.
5713 * @param forSequences
5714 * update sequence-related annotations
5715 * @param forAlignment
5716 * update non-sequence-related annotations
5719 public void setAnnotationsVisibility(boolean visible,
5720 boolean forSequences, boolean forAlignment)
5722 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5723 .getAlignmentAnnotation();
5728 for (AlignmentAnnotation aa : anns)
5731 * don't display non-positional annotations on an alignment
5733 if (aa.annotations == null)
5737 boolean apply = (aa.sequenceRef == null && forAlignment)
5738 || (aa.sequenceRef != null && forSequences);
5741 aa.visible = visible;
5744 alignPanel.validateAnnotationDimensions(true);
5745 alignPanel.alignmentChanged();
5749 * Store selected annotation sort order for the view and repaint.
5752 protected void sortAnnotations_actionPerformed()
5754 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5756 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5757 alignPanel.paintAlignment(false, false);
5762 * @return alignment panels in this alignment frame
5764 public List<? extends AlignmentViewPanel> getAlignPanels()
5766 // alignPanels is never null
5767 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5772 * Open a new alignment window, with the cDNA associated with this (protein)
5773 * alignment, aligned as is the protein.
5775 protected void viewAsCdna_actionPerformed()
5777 // TODO no longer a menu action - refactor as required
5778 final AlignmentI alignment = getViewport().getAlignment();
5779 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5780 if (mappings == null)
5784 List<SequenceI> cdnaSeqs = new ArrayList<>();
5785 for (SequenceI aaSeq : alignment.getSequences())
5787 for (AlignedCodonFrame acf : mappings)
5789 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5793 * There is a cDNA mapping for this protein sequence - add to new
5794 * alignment. It will share the same dataset sequence as other mapped
5795 * cDNA (no new mappings need to be created).
5797 final Sequence newSeq = new Sequence(dnaSeq);
5798 newSeq.setDatasetSequence(dnaSeq);
5799 cdnaSeqs.add(newSeq);
5803 if (cdnaSeqs.size() == 0)
5805 // show a warning dialog no mapped cDNA
5808 AlignmentI cdna = new Alignment(
5809 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5810 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5811 AlignFrame.DEFAULT_HEIGHT);
5812 cdna.alignAs(alignment);
5813 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5815 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5816 AlignFrame.DEFAULT_HEIGHT);
5820 * Set visibility of dna/protein complement view (available when shown in a
5826 protected void showComplement_actionPerformed(boolean show)
5828 SplitContainerI sf = getSplitViewContainer();
5831 sf.setComplementVisible(this, show);
5836 * Generate the reverse (optionally complemented) of the selected sequences,
5837 * and add them to the alignment
5840 protected void showReverse_actionPerformed(boolean complement)
5842 AlignmentI al = null;
5845 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5846 al = dna.reverseCdna(complement);
5847 viewport.addAlignment(al, "");
5848 addHistoryItem(new EditCommand(
5849 MessageManager.getString("label.add_sequences"), Action.PASTE,
5850 al.getSequencesArray(), 0, al.getWidth(),
5851 viewport.getAlignment()));
5852 } catch (Exception ex)
5854 System.err.println(ex.getMessage());
5860 * Try to run a script in the Groovy console, having first ensured that this
5861 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5862 * be targeted at this alignment.
5865 protected void runGroovy_actionPerformed()
5867 Jalview.setCurrentAlignFrame(this);
5868 groovy.ui.Console console = Desktop.getGroovyConsole();
5869 if (console != null)
5873 console.runScript();
5874 } catch (Exception ex)
5876 System.err.println((ex.toString()));
5877 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5878 MessageManager.getString("label.couldnt_run_groovy_script"),
5879 MessageManager.getString("label.groovy_support_failed"),
5880 JvOptionPane.ERROR_MESSAGE);
5885 System.err.println("Can't run Groovy script as console not found");
5890 * Hides columns containing (or not containing) a specified feature, provided
5891 * that would not leave all columns hidden
5893 * @param featureType
5894 * @param columnsContaining
5897 public boolean hideFeatureColumns(String featureType,
5898 boolean columnsContaining)
5900 boolean notForHiding = avc.markColumnsContainingFeatures(
5901 columnsContaining, false, false, featureType);
5904 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5905 false, featureType))
5907 getViewport().hideSelectedColumns();
5915 protected void selectHighlightedColumns_actionPerformed(
5916 ActionEvent actionEvent)
5918 // include key modifier check in case user selects from menu
5919 avc.markHighlightedColumns(
5920 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5921 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5922 | ActionEvent.CTRL_MASK)) != 0);
5926 protected void copyHighlightedColumns_actionPerformed(
5927 ActionEvent actionEvent)
5929 avc.copyHighlightedRegionsToClipboard();
5933 * Rebuilds the Colour menu, including any user-defined colours which have
5934 * been loaded either on startup or during the session
5936 public void buildColourMenu()
5938 colourMenu.removeAll();
5940 colourMenu.add(applyToAllGroups);
5941 colourMenu.add(textColour);
5942 colourMenu.addSeparator();
5944 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5945 viewport.getAlignment(), false);
5947 colourMenu.add(annotationColour);
5948 bg.add(annotationColour);
5949 colourMenu.addSeparator();
5950 colourMenu.add(conservationMenuItem);
5951 colourMenu.add(modifyConservation);
5952 colourMenu.add(abovePIDThreshold);
5953 colourMenu.add(modifyPID);
5955 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5956 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5960 * Open a dialog (if not already open) that allows the user to select and
5961 * calculate PCA or Tree analysis
5963 protected void openTreePcaDialog()
5965 if (alignPanel.getCalculationDialog() == null)
5967 new CalculationChooser(AlignFrame.this);
5972 protected void loadVcf_actionPerformed()
5974 JalviewFileChooser chooser = new JalviewFileChooser(
5975 Cache.getProperty("LAST_DIRECTORY"));
5976 chooser.setFileView(new JalviewFileView());
5977 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
5978 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
5979 final AlignFrame us = this;
5980 chooser.setResponseHandler(0, () -> {
5981 String choice = chooser.getSelectedFile().getPath();
5982 Cache.setProperty("LAST_DIRECTORY", choice);
5983 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
5984 new VCFLoader(choice).loadVCF(seqs, us);
5986 chooser.showOpenDialog(null);
5990 private Rectangle lastFeatureSettingsBounds = null;
5993 public void setFeatureSettingsGeometry(Rectangle bounds)
5995 lastFeatureSettingsBounds = bounds;
5999 public Rectangle getFeatureSettingsGeometry()
6001 return lastFeatureSettingsBounds;
6006 class PrintThread extends Thread
6010 public PrintThread(AlignmentPanel ap)
6015 static PageFormat pf;
6020 PrinterJob printJob = PrinterJob.getPrinterJob();
6024 printJob.setPrintable(ap, pf);
6028 printJob.setPrintable(ap);
6031 if (printJob.printDialog())
6036 } catch (Exception PrintException)
6038 PrintException.printStackTrace();