2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Component;
26 import java.awt.Rectangle;
27 import java.awt.Toolkit;
28 import java.awt.datatransfer.Clipboard;
29 import java.awt.datatransfer.DataFlavor;
30 import java.awt.datatransfer.StringSelection;
31 import java.awt.datatransfer.Transferable;
32 import java.awt.dnd.DnDConstants;
33 import java.awt.dnd.DropTargetDragEvent;
34 import java.awt.dnd.DropTargetDropEvent;
35 import java.awt.dnd.DropTargetEvent;
36 import java.awt.dnd.DropTargetListener;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.event.FocusAdapter;
40 import java.awt.event.FocusEvent;
41 import java.awt.event.ItemEvent;
42 import java.awt.event.ItemListener;
43 import java.awt.event.KeyAdapter;
44 import java.awt.event.KeyEvent;
45 import java.awt.event.MouseEvent;
46 import java.awt.print.PageFormat;
47 import java.awt.print.PrinterJob;
48 import java.beans.PropertyChangeEvent;
50 import java.io.FileWriter;
51 import java.io.IOException;
52 import java.io.PrintWriter;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.Deque;
57 import java.util.Enumeration;
58 import java.util.Hashtable;
59 import java.util.List;
60 import java.util.Locale;
61 import java.util.Vector;
62 import java.util.concurrent.Callable;
64 import javax.swing.ButtonGroup;
65 import javax.swing.JCheckBoxMenuItem;
66 import javax.swing.JComponent;
67 import javax.swing.JEditorPane;
68 import javax.swing.JInternalFrame;
69 import javax.swing.JLabel;
70 import javax.swing.JLayeredPane;
71 import javax.swing.JMenu;
72 import javax.swing.JMenuItem;
73 import javax.swing.JPanel;
74 import javax.swing.JScrollPane;
75 import javax.swing.SwingUtilities;
77 import ext.vamsas.ServiceHandle;
78 import jalview.analysis.AlignmentSorter;
79 import jalview.analysis.AlignmentUtils;
80 import jalview.analysis.CrossRef;
81 import jalview.analysis.Dna;
82 import jalview.analysis.GeneticCodeI;
83 import jalview.analysis.ParseProperties;
84 import jalview.analysis.SequenceIdMatcher;
85 import jalview.api.AlignExportSettingsI;
86 import jalview.api.AlignViewControllerGuiI;
87 import jalview.api.AlignViewControllerI;
88 import jalview.api.AlignViewportI;
89 import jalview.api.AlignmentViewPanel;
90 import jalview.api.FeatureSettingsControllerI;
91 import jalview.api.FeatureSettingsModelI;
92 import jalview.api.SplitContainerI;
93 import jalview.api.ViewStyleI;
94 import jalview.api.analysis.SimilarityParamsI;
95 import jalview.bin.Cache;
96 import jalview.bin.Console;
97 import jalview.bin.Jalview;
98 import jalview.commands.CommandI;
99 import jalview.commands.EditCommand;
100 import jalview.commands.EditCommand.Action;
101 import jalview.commands.OrderCommand;
102 import jalview.commands.RemoveGapColCommand;
103 import jalview.commands.RemoveGapsCommand;
104 import jalview.commands.SlideSequencesCommand;
105 import jalview.commands.TrimRegionCommand;
106 import jalview.datamodel.AlignExportSettingsAdapter;
107 import jalview.datamodel.AlignedCodonFrame;
108 import jalview.datamodel.Alignment;
109 import jalview.datamodel.AlignmentAnnotation;
110 import jalview.datamodel.AlignmentExportData;
111 import jalview.datamodel.AlignmentI;
112 import jalview.datamodel.AlignmentOrder;
113 import jalview.datamodel.AlignmentView;
114 import jalview.datamodel.ColumnSelection;
115 import jalview.datamodel.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())
986 progressBar.setProgressBar(message, id);
990 public void registerHandler(final long id,
991 final IProgressIndicatorHandler handler)
993 progressBar.registerHandler(id, handler);
998 * @return true if any progress bars are still active
1001 public boolean operationInProgress()
1003 return progressBar.operationInProgress();
1007 * Sets the text of the status bar. Note that setting a null or empty value
1008 * will cause the status bar to be hidden, with possibly undesirable flicker
1009 * of the screen layout.
1012 public void setStatus(String text)
1014 statusBar.setText(text == null || text.isEmpty() ? " " : text);
1018 * Added so Castor Mapping file can obtain Jalview Version
1020 public String getVersion()
1022 return Cache.getProperty("VERSION");
1025 public FeatureRenderer getFeatureRenderer()
1027 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1031 public void fetchSequence_actionPerformed()
1033 new SequenceFetcher(this);
1037 public void addFromFile_actionPerformed(ActionEvent e)
1039 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1043 public void reload_actionPerformed(ActionEvent e)
1045 if (fileName != null)
1047 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1048 // originating file's format
1049 // TODO: work out how to recover feature settings for correct view(s) when
1050 // file is reloaded.
1051 if (FileFormat.Jalview.equals(currentFileFormat))
1053 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1054 for (int i = 0; i < frames.length; i++)
1056 if (frames[i] instanceof AlignFrame && frames[i] != this
1057 && ((AlignFrame) frames[i]).fileName != null
1058 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1062 frames[i].setSelected(true);
1063 Desktop.instance.closeAssociatedWindows();
1064 } catch (java.beans.PropertyVetoException ex)
1070 Desktop.instance.closeAssociatedWindows();
1072 FileLoader loader = new FileLoader();
1073 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(fileName)
1074 ? DataSourceType.URL
1075 : DataSourceType.FILE;
1076 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1080 Rectangle bounds = this.getBounds();
1082 FileLoader loader = new FileLoader();
1084 AlignFrame newframe = null;
1086 if (fileObject == null)
1089 DataSourceType protocol = HttpUtils.startsWithHttpOrHttps(
1090 fileName) ? DataSourceType.URL : DataSourceType.FILE;
1091 newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
1096 newframe = loader.LoadFileWaitTillLoaded(fileObject,
1097 DataSourceType.FILE, currentFileFormat);
1100 newframe.setBounds(bounds);
1101 if (featureSettings != null && featureSettings.isShowing())
1103 final Rectangle fspos = featureSettings.frame.getBounds();
1104 // TODO: need a 'show feature settings' function that takes bounds -
1105 // need to refactor Desktop.addFrame
1106 newframe.featureSettings_actionPerformed(null);
1107 final FeatureSettings nfs = newframe.featureSettings;
1108 SwingUtilities.invokeLater(new Runnable()
1113 nfs.frame.setBounds(fspos);
1116 this.featureSettings.close();
1117 this.featureSettings = null;
1119 this.closeMenuItem_actionPerformed(true);
1125 public void addFromText_actionPerformed(ActionEvent e)
1128 .inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
1132 public void addFromURL_actionPerformed(ActionEvent e)
1134 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1138 public void save_actionPerformed(ActionEvent e)
1140 if (fileName == null || (currentFileFormat == null)
1141 || HttpUtils.startsWithHttpOrHttps(fileName))
1143 saveAs_actionPerformed();
1147 saveAlignment(fileName, currentFileFormat);
1152 * Saves the alignment to a file with a name chosen by the user, if necessary
1153 * warning if a file would be overwritten
1156 public void saveAs_actionPerformed()
1158 String format = currentFileFormat == null ? null
1159 : currentFileFormat.getName();
1160 JalviewFileChooser chooser = JalviewFileChooser
1161 .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
1163 chooser.setFileView(new JalviewFileView());
1164 chooser.setDialogTitle(
1165 MessageManager.getString("label.save_alignment_to_file"));
1166 chooser.setToolTipText(MessageManager.getString("action.save"));
1168 int value = chooser.showSaveDialog(this);
1170 if (value != JalviewFileChooser.APPROVE_OPTION)
1174 currentFileFormat = chooser.getSelectedFormat();
1175 // todo is this (2005) test now obsolete - value is never null?
1176 while (currentFileFormat == null)
1178 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1180 .getString("label.select_file_format_before_saving"),
1181 MessageManager.getString("label.file_format_not_specified"),
1182 JvOptionPane.WARNING_MESSAGE);
1183 currentFileFormat = chooser.getSelectedFormat();
1184 value = chooser.showSaveDialog(this);
1185 if (value != JalviewFileChooser.APPROVE_OPTION)
1191 fileName = chooser.getSelectedFile().getPath();
1193 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1194 Cache.setProperty("LAST_DIRECTORY", fileName);
1195 saveAlignment(fileName, currentFileFormat);
1198 boolean lastSaveSuccessful = false;
1200 FileFormatI lastFormatSaved;
1202 String lastFilenameSaved;
1205 * Raise a dialog or status message for the last call to saveAlignment.
1207 * @return true if last call to saveAlignment(file, format) was successful.
1209 public boolean isSaveAlignmentSuccessful()
1212 if (!lastSaveSuccessful)
1214 if (!Platform.isHeadless())
1216 JvOptionPane.showInternalMessageDialog(this, MessageManager
1217 .formatMessage("label.couldnt_save_file", new Object[]
1218 { lastFilenameSaved }),
1219 MessageManager.getString("label.error_saving_file"),
1220 JvOptionPane.WARNING_MESSAGE);
1224 Console.error(MessageManager
1225 .formatMessage("label.couldnt_save_file", new Object[]
1226 { lastFilenameSaved }));
1232 setStatus(MessageManager.formatMessage(
1233 "label.successfully_saved_to_file_in_format", new Object[]
1234 { lastFilenameSaved, lastFormatSaved }));
1237 return lastSaveSuccessful;
1241 * Saves the alignment to the specified file path, in the specified format,
1242 * which may be an alignment format, or Jalview project format. If the
1243 * alignment has hidden regions, or the format is one capable of including
1244 * non-sequence data (features, annotations, groups), then the user may be
1245 * prompted to specify what to include in the output.
1250 public void saveAlignment(String file, FileFormatI format)
1252 lastSaveSuccessful = true;
1253 lastFilenameSaved = file;
1254 lastFormatSaved = format;
1256 if (FileFormat.Jalview.equals(format))
1258 String shortName = title;
1259 if (shortName.indexOf(File.separatorChar) > -1)
1261 shortName = shortName
1262 .substring(shortName.lastIndexOf(File.separatorChar) + 1);
1264 lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
1267 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1268 if (lastSaveSuccessful)
1270 this.getViewport().setSavedUpToDate(true);
1273 statusBar.setText(MessageManager.formatMessage(
1274 "label.successfully_saved_to_file_in_format", new Object[]
1280 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1281 Callable<Void> cancelAction = () -> {
1282 lastSaveSuccessful = false;
1285 Callable<Void> outputAction = () -> {
1286 // todo defer this to inside formatSequences (or later)
1287 AlignmentExportData exportData = viewport.getAlignExportData(options);
1288 String output = new FormatAdapter(alignPanel, options)
1289 .formatSequences(format, exportData.getAlignment(),
1290 exportData.getOmitHidden(),
1291 exportData.getStartEndPostions(),
1292 viewport.getAlignment().getHiddenColumns());
1295 lastSaveSuccessful = false;
1299 // create backupfiles object and get new temp filename destination
1300 boolean doBackup = BackupFiles.getEnabled();
1301 BackupFiles backupfiles = null;
1304 Console.trace("ALIGNFRAME making backupfiles object for " + file);
1305 backupfiles = new BackupFiles(file);
1309 String tempFilePath = doBackup ? backupfiles.getTempFilePath()
1311 Console.trace("ALIGNFRAME setting PrintWriter");
1312 PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
1314 if (backupfiles != null)
1316 Console.trace("ALIGNFRAME about to write to temp file "
1317 + backupfiles.getTempFilePath());
1321 Console.trace("ALIGNFRAME about to close file");
1323 Console.trace("ALIGNFRAME closed file");
1324 AlignFrame.this.setTitle(file);
1325 statusBar.setText(MessageManager.formatMessage(
1326 "label.successfully_saved_to_file_in_format", new Object[]
1327 { fileName, format.getName() }));
1328 lastSaveSuccessful = true;
1329 } catch (IOException e)
1331 lastSaveSuccessful = false;
1333 "ALIGNFRAME Something happened writing the temp file");
1334 Console.error(e.getMessage());
1335 Console.debug(Cache.getStackTraceString(e));
1336 } catch (Exception ex)
1338 lastSaveSuccessful = false;
1340 "ALIGNFRAME Something unexpected happened writing the temp file");
1341 Console.error(ex.getMessage());
1342 Console.debug(Cache.getStackTraceString(ex));
1347 backupfiles.setWriteSuccess(lastSaveSuccessful);
1348 Console.debug("ALIGNFRAME writing temp file was "
1349 + (lastSaveSuccessful ? "" : "NOT ") + "successful");
1350 // do the backup file roll and rename the temp file to actual file
1351 Console.trace("ALIGNFRAME about to rollBackupsAndRenameTempFile");
1352 lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
1353 Console.debug("ALIGNFRAME performed rollBackupsAndRenameTempFile "
1354 + (lastSaveSuccessful ? "" : "un") + "successfully");
1357 Console.debug("lastSaveSuccessful=" + lastSaveSuccessful);
1358 if (lastSaveSuccessful)
1360 AlignFrame.this.getViewport().setSavedUpToDate(true);
1367 * show dialog with export options if applicable; else just do it
1369 if (AlignExportOptions.isNeeded(viewport, format))
1371 AlignExportOptions choices = new AlignExportOptions(
1372 alignPanel.getAlignViewport(), format, options);
1373 choices.setResponseAction(0, outputAction);
1374 choices.setResponseAction(1, cancelAction);
1375 choices.showDialog();
1381 outputAction.call();
1382 } catch (Exception e)
1384 // TODO Auto-generated catch block
1385 e.printStackTrace();
1391 * Outputs the alignment to textbox in the requested format, if necessary
1392 * first prompting the user for whether to include hidden regions or
1395 * @param fileFormatName
1398 protected void outputText_actionPerformed(String fileFormatName)
1400 FileFormatI fileFormat = FileFormats.getInstance()
1401 .forName(fileFormatName);
1402 AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
1403 Callable<Void> outputAction = () -> {
1404 // todo defer this to inside formatSequences (or later)
1405 AlignmentExportData exportData = viewport.getAlignExportData(options);
1406 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1407 cap.setForInput(null);
1410 FileFormatI format = fileFormat;
1411 cap.setText(new FormatAdapter(alignPanel, options).formatSequences(
1412 format, exportData.getAlignment(),
1413 exportData.getOmitHidden(),
1414 exportData.getStartEndPostions(),
1415 viewport.getAlignment().getHiddenColumns()));
1416 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1417 "label.alignment_output_command", new Object[]
1418 { fileFormat.getName() }), 600, 500);
1419 } catch (OutOfMemoryError oom)
1421 new OOMWarning("Outputting alignment as " + fileFormat.getName(),
1429 * show dialog with export options if applicable; else just do it
1431 if (AlignExportOptions.isNeeded(viewport, fileFormat))
1433 AlignExportOptions choices = new AlignExportOptions(
1434 alignPanel.getAlignViewport(), fileFormat, options);
1435 choices.setResponseAction(0, outputAction);
1436 choices.showDialog();
1442 outputAction.call();
1443 } catch (Exception e)
1445 e.printStackTrace();
1457 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1459 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1460 htmlSVG.exportHTML(null);
1464 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1466 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1467 bjs.exportHTML(null);
1470 public void createImageMap(File file, String image)
1472 alignPanel.makePNGImageMap(file, image);
1476 * Creates a PNG image of the alignment and writes it to the given file. If
1477 * the file is null, the user is prompted to choose a file.
1482 public void createPNG(File f)
1484 createPNG(f, null, BitmapImageSizing.nullBitmapImageSizing());
1487 public void createPNG(File f, String renderer, BitmapImageSizing userBis)
1489 alignPanel.makeAlignmentImage(TYPE.PNG, f, renderer, userBis);
1493 * Creates an EPS image of the alignment and writes it to the given file. If
1494 * the file is null, the user is prompted to choose a file.
1499 public void createEPS(File f)
1504 public void createEPS(File f, String renderer)
1506 alignPanel.makeAlignmentImage(TYPE.EPS, f, renderer);
1510 * Creates an SVG image of the alignment and writes it to the given file. If
1511 * the file is null, the user is prompted to choose a file.
1516 public void createSVG(File f)
1521 public void createSVG(File f, String renderer)
1523 alignPanel.makeAlignmentImage(TYPE.SVG, f, renderer);
1527 public void pageSetup_actionPerformed(ActionEvent e)
1529 PrinterJob printJob = PrinterJob.getPrinterJob();
1530 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1540 public void printMenuItem_actionPerformed(ActionEvent e)
1542 // Putting in a thread avoids Swing painting problems
1543 PrintThread thread = new PrintThread(alignPanel);
1548 public void exportFeatures_actionPerformed(ActionEvent e)
1550 new AnnotationExporter(alignPanel).exportFeatures();
1554 public void exportAnnotations_actionPerformed(ActionEvent e)
1556 new AnnotationExporter(alignPanel).exportAnnotations();
1560 public void associatedData_actionPerformed(ActionEvent e)
1562 final JalviewFileChooser chooser = new JalviewFileChooser(
1563 Cache.getProperty("LAST_DIRECTORY"));
1564 chooser.setFileView(new JalviewFileView());
1565 String tooltip = MessageManager
1566 .getString("label.load_jalview_annotations");
1567 chooser.setDialogTitle(tooltip);
1568 chooser.setToolTipText(tooltip);
1569 chooser.setResponseHandler(0, () -> {
1570 String choice = chooser.getSelectedFile().getPath();
1571 Cache.setProperty("LAST_DIRECTORY", choice);
1572 loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
1576 chooser.showOpenDialog(this);
1580 * Close the current view or all views in the alignment frame. If the frame
1581 * only contains one view then the alignment will be removed from memory.
1583 * @param closeAllTabs
1586 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1588 if (alignPanels != null && alignPanels.size() < 2)
1590 closeAllTabs = true;
1595 if (alignPanels != null)
1599 if (this.isClosed())
1601 // really close all the windows - otherwise wait till
1602 // setClosed(true) is called
1603 for (int i = 0; i < alignPanels.size(); i++)
1605 AlignmentPanel ap = alignPanels.get(i);
1612 closeView(alignPanel);
1617 if (featureSettings != null && featureSettings.isOpen())
1619 featureSettings.close();
1620 featureSettings = null;
1623 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1624 * be called recursively, with the frame now in 'closed' state
1626 this.setClosed(true);
1628 } catch (Exception ex)
1630 ex.printStackTrace();
1635 * Close the specified panel and close up tabs appropriately.
1637 * @param panelToClose
1639 public void closeView(AlignmentPanel panelToClose)
1641 int index = tabbedPane.getSelectedIndex();
1642 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1643 alignPanels.remove(panelToClose);
1644 panelToClose.closePanel();
1645 panelToClose = null;
1647 tabbedPane.removeTabAt(closedindex);
1648 tabbedPane.validate();
1650 if (index > closedindex || index == tabbedPane.getTabCount())
1652 // modify currently selected tab index if necessary.
1656 this.tabSelectionChanged(index);
1662 void updateEditMenuBar()
1665 if (viewport.getHistoryList().size() > 0)
1667 undoMenuItem.setEnabled(true);
1668 CommandI command = viewport.getHistoryList().peek();
1669 undoMenuItem.setText(MessageManager
1670 .formatMessage("label.undo_command", new Object[]
1671 { command.getDescription() }));
1675 undoMenuItem.setEnabled(false);
1676 undoMenuItem.setText(MessageManager.getString("action.undo"));
1679 if (viewport.getRedoList().size() > 0)
1681 redoMenuItem.setEnabled(true);
1683 CommandI command = viewport.getRedoList().peek();
1684 redoMenuItem.setText(MessageManager
1685 .formatMessage("label.redo_command", new Object[]
1686 { command.getDescription() }));
1690 redoMenuItem.setEnabled(false);
1691 redoMenuItem.setText(MessageManager.getString("action.redo"));
1696 public void addHistoryItem(CommandI command)
1698 if (command.getSize() > 0)
1700 viewport.addToHistoryList(command);
1701 viewport.clearRedoList();
1702 updateEditMenuBar();
1703 viewport.updateHiddenColumns();
1704 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1705 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1706 // viewport.getColumnSelection()
1707 // .getHiddenColumns().size() > 0);
1713 * @return alignment objects for all views
1715 AlignmentI[] getViewAlignments()
1717 if (alignPanels != null)
1719 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1721 for (AlignmentPanel ap : alignPanels)
1723 als[i++] = ap.av.getAlignment();
1727 if (viewport != null)
1729 return new AlignmentI[] { viewport.getAlignment() };
1741 protected void undoMenuItem_actionPerformed(ActionEvent e)
1743 if (viewport.getHistoryList().isEmpty())
1747 CommandI command = viewport.getHistoryList().pop();
1748 viewport.addToRedoList(command);
1749 command.undoCommand(getViewAlignments());
1751 AlignmentViewport originalSource = getOriginatingSource(command);
1752 updateEditMenuBar();
1754 if (originalSource != null)
1756 if (originalSource != viewport)
1759 "Implementation worry: mismatch of viewport origin for undo");
1761 originalSource.updateHiddenColumns();
1762 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1764 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1765 // viewport.getColumnSelection()
1766 // .getHiddenColumns().size() > 0);
1767 originalSource.firePropertyChange("alignment", null,
1768 originalSource.getAlignment().getSequences());
1779 protected void redoMenuItem_actionPerformed(ActionEvent e)
1781 if (viewport.getRedoList().size() < 1)
1786 CommandI command = viewport.getRedoList().pop();
1787 viewport.addToHistoryList(command);
1788 command.doCommand(getViewAlignments());
1790 AlignmentViewport originalSource = getOriginatingSource(command);
1791 updateEditMenuBar();
1793 if (originalSource != null)
1796 if (originalSource != viewport)
1799 "Implementation worry: mismatch of viewport origin for redo");
1801 originalSource.updateHiddenColumns();
1802 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1804 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1805 // viewport.getColumnSelection()
1806 // .getHiddenColumns().size() > 0);
1807 originalSource.firePropertyChange("alignment", null,
1808 originalSource.getAlignment().getSequences());
1812 AlignmentViewport getOriginatingSource(CommandI command)
1814 AlignmentViewport originalSource = null;
1815 // For sequence removal and addition, we need to fire
1816 // the property change event FROM the viewport where the
1817 // original alignment was altered
1818 AlignmentI al = null;
1819 if (command instanceof EditCommand)
1821 EditCommand editCommand = (EditCommand) command;
1822 al = editCommand.getAlignment();
1823 List<Component> comps = PaintRefresher.components
1824 .get(viewport.getSequenceSetId());
1826 for (Component comp : comps)
1828 if (comp instanceof AlignmentPanel)
1830 if (al == ((AlignmentPanel) comp).av.getAlignment())
1832 originalSource = ((AlignmentPanel) comp).av;
1839 if (originalSource == null)
1841 // The original view is closed, we must validate
1842 // the current view against the closed view first
1845 PaintRefresher.validateSequences(al, viewport.getAlignment());
1848 originalSource = viewport;
1851 return originalSource;
1855 * Calls AlignmentI.moveSelectedSequencesByOne with current sequence selection
1856 * or the sequence under cursor in keyboard mode
1861 public void moveSelectedSequences(boolean up)
1863 SequenceGroup sg = viewport.getSelectionGroup();
1867 if (viewport.cursorMode)
1869 sg = new SequenceGroup();
1870 sg.addSequence(viewport.getAlignment().getSequenceAt(
1871 alignPanel.getSeqPanel().seqCanvas.cursorY), false);
1879 if (sg.getSize() < 1)
1884 // TODO: JAL-3733 - add an event to the undo buffer for this !
1886 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1887 viewport.getHiddenRepSequences(), up);
1888 alignPanel.paintAlignment(true, false);
1891 synchronized void slideSequences(boolean right, int size)
1893 List<SequenceI> sg = new ArrayList<>();
1894 if (viewport.cursorMode)
1896 sg.add(viewport.getAlignment()
1897 .getSequenceAt(alignPanel.getSeqPanel().seqCanvas.cursorY));
1899 else if (viewport.getSelectionGroup() != null
1900 && viewport.getSelectionGroup().getSize() != viewport
1901 .getAlignment().getHeight())
1903 sg = viewport.getSelectionGroup()
1904 .getSequences(viewport.getHiddenRepSequences());
1912 List<SequenceI> invertGroup = new ArrayList<>();
1914 for (SequenceI seq : viewport.getAlignment().getSequences())
1916 if (!sg.contains(seq))
1918 invertGroup.add(seq);
1922 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1924 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1925 for (int i = 0; i < invertGroup.size(); i++)
1927 seqs2[i] = invertGroup.get(i);
1930 SlideSequencesCommand ssc;
1933 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1, size,
1934 viewport.getGapCharacter());
1938 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2, size,
1939 viewport.getGapCharacter());
1942 int groupAdjustment = 0;
1943 if (ssc.getGapsInsertedBegin() && right)
1945 if (viewport.cursorMode)
1947 alignPanel.getSeqPanel().moveCursor(size, 0);
1951 groupAdjustment = size;
1954 else if (!ssc.getGapsInsertedBegin() && !right)
1956 if (viewport.cursorMode)
1958 alignPanel.getSeqPanel().moveCursor(-size, 0);
1962 groupAdjustment = -size;
1966 if (groupAdjustment != 0)
1968 viewport.getSelectionGroup().setStartRes(
1969 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1970 viewport.getSelectionGroup().setEndRes(
1971 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1975 * just extend the last slide command if compatible; but not if in
1976 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1978 boolean appendHistoryItem = false;
1979 Deque<CommandI> historyList = viewport.getHistoryList();
1980 boolean inSplitFrame = getSplitViewContainer() != null;
1981 if (!inSplitFrame && historyList != null && historyList.size() > 0
1982 && historyList.peek() instanceof SlideSequencesCommand)
1984 appendHistoryItem = ssc.appendSlideCommand(
1985 (SlideSequencesCommand) historyList.peek());
1988 if (!appendHistoryItem)
1990 addHistoryItem(ssc);
2003 protected void copy_actionPerformed()
2005 if (viewport.getSelectionGroup() == null)
2009 // TODO: preserve the ordering of displayed alignment annotation in any
2010 // internal paste (particularly sequence associated annotation)
2011 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
2012 String[] omitHidden = null;
2014 if (viewport.hasHiddenColumns())
2016 omitHidden = viewport.getViewAsString(true);
2019 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
2020 seqs, omitHidden, null);
2022 StringSelection ss = new StringSelection(output);
2026 jalview.gui.Desktop.internalCopy = true;
2027 // Its really worth setting the clipboard contents
2028 // to empty before setting the large StringSelection!!
2029 Toolkit.getDefaultToolkit().getSystemClipboard()
2030 .setContents(new StringSelection(""), null);
2032 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
2034 } catch (OutOfMemoryError er)
2036 new OOMWarning("copying region", er);
2040 HiddenColumns hiddenColumns = null;
2041 if (viewport.hasHiddenColumns())
2043 int hiddenOffset = viewport.getSelectionGroup().getStartRes();
2044 int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
2046 // create new HiddenColumns object with copy of hidden regions
2047 // between startRes and endRes, offset by startRes
2048 hiddenColumns = new HiddenColumns(
2049 viewport.getAlignment().getHiddenColumns(), hiddenOffset,
2050 hiddenCutoff, hiddenOffset);
2053 Desktop.jalviewClipboard = new Object[] { seqs,
2054 viewport.getAlignment().getDataset(), hiddenColumns };
2055 setStatus(MessageManager.formatMessage(
2056 "label.copied_sequences_to_clipboard", new Object[]
2057 { Integer.valueOf(seqs.length).toString() }));
2067 protected void pasteNew_actionPerformed(ActionEvent e)
2079 protected void pasteThis_actionPerformed(ActionEvent e)
2085 * Paste contents of Jalview clipboard
2087 * @param newAlignment
2088 * true to paste to a new alignment, otherwise add to this.
2090 void paste(boolean newAlignment)
2092 boolean externalPaste = true;
2095 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
2096 Transferable contents = c.getContents(this);
2098 if (contents == null)
2107 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
2108 if (str.length() < 1)
2113 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
2115 } catch (OutOfMemoryError er)
2117 new OOMWarning("Out of memory pasting sequences!!", er);
2121 SequenceI[] sequences;
2122 boolean annotationAdded = false;
2123 AlignmentI alignment = null;
2125 if (Desktop.jalviewClipboard != null)
2127 // The clipboard was filled from within Jalview, we must use the
2129 // And dataset from the copied alignment
2130 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2131 // be doubly sure that we create *new* sequence objects.
2132 sequences = new SequenceI[newseq.length];
2133 for (int i = 0; i < newseq.length; i++)
2135 sequences[i] = new Sequence(newseq[i]);
2137 alignment = new Alignment(sequences);
2138 externalPaste = false;
2142 // parse the clipboard as an alignment.
2143 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2145 sequences = alignment.getSequencesArray();
2149 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2155 if (Desktop.jalviewClipboard != null)
2157 // dataset is inherited
2158 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2162 // new dataset is constructed
2163 alignment.setDataset(null);
2165 alwidth = alignment.getWidth() + 1;
2169 AlignmentI pastedal = alignment; // preserve pasted alignment object
2170 // Add pasted sequences and dataset into existing alignment.
2171 alignment = viewport.getAlignment();
2172 alwidth = alignment.getWidth() + 1;
2173 // decide if we need to import sequences from an existing dataset
2174 boolean importDs = Desktop.jalviewClipboard != null
2175 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2176 // importDs==true instructs us to copy over new dataset sequences from
2177 // an existing alignment
2178 Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
2180 // minimum dataset set
2182 for (int i = 0; i < sequences.length; i++)
2186 newDs.addElement(null);
2188 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2190 if (importDs && ds != null)
2192 if (!newDs.contains(ds))
2194 newDs.setElementAt(ds, i);
2195 ds = new Sequence(ds);
2196 // update with new dataset sequence
2197 sequences[i].setDatasetSequence(ds);
2201 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2206 // copy and derive new dataset sequence
2207 sequences[i] = sequences[i].deriveSequence();
2208 alignment.getDataset()
2209 .addSequence(sequences[i].getDatasetSequence());
2210 // TODO: avoid creation of duplicate dataset sequences with a
2211 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2213 alignment.addSequence(sequences[i]); // merges dataset
2217 newDs.clear(); // tidy up
2219 if (alignment.getAlignmentAnnotation() != null)
2221 for (AlignmentAnnotation alan : alignment
2222 .getAlignmentAnnotation())
2224 if (alan.graphGroup > fgroup)
2226 fgroup = alan.graphGroup;
2230 if (pastedal.getAlignmentAnnotation() != null)
2232 // Add any annotation attached to alignment.
2233 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2234 for (int i = 0; i < alann.length; i++)
2236 annotationAdded = true;
2237 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2239 AlignmentAnnotation newann = new AlignmentAnnotation(
2241 if (newann.graphGroup > -1)
2243 if (newGraphGroups.size() <= newann.graphGroup
2244 || newGraphGroups.get(newann.graphGroup) == null)
2246 for (int q = newGraphGroups
2247 .size(); q <= newann.graphGroup; q++)
2249 newGraphGroups.add(q, null);
2251 newGraphGroups.set(newann.graphGroup,
2252 Integer.valueOf(++fgroup));
2254 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2258 newann.padAnnotation(alwidth);
2259 alignment.addAnnotation(newann);
2269 addHistoryItem(new EditCommand(
2270 MessageManager.getString("label.add_sequences"),
2271 Action.PASTE, sequences, 0, alignment.getWidth(),
2274 // Add any annotations attached to sequences
2275 for (int i = 0; i < sequences.length; i++)
2277 if (sequences[i].getAnnotation() != null)
2279 AlignmentAnnotation newann;
2280 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2282 annotationAdded = true;
2283 newann = sequences[i].getAnnotation()[a];
2284 newann.adjustForAlignment();
2285 newann.padAnnotation(alwidth);
2286 if (newann.graphGroup > -1)
2288 if (newann.graphGroup > -1)
2290 if (newGraphGroups.size() <= newann.graphGroup
2291 || newGraphGroups.get(newann.graphGroup) == null)
2293 for (int q = newGraphGroups
2294 .size(); q <= newann.graphGroup; q++)
2296 newGraphGroups.add(q, null);
2298 newGraphGroups.set(newann.graphGroup,
2299 Integer.valueOf(++fgroup));
2301 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2305 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
2309 alignment.setAnnotationIndex(sequences[i].getAnnotation()[a],
2317 // propagate alignment changed.
2318 viewport.getRanges().setEndSeq(alignment.getHeight() - 1);
2319 if (annotationAdded)
2321 // Duplicate sequence annotation in all views.
2322 AlignmentI[] alview = this.getViewAlignments();
2323 for (int i = 0; i < sequences.length; i++)
2325 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2330 for (int avnum = 0; avnum < alview.length; avnum++)
2332 if (alview[avnum] != alignment)
2334 // duplicate in a view other than the one with input focus
2335 int avwidth = alview[avnum].getWidth() + 1;
2336 // this relies on sann being preserved after we
2337 // modify the sequence's annotation array for each duplication
2338 for (int a = 0; a < sann.length; a++)
2340 AlignmentAnnotation newann = new AlignmentAnnotation(
2342 sequences[i].addAlignmentAnnotation(newann);
2343 newann.padAnnotation(avwidth);
2344 alview[avnum].addAnnotation(newann); // annotation was
2345 // duplicated earlier
2346 // TODO JAL-1145 graphGroups are not updated for sequence
2347 // annotation added to several views. This may cause
2349 alview[avnum].setAnnotationIndex(newann, a);
2354 buildSortByAnnotationScoresMenu();
2356 viewport.firePropertyChange("alignment", null,
2357 alignment.getSequences());
2358 if (alignPanels != null)
2360 for (AlignmentPanel ap : alignPanels)
2362 ap.validateAnnotationDimensions(false);
2367 alignPanel.validateAnnotationDimensions(false);
2373 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2375 String newtitle = new String("Copied sequences");
2377 if (Desktop.jalviewClipboard != null
2378 && Desktop.jalviewClipboard[2] != null)
2380 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2381 af.viewport.setHiddenColumns(hc);
2384 // >>>This is a fix for the moment, until a better solution is
2386 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2387 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2388 .getFeatureRenderer());
2390 // TODO: maintain provenance of an alignment, rather than just make the
2391 // title a concatenation of operations.
2394 if (title.startsWith("Copied sequences"))
2400 newtitle = newtitle.concat("- from " + title);
2405 newtitle = new String("Pasted sequences");
2408 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2413 } catch (Exception ex)
2415 ex.printStackTrace();
2416 System.out.println("Exception whilst pasting: " + ex);
2417 // could be anything being pasted in here
2423 protected void expand_newalign(ActionEvent e)
2427 AlignmentI alignment = AlignmentUtils
2428 .expandContext(getViewport().getAlignment(), -1);
2429 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2431 String newtitle = new String("Flanking alignment");
2433 if (Desktop.jalviewClipboard != null
2434 && Desktop.jalviewClipboard[2] != null)
2436 HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
2437 af.viewport.setHiddenColumns(hc);
2440 // >>>This is a fix for the moment, until a better solution is
2442 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2443 .transferSettings(alignPanel.getSeqPanel().seqCanvas
2444 .getFeatureRenderer());
2446 // TODO: maintain provenance of an alignment, rather than just make the
2447 // title a concatenation of operations.
2449 if (title.startsWith("Copied sequences"))
2455 newtitle = newtitle.concat("- from " + title);
2459 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2461 } catch (Exception ex)
2463 ex.printStackTrace();
2464 System.out.println("Exception whilst pasting: " + ex);
2465 // could be anything being pasted in here
2466 } catch (OutOfMemoryError oom)
2468 new OOMWarning("Viewing flanking region of alignment", oom);
2473 * Action Cut (delete and copy) the selected region
2476 protected void cut_actionPerformed()
2478 copy_actionPerformed();
2479 delete_actionPerformed();
2483 * Performs menu option to Delete the currently selected region
2486 protected void delete_actionPerformed()
2489 SequenceGroup sg = viewport.getSelectionGroup();
2495 Callable okAction = () -> {
2496 SequenceI[] cut = sg.getSequences()
2497 .toArray(new SequenceI[sg.getSize()]);
2499 addHistoryItem(new EditCommand(
2500 MessageManager.getString("label.cut_sequences"), Action.CUT,
2501 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2502 viewport.getAlignment()));
2504 viewport.setSelectionGroup(null);
2505 viewport.sendSelection();
2506 viewport.getAlignment().deleteGroup(sg);
2508 viewport.firePropertyChange("alignment", null,
2509 viewport.getAlignment().getSequences());
2510 if (viewport.getAlignment().getHeight() < 1)
2514 AlignFrame.this.setClosed(true);
2515 } catch (Exception ex)
2523 * If the cut affects all sequences, prompt for confirmation
2525 boolean wholeHeight = sg.getSize() == viewport.getAlignment()
2527 boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
2528 + 1) == viewport.getAlignment().getWidth()) ? true : false;
2529 if (wholeHeight && wholeWidth)
2531 JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
2532 dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
2533 Object[] options = new Object[] {
2534 MessageManager.getString("action.ok"),
2535 MessageManager.getString("action.cancel") };
2536 dialog.showDialog(MessageManager.getString("warn.delete_all"),
2537 MessageManager.getString("label.delete_all"),
2538 JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
2539 options, options[0]);
2546 } catch (Exception e)
2548 e.printStackTrace();
2560 protected void deleteGroups_actionPerformed(ActionEvent e)
2562 if (avc.deleteGroups())
2564 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2565 alignPanel.updateAnnotation();
2566 alignPanel.paintAlignment(true, true);
2577 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2579 SequenceGroup sg = new SequenceGroup(
2580 viewport.getAlignment().getSequences());
2582 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2583 viewport.setSelectionGroup(sg);
2584 viewport.isSelectionGroupChanged(true);
2585 viewport.sendSelection();
2586 // JAL-2034 - should delegate to
2587 // alignPanel to decide if overview needs
2589 alignPanel.paintAlignment(false, false);
2590 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2600 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2602 if (viewport.cursorMode)
2604 alignPanel.getSeqPanel().keyboardNo1 = null;
2605 alignPanel.getSeqPanel().keyboardNo2 = null;
2607 viewport.setSelectionGroup(null);
2608 viewport.getColumnSelection().clear();
2609 viewport.setSearchResults(null);
2610 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2611 // JAL-2034 - should delegate to
2612 // alignPanel to decide if overview needs
2614 alignPanel.paintAlignment(false, false);
2615 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2616 viewport.sendSelection();
2626 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2628 SequenceGroup sg = viewport.getSelectionGroup();
2632 selectAllSequenceMenuItem_actionPerformed(null);
2637 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2639 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2641 // JAL-2034 - should delegate to
2642 // alignPanel to decide if overview needs
2645 alignPanel.paintAlignment(true, false);
2646 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2647 viewport.sendSelection();
2651 public void invertColSel_actionPerformed(ActionEvent e)
2653 viewport.invertColumnSelection();
2654 alignPanel.paintAlignment(true, false);
2655 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2656 viewport.sendSelection();
2666 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2668 trimAlignment(true);
2678 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2680 trimAlignment(false);
2683 void trimAlignment(boolean trimLeft)
2685 ColumnSelection colSel = viewport.getColumnSelection();
2688 if (!colSel.isEmpty())
2692 column = colSel.getMin();
2696 column = colSel.getMax();
2700 if (viewport.getSelectionGroup() != null)
2702 seqs = viewport.getSelectionGroup()
2703 .getSequencesAsArray(viewport.getHiddenRepSequences());
2707 seqs = viewport.getAlignment().getSequencesArray();
2710 TrimRegionCommand trimRegion;
2713 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2714 column, viewport.getAlignment());
2715 viewport.getRanges().setStartRes(0);
2719 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2720 column, viewport.getAlignment());
2723 setStatus(MessageManager.formatMessage("label.removed_columns",
2725 { Integer.valueOf(trimRegion.getSize()).toString() }));
2727 addHistoryItem(trimRegion);
2729 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2731 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2732 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2734 viewport.getAlignment().deleteGroup(sg);
2738 viewport.firePropertyChange("alignment", null,
2739 viewport.getAlignment().getSequences());
2750 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2752 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2755 if (viewport.getSelectionGroup() != null)
2757 seqs = viewport.getSelectionGroup()
2758 .getSequencesAsArray(viewport.getHiddenRepSequences());
2759 start = viewport.getSelectionGroup().getStartRes();
2760 end = viewport.getSelectionGroup().getEndRes();
2764 seqs = viewport.getAlignment().getSequencesArray();
2767 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2768 "Remove Gapped Columns", seqs, start, end,
2769 viewport.getAlignment());
2771 addHistoryItem(removeGapCols);
2773 setStatus(MessageManager.formatMessage("label.removed_empty_columns",
2775 { Integer.valueOf(removeGapCols.getSize()).toString() }));
2777 // This is to maintain viewport position on first residue
2778 // of first sequence
2779 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2780 ViewportRanges ranges = viewport.getRanges();
2781 int startRes = seq.findPosition(ranges.getStartRes());
2782 // ShiftList shifts;
2783 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2784 // edit.alColumnChanges=shifts.getInverse();
2785 // if (viewport.hasHiddenColumns)
2786 // viewport.getColumnSelection().compensateForEdits(shifts);
2787 ranges.setStartRes(seq.findIndex(startRes) - 1);
2788 viewport.firePropertyChange("alignment", null,
2789 viewport.getAlignment().getSequences());
2800 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2802 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2805 if (viewport.getSelectionGroup() != null)
2807 seqs = viewport.getSelectionGroup()
2808 .getSequencesAsArray(viewport.getHiddenRepSequences());
2809 start = viewport.getSelectionGroup().getStartRes();
2810 end = viewport.getSelectionGroup().getEndRes();
2814 seqs = viewport.getAlignment().getSequencesArray();
2817 // This is to maintain viewport position on first residue
2818 // of first sequence
2819 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2820 int startRes = seq.findPosition(viewport.getRanges().getStartRes());
2822 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2823 viewport.getAlignment()));
2825 viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
2827 viewport.firePropertyChange("alignment", null,
2828 viewport.getAlignment().getSequences());
2839 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2841 viewport.setPadGaps(padGapsMenuitem.isSelected());
2842 viewport.firePropertyChange("alignment", null,
2843 viewport.getAlignment().getSequences());
2847 * Opens a Finder dialog
2852 public void findMenuItem_actionPerformed(ActionEvent e)
2854 new Finder(alignPanel, false, null);
2858 * Create a new view of the current alignment.
2861 public void newView_actionPerformed(ActionEvent e)
2863 newView(null, true);
2867 * Creates and shows a new view of the current alignment.
2870 * title of newly created view; if null, one will be generated
2871 * @param copyAnnotation
2872 * if true then duplicate all annnotation, groups and settings
2873 * @return new alignment panel, already displayed.
2875 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2878 * Create a new AlignmentPanel (with its own, new Viewport)
2880 AlignmentPanel newap = new jalview.project.Jalview2XML()
2881 .copyAlignPanel(alignPanel);
2882 if (!copyAnnotation)
2885 * remove all groups and annotation except for the automatic stuff
2887 newap.av.getAlignment().deleteAllGroups();
2888 newap.av.getAlignment().deleteAllAnnotations(false);
2891 newap.av.setGatherViewsHere(false);
2893 if (viewport.getViewName() == null)
2895 viewport.setViewName(
2896 MessageManager.getString("label.view_name_original"));
2900 * Views share the same edits undo and redo stacks
2902 newap.av.setHistoryList(viewport.getHistoryList());
2903 newap.av.setRedoList(viewport.getRedoList());
2906 * copy any visualisation settings that are not saved in the project
2908 newap.av.setColourAppliesToAllGroups(
2909 viewport.getColourAppliesToAllGroups());
2912 * Views share the same mappings; need to deregister any new mappings
2913 * created by copyAlignPanel, and register the new reference to the shared
2916 newap.av.replaceMappings(viewport.getAlignment());
2919 * start up cDNA consensus (if applicable) now mappings are in place
2921 if (newap.av.initComplementConsensus())
2923 newap.refresh(true); // adjust layout of annotations
2926 newap.av.setViewName(getNewViewName(viewTitle));
2928 addAlignmentPanel(newap, true);
2929 newap.alignmentChanged();
2931 if (alignPanels.size() == 2)
2933 viewport.setGatherViewsHere(true);
2935 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2941 * Make a new name for the view, ensuring it is unique within the current
2942 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2943 * these now use viewId. Unique view names are still desirable for usability.)
2948 protected String getNewViewName(String viewTitle)
2950 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2951 boolean addFirstIndex = false;
2952 if (viewTitle == null || viewTitle.trim().length() == 0)
2954 viewTitle = MessageManager.getString("action.view");
2955 addFirstIndex = true;
2959 index = 1;// we count from 1 if given a specific name
2961 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2963 List<Component> comps = PaintRefresher.components
2964 .get(viewport.getSequenceSetId());
2966 List<String> existingNames = getExistingViewNames(comps);
2968 while (existingNames.contains(newViewName))
2970 newViewName = viewTitle + " " + (++index);
2976 * Returns a list of distinct view names found in the given list of
2977 * components. View names are held on the viewport of an AlignmentPanel.
2982 protected List<String> getExistingViewNames(List<Component> comps)
2984 List<String> existingNames = new ArrayList<>();
2985 for (Component comp : comps)
2987 if (comp instanceof AlignmentPanel)
2989 AlignmentPanel ap = (AlignmentPanel) comp;
2990 if (!existingNames.contains(ap.av.getViewName()))
2992 existingNames.add(ap.av.getViewName());
2996 return existingNames;
3000 * Explode tabbed views into separate windows.
3003 public void expandViews_actionPerformed(ActionEvent e)
3005 Desktop.explodeViews(this);
3009 * Gather views in separate windows back into a tabbed presentation.
3012 public void gatherViews_actionPerformed(ActionEvent e)
3014 Desktop.instance.gatherViews(this);
3024 public void font_actionPerformed(ActionEvent e)
3026 new FontChooser(alignPanel);
3036 protected void seqLimit_actionPerformed(ActionEvent e)
3038 viewport.setShowJVSuffix(seqLimits.isSelected());
3040 alignPanel.getIdPanel().getIdCanvas()
3041 .setPreferredSize(alignPanel.calculateIdWidth());
3042 alignPanel.paintAlignment(true, false);
3046 public void idRightAlign_actionPerformed(ActionEvent e)
3048 viewport.setRightAlignIds(idRightAlign.isSelected());
3049 alignPanel.paintAlignment(false, false);
3053 public void centreColumnLabels_actionPerformed(ActionEvent e)
3055 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
3056 alignPanel.paintAlignment(false, false);
3062 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
3065 protected void followHighlight_actionPerformed()
3068 * Set the 'follow' flag on the Viewport (and scroll to position if now
3071 final boolean state = this.followHighlightMenuItem.getState();
3072 viewport.setFollowHighlight(state);
3075 alignPanel.scrollToPosition(viewport.getSearchResults());
3086 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
3088 viewport.setColourText(colourTextMenuItem.isSelected());
3089 alignPanel.paintAlignment(false, false);
3099 public void wrapMenuItem_actionPerformed(ActionEvent e)
3101 scaleAbove.setVisible(wrapMenuItem.isSelected());
3102 scaleLeft.setVisible(wrapMenuItem.isSelected());
3103 scaleRight.setVisible(wrapMenuItem.isSelected());
3104 viewport.setWrapAlignment(wrapMenuItem.isSelected());
3105 alignPanel.updateLayout();
3109 public void showAllSeqs_actionPerformed(ActionEvent e)
3111 viewport.showAllHiddenSeqs();
3115 public void showAllColumns_actionPerformed(ActionEvent e)
3117 viewport.showAllHiddenColumns();
3118 alignPanel.paintAlignment(true, true);
3119 viewport.sendSelection();
3123 public void hideSelSequences_actionPerformed(ActionEvent e)
3125 viewport.hideAllSelectedSeqs();
3129 * called by key handler and the hide all/show all menu items
3134 protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3137 boolean hide = false;
3138 SequenceGroup sg = viewport.getSelectionGroup();
3139 if (!toggleSeqs && !toggleCols)
3141 // Hide everything by the current selection - this is a hack - we do the
3142 // invert and then hide
3143 // first check that there will be visible columns after the invert.
3144 if (viewport.hasSelectedColumns() || (sg != null && sg.getSize() > 0
3145 && sg.getStartRes() <= sg.getEndRes()))
3147 // now invert the sequence set, if required - empty selection implies
3148 // that no hiding is required.
3151 invertSequenceMenuItem_actionPerformed(null);
3152 sg = viewport.getSelectionGroup();
3156 viewport.expandColSelection(sg, true);
3157 // finally invert the column selection and get the new sequence
3159 invertColSel_actionPerformed(null);
3166 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3168 hideSelSequences_actionPerformed(null);
3171 else if (!(toggleCols && viewport.hasSelectedColumns()))
3173 showAllSeqs_actionPerformed(null);
3179 if (viewport.hasSelectedColumns())
3181 hideSelColumns_actionPerformed(null);
3184 viewport.setSelectionGroup(sg);
3189 showAllColumns_actionPerformed(null);
3198 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3199 * event.ActionEvent)
3202 public void hideAllButSelection_actionPerformed(ActionEvent e)
3204 toggleHiddenRegions(false, false);
3205 viewport.sendSelection();
3212 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3216 public void hideAllSelection_actionPerformed(ActionEvent e)
3218 SequenceGroup sg = viewport.getSelectionGroup();
3219 viewport.expandColSelection(sg, false);
3220 viewport.hideAllSelectedSeqs();
3221 viewport.hideSelectedColumns();
3222 alignPanel.updateLayout();
3223 alignPanel.paintAlignment(true, true);
3224 viewport.sendSelection();
3231 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3235 public void showAllhidden_actionPerformed(ActionEvent e)
3237 viewport.showAllHiddenColumns();
3238 viewport.showAllHiddenSeqs();
3239 alignPanel.paintAlignment(true, true);
3240 viewport.sendSelection();
3244 public void hideSelColumns_actionPerformed(ActionEvent e)
3246 viewport.hideSelectedColumns();
3247 alignPanel.updateLayout();
3248 alignPanel.paintAlignment(true, true);
3249 viewport.sendSelection();
3253 public void hiddenMarkers_actionPerformed(ActionEvent e)
3255 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3266 protected void scaleAbove_actionPerformed(ActionEvent e)
3268 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3269 alignPanel.updateLayout();
3270 alignPanel.paintAlignment(true, false);
3280 protected void scaleLeft_actionPerformed(ActionEvent e)
3282 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3283 alignPanel.updateLayout();
3284 alignPanel.paintAlignment(true, false);
3294 protected void scaleRight_actionPerformed(ActionEvent e)
3296 viewport.setScaleRightWrapped(scaleRight.isSelected());
3297 alignPanel.updateLayout();
3298 alignPanel.paintAlignment(true, false);
3308 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3310 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3311 alignPanel.paintAlignment(false, false);
3321 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3323 viewport.setShowText(viewTextMenuItem.isSelected());
3324 alignPanel.paintAlignment(false, false);
3334 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3336 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3337 alignPanel.paintAlignment(false, false);
3340 public FeatureSettings featureSettings;
3343 public FeatureSettingsControllerI getFeatureSettingsUI()
3345 return featureSettings;
3349 public void featureSettings_actionPerformed(ActionEvent e)
3351 showFeatureSettingsUI();
3355 public FeatureSettingsControllerI showFeatureSettingsUI()
3357 if (featureSettings != null)
3359 featureSettings.closeOldSettings();
3360 featureSettings = null;
3362 if (!showSeqFeatures.isSelected())
3364 // make sure features are actually displayed
3365 showSeqFeatures.setSelected(true);
3366 showSeqFeatures_actionPerformed(null);
3368 featureSettings = new FeatureSettings(this);
3369 return featureSettings;
3373 * Set or clear 'Show Sequence Features'
3379 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3381 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3382 alignPanel.paintAlignment(true, true);
3386 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3387 * the annotations panel as a whole.
3389 * The options to show/hide all annotations should be enabled when the panel
3390 * is shown, and disabled when the panel is hidden.
3395 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3397 final boolean setVisible = annotationPanelMenuItem.isSelected();
3398 viewport.setShowAnnotation(setVisible);
3399 this.showAllSeqAnnotations.setEnabled(setVisible);
3400 this.hideAllSeqAnnotations.setEnabled(setVisible);
3401 this.showAllAlAnnotations.setEnabled(setVisible);
3402 this.hideAllAlAnnotations.setEnabled(setVisible);
3403 alignPanel.updateLayout();
3407 public void alignmentProperties()
3410 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3413 String content = MessageManager.formatMessage("label.html_content",
3415 { contents.toString() });
3418 if (Platform.isJS())
3420 JLabel textLabel = new JLabel();
3421 textLabel.setText(content);
3422 textLabel.setBackground(Color.WHITE);
3424 pane = new JPanel(new BorderLayout());
3425 ((JPanel) pane).setOpaque(true);
3426 pane.setBackground(Color.WHITE);
3427 ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
3436 JEditorPane editPane = new JEditorPane("text/html", "");
3437 editPane.setEditable(false);
3438 editPane.setText(content);
3442 JInternalFrame frame = new JInternalFrame();
3444 frame.getContentPane().add(new JScrollPane(pane));
3446 Desktop.addInternalFrame(frame, MessageManager
3447 .formatMessage("label.alignment_properties", new Object[]
3448 { getTitle() }), 500, 400);
3452 * Opens an Overview panel for the alignment, unless one is open already
3457 public void overviewMenuItem_actionPerformed(ActionEvent e)
3459 boolean showHiddenRegions = Cache
3460 .getDefault(Preferences.SHOW_OV_HIDDEN_AT_START, false);
3461 openOverviewPanel(showHiddenRegions);
3464 public OverviewPanel openOverviewPanel(boolean showHidden)
3466 if (alignPanel.overviewPanel != null)
3468 return alignPanel.overviewPanel;
3470 JInternalFrame frame = new JInternalFrame();
3471 final OverviewPanel overview = new OverviewPanel(alignPanel, frame,
3473 frame.setContentPane(overview);
3474 Desktop.addInternalFrame(frame, "", true, frame.getWidth(),
3475 frame.getHeight(), true, true);
3476 frame.setFrameIcon(null);
3478 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3479 final AlignmentPanel thePanel = this.alignPanel;
3480 frame.addInternalFrameListener(
3481 new javax.swing.event.InternalFrameAdapter()
3484 public void internalFrameClosed(
3485 javax.swing.event.InternalFrameEvent evt)
3488 thePanel.setOverviewPanel(null);
3491 if (getKeyListeners().length > 0)
3493 frame.addKeyListener(getKeyListeners()[0]);
3496 alignPanel.setOverviewPanel(overview);
3497 alignPanel.setOverviewTitle(this);
3503 public void textColour_actionPerformed()
3505 new TextColourChooser().chooseColour(alignPanel, null);
3509 * public void covariationColour_actionPerformed() {
3511 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3515 public void annotationColour_actionPerformed()
3517 new AnnotationColourChooser(viewport, alignPanel);
3521 public void annotationColumn_actionPerformed(ActionEvent e)
3523 new AnnotationColumnChooser(viewport, alignPanel);
3527 * Action on the user checking or unchecking the option to apply the selected
3528 * colour scheme to all groups. If unchecked, groups may have their own
3529 * independent colour schemes.
3534 public void applyToAllGroups_actionPerformed(boolean selected)
3536 viewport.setColourAppliesToAllGroups(selected);
3540 * Action on user selecting a colour from the colour menu
3543 * the name (not the menu item label!) of the colour scheme
3546 public void changeColour_actionPerformed(String name)
3549 * 'User Defined' opens a panel to configure or load a
3550 * user-defined colour scheme
3552 if (ResidueColourScheme.USER_DEFINED_MENU.equals(name))
3554 new UserDefinedColours(alignPanel);
3559 * otherwise set the chosen colour scheme (or null for 'None')
3561 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3562 viewport, viewport.getAlignment(),
3563 viewport.getHiddenRepSequences());
3568 * Actions on setting or changing the alignment colour scheme
3573 public void changeColour(ColourSchemeI cs)
3575 // TODO: pull up to controller method
3576 ColourMenuHelper.setColourSelected(colourMenu, cs);
3578 viewport.setGlobalColourScheme(cs);
3580 alignPanel.paintAlignment(true, true);
3584 * Show the PID threshold slider panel
3587 protected void modifyPID_actionPerformed()
3589 SliderPanel.setPIDSliderSource(alignPanel, viewport.getResidueShading(),
3590 alignPanel.getViewName());
3591 SliderPanel.showPIDSlider();
3595 * Show the Conservation slider panel
3598 protected void modifyConservation_actionPerformed()
3600 SliderPanel.setConservationSlider(alignPanel,
3601 viewport.getResidueShading(), alignPanel.getViewName());
3602 SliderPanel.showConservationSlider();
3606 * Action on selecting or deselecting (Colour) By Conservation
3609 public void conservationMenuItem_actionPerformed(boolean selected)
3611 modifyConservation.setEnabled(selected);
3612 viewport.setConservationSelected(selected);
3613 viewport.getResidueShading().setConservationApplied(selected);
3615 changeColour(viewport.getGlobalColourScheme());
3618 modifyConservation_actionPerformed();
3622 SliderPanel.hideConservationSlider();
3627 * Action on selecting or deselecting (Colour) Above PID Threshold
3630 public void abovePIDThreshold_actionPerformed(boolean selected)
3632 modifyPID.setEnabled(selected);
3633 viewport.setAbovePIDThreshold(selected);
3636 viewport.getResidueShading().setThreshold(0,
3637 viewport.isIgnoreGapsConsensus());
3640 changeColour(viewport.getGlobalColourScheme());
3643 modifyPID_actionPerformed();
3647 SliderPanel.hidePIDSlider();
3658 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3660 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3661 AlignmentSorter.sortByPID(viewport.getAlignment(),
3662 viewport.getAlignment().getSequenceAt(0));
3663 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3664 viewport.getAlignment()));
3665 alignPanel.paintAlignment(true, false);
3675 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3677 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3678 AlignmentSorter.sortByID(viewport.getAlignment());
3680 new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
3681 alignPanel.paintAlignment(true, false);
3691 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3693 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3694 AlignmentSorter.sortByLength(viewport.getAlignment());
3695 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3696 viewport.getAlignment()));
3697 alignPanel.paintAlignment(true, false);
3707 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3709 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3710 AlignmentSorter.sortByGroup(viewport.getAlignment());
3711 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3712 viewport.getAlignment()));
3714 alignPanel.paintAlignment(true, false);
3724 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3726 new RedundancyPanel(alignPanel, this);
3736 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3738 if ((viewport.getSelectionGroup() == null)
3739 || (viewport.getSelectionGroup().getSize() < 2))
3741 JvOptionPane.showInternalMessageDialog(this,
3742 MessageManager.getString(
3743 "label.you_must_select_least_two_sequences"),
3744 MessageManager.getString("label.invalid_selection"),
3745 JvOptionPane.WARNING_MESSAGE);
3749 JInternalFrame frame = new JInternalFrame();
3750 frame.setContentPane(new PairwiseAlignPanel(viewport));
3751 Desktop.addInternalFrame(frame,
3752 MessageManager.getString("action.pairwise_alignment"), 600,
3758 public void autoCalculate_actionPerformed(ActionEvent e)
3760 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3761 if (viewport.autoCalculateConsensus)
3763 viewport.firePropertyChange("alignment", null,
3764 viewport.getAlignment().getSequences());
3769 public void sortByTreeOption_actionPerformed(ActionEvent e)
3771 viewport.sortByTree = sortByTree.isSelected();
3775 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3777 viewport.followSelection = listenToViewSelections.isSelected();
3781 * Constructs a tree panel and adds it to the desktop
3784 * tree type (NJ or AV)
3786 * name of score model used to compute the tree
3788 * parameters for the distance or similarity calculation
3790 void newTreePanel(String type, String modelName,
3791 SimilarityParamsI options)
3793 String frameTitle = "";
3796 boolean onSelection = false;
3797 if (viewport.getSelectionGroup() != null
3798 && viewport.getSelectionGroup().getSize() > 0)
3800 SequenceGroup sg = viewport.getSelectionGroup();
3802 /* Decide if the selection is a column region */
3803 for (SequenceI _s : sg.getSequences())
3805 if (_s.getLength() < sg.getEndRes())
3807 JvOptionPane.showMessageDialog(Desktop.desktop,
3808 MessageManager.getString(
3809 "label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3810 MessageManager.getString(
3811 "label.sequences_selection_not_aligned"),
3812 JvOptionPane.WARNING_MESSAGE);
3821 if (viewport.getAlignment().getHeight() < 2)
3827 tp = new TreePanel(alignPanel, type, modelName, options);
3828 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3830 frameTitle += " from ";
3832 if (viewport.getViewName() != null)
3834 frameTitle += viewport.getViewName() + " of ";
3837 frameTitle += this.title;
3839 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3850 public void addSortByOrderMenuItem(String title,
3851 final AlignmentOrder order)
3853 final JMenuItem item = new JMenuItem(MessageManager
3854 .formatMessage("action.by_title_param", new Object[]
3857 item.addActionListener(new java.awt.event.ActionListener()
3860 public void actionPerformed(ActionEvent e)
3862 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3864 // TODO: JBPNote - have to map order entries to curent SequenceI
3866 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3868 addHistoryItem(new OrderCommand(order.getName(), oldOrder,
3869 viewport.getAlignment()));
3871 alignPanel.paintAlignment(true, false);
3877 * Add a new sort by annotation score menu item
3880 * the menu to add the option to
3882 * the label used to retrieve scores for each sequence on the
3885 public void addSortByAnnotScoreMenuItem(JMenu sort,
3886 final String scoreLabel)
3888 final JMenuItem item = new JMenuItem(scoreLabel);
3890 item.addActionListener(new java.awt.event.ActionListener()
3893 public void actionPerformed(ActionEvent e)
3895 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3896 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3897 viewport.getAlignment());// ,viewport.getSelectionGroup());
3898 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3899 viewport.getAlignment()));
3900 alignPanel.paintAlignment(true, false);
3906 * last hash for alignment's annotation array - used to minimise cost of
3909 protected int _annotationScoreVectorHash;
3912 * search the alignment and rebuild the sort by annotation score submenu the
3913 * last alignment annotation vector hash is stored to minimize cost of
3914 * rebuilding in subsequence calls.
3918 public void buildSortByAnnotationScoresMenu()
3920 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3925 if (viewport.getAlignment().getAlignmentAnnotation()
3926 .hashCode() != _annotationScoreVectorHash)
3928 sortByAnnotScore.removeAll();
3929 // almost certainly a quicker way to do this - but we keep it simple
3930 Hashtable<String, String> scoreSorts = new Hashtable<>();
3931 AlignmentAnnotation aann[];
3932 for (SequenceI sqa : viewport.getAlignment().getSequences())
3934 aann = sqa.getAnnotation();
3935 for (int i = 0; aann != null && i < aann.length; i++)
3937 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3939 scoreSorts.put(aann[i].label, aann[i].label);
3943 Enumeration<String> labels = scoreSorts.keys();
3944 while (labels.hasMoreElements())
3946 addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
3948 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3951 _annotationScoreVectorHash = viewport.getAlignment()
3952 .getAlignmentAnnotation().hashCode();
3957 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3958 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3959 * call. Listeners are added to remove the menu item when the treePanel is
3960 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3964 public void buildTreeSortMenu()
3966 sortByTreeMenu.removeAll();
3968 List<Component> comps = PaintRefresher.components
3969 .get(viewport.getSequenceSetId());
3970 List<TreePanel> treePanels = new ArrayList<>();
3971 for (Component comp : comps)
3973 if (comp instanceof TreePanel)
3975 treePanels.add((TreePanel) comp);
3979 if (treePanels.size() < 1)
3981 sortByTreeMenu.setVisible(false);
3985 sortByTreeMenu.setVisible(true);
3987 for (final TreePanel tp : treePanels)
3989 final JMenuItem item = new JMenuItem(tp.getTitle());
3990 item.addActionListener(new java.awt.event.ActionListener()
3993 public void actionPerformed(ActionEvent e)
3995 tp.sortByTree_actionPerformed();
3996 addHistoryItem(tp.sortAlignmentIn(alignPanel));
4001 sortByTreeMenu.add(item);
4005 public boolean sortBy(AlignmentOrder alorder, String undoname)
4007 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
4008 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
4009 if (undoname != null)
4011 addHistoryItem(new OrderCommand(undoname, oldOrder,
4012 viewport.getAlignment()));
4014 alignPanel.paintAlignment(true, false);
4019 * Work out whether the whole set of sequences or just the selected set will
4020 * be submitted for multiple alignment.
4023 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
4025 // Now, check we have enough sequences
4026 AlignmentView msa = null;
4028 if ((viewport.getSelectionGroup() != null)
4029 && (viewport.getSelectionGroup().getSize() > 1))
4031 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
4032 // some common interface!
4034 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
4035 * SequenceI[sz = seqs.getSize(false)];
4037 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
4038 * seqs.getSequenceAt(i); }
4040 msa = viewport.getAlignmentView(true);
4042 else if (viewport.getSelectionGroup() != null
4043 && viewport.getSelectionGroup().getSize() == 1)
4045 int option = JvOptionPane.showConfirmDialog(this,
4046 MessageManager.getString("warn.oneseq_msainput_selection"),
4047 MessageManager.getString("label.invalid_selection"),
4048 JvOptionPane.OK_CANCEL_OPTION);
4049 if (option == JvOptionPane.OK_OPTION)
4051 msa = viewport.getAlignmentView(false);
4056 msa = viewport.getAlignmentView(false);
4062 * Decides what is submitted to a secondary structure prediction service: the
4063 * first sequence in the alignment, or in the current selection, or, if the
4064 * alignment is 'aligned' (ie padded with gaps), then the currently selected
4065 * region or the whole alignment. (where the first sequence in the set is the
4066 * one that the prediction will be for).
4068 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
4070 AlignmentView seqs = null;
4072 if ((viewport.getSelectionGroup() != null)
4073 && (viewport.getSelectionGroup().getSize() > 0))
4075 seqs = viewport.getAlignmentView(true);
4079 seqs = viewport.getAlignmentView(false);
4081 // limit sequences - JBPNote in future - could spawn multiple prediction
4083 // TODO: viewport.getAlignment().isAligned is a global state - the local
4084 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
4085 if (!viewport.getAlignment().isAligned(false))
4087 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
4088 // TODO: if seqs.getSequences().length>1 then should really have warned
4102 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
4104 // Pick the tree file
4105 JalviewFileChooser chooser = new JalviewFileChooser(
4106 Cache.getProperty("LAST_DIRECTORY"));
4107 chooser.setFileView(new JalviewFileView());
4108 chooser.setDialogTitle(
4109 MessageManager.getString("label.select_newick_like_tree_file"));
4110 chooser.setToolTipText(
4111 MessageManager.getString("label.load_tree_file"));
4113 chooser.setResponseHandler(0, () -> {
4114 String filePath = chooser.getSelectedFile().getPath();
4115 Cache.setProperty("LAST_DIRECTORY", filePath);
4116 NewickFile fin = null;
4119 fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
4120 DataSourceType.FILE));
4121 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
4122 } catch (Exception ex)
4124 JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
4125 MessageManager.getString("label.problem_reading_tree_file"),
4126 JvOptionPane.WARNING_MESSAGE);
4127 ex.printStackTrace();
4129 if (fin != null && fin.hasWarningMessage())
4131 JvOptionPane.showMessageDialog(Desktop.desktop,
4132 fin.getWarningMessage(),
4134 .getString("label.possible_problem_with_tree_file"),
4135 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,
4204 PAEContactMatrix cm)
4207 int w = 400, h = 500;
4211 NewickFile fin = new NewickFile(
4212 new FileParse(cm.getNewick(), DataSourceType.PASTE));
4213 String title = "PAE Matrix Tree for "
4214 + cm.getReferenceSeq().getDisplayId(false);
4216 showColumnWiseTree(fin, aa, title, w, h, x, y);
4217 } catch (Throwable xx)
4219 Console.error("Unexpected exception showing tree for contact matrix",
4224 public TreePanel showColumnWiseTree(NewickFile nf, AlignmentAnnotation aa,
4225 String treeTitle, int w, int h, int x, int y)
4230 if (nf.getTree() == null)
4234 TreePanel tp = new TreePanel(alignPanel, nf, aa, title);
4240 tp.setLocation(x, y);
4243 Desktop.addInternalFrame(tp, title, w, h);
4245 } catch (Throwable xx)
4247 Console.error("Unexpected exception showing tree for contact matrix",
4253 private boolean buildingMenu = false;
4256 * Generates menu items and listener event actions for web service clients
4259 public void BuildWebServiceMenu()
4261 while (buildingMenu)
4265 System.err.println("Waiting for building menu to finish.");
4267 } catch (Exception e)
4271 final AlignFrame me = this;
4272 buildingMenu = true;
4273 new Thread(new Runnable()
4278 final List<JMenuItem> legacyItems = new ArrayList<>();
4281 // System.err.println("Building ws menu again "
4282 // + Thread.currentThread());
4283 // TODO: add support for context dependent disabling of services based
4285 // alignment and current selection
4286 // TODO: add additional serviceHandle parameter to specify abstract
4288 // class independently of AbstractName
4289 // TODO: add in rediscovery GUI function to restart discoverer
4290 // TODO: group services by location as well as function and/or
4292 // object broker mechanism.
4293 final Vector<JMenu> wsmenu = new Vector<>();
4294 final IProgressIndicator af = me;
4297 * do not i18n these strings - they are hard-coded in class
4298 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4299 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4301 final JMenu msawsmenu = new JMenu("Alignment");
4302 final JMenu secstrmenu = new JMenu(
4303 "Secondary Structure Prediction");
4304 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4305 final JMenu analymenu = new JMenu("Analysis");
4306 final JMenu dismenu = new JMenu("Protein Disorder");
4307 // JAL-940 - only show secondary structure prediction services from
4308 // the legacy server
4309 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4311 Discoverer.services != null && (Discoverer.services.size() > 0))
4313 // TODO: refactor to allow list of AbstractName/Handler bindings to
4315 // stored or retrieved from elsewhere
4316 // No MSAWS used any more:
4317 // Vector msaws = null; // (Vector)
4318 // Discoverer.services.get("MsaWS");
4319 Vector<ServiceHandle> secstrpr = Discoverer.services
4321 if (secstrpr != null)
4323 // Add any secondary structure prediction services
4324 for (int i = 0, j = secstrpr.size(); i < j; i++)
4326 final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
4327 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4328 .getServiceClient(sh);
4329 int p = secstrmenu.getItemCount();
4330 impl.attachWSMenuEntry(secstrmenu, me);
4331 int q = secstrmenu.getItemCount();
4332 for (int litm = p; litm < q; litm++)
4334 legacyItems.add(secstrmenu.getItem(litm));
4340 // Add all submenus in the order they should appear on the web
4342 wsmenu.add(msawsmenu);
4343 wsmenu.add(secstrmenu);
4344 wsmenu.add(dismenu);
4345 wsmenu.add(analymenu);
4346 // No search services yet
4347 // wsmenu.add(seqsrchmenu);
4349 javax.swing.SwingUtilities.invokeLater(new Runnable()
4356 webService.removeAll();
4357 // first, add discovered services onto the webservices menu
4358 if (wsmenu.size() > 0)
4360 for (int i = 0, j = wsmenu.size(); i < j; i++)
4362 webService.add(wsmenu.get(i));
4367 webService.add(me.webServiceNoServices);
4369 // TODO: move into separate menu builder class.
4371 // logic for 2.11.1.4 is
4372 // always look to see if there is a discover. if there isn't
4373 // we can't show any Jws2 services
4374 // if there are services available, show them - regardless of
4375 // the 'show JWS2 preference'
4376 // if the discoverer is running then say so
4377 // otherwise offer to trigger discovery if 'show JWS2' is not
4379 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4380 if (jws2servs != null)
4382 if (jws2servs.hasServices())
4384 jws2servs.attachWSMenuEntry(webService, me);
4385 for (Jws2Instance sv : jws2servs.getServices())
4387 if (sv.description.toLowerCase(Locale.ROOT)
4390 for (JMenuItem jmi : legacyItems)
4392 jmi.setVisible(false);
4398 if (jws2servs.isRunning())
4400 JMenuItem tm = new JMenuItem(
4401 "Still discovering JABA Services");
4402 tm.setEnabled(false);
4405 else if (!Cache.getDefault("SHOW_JWS2_SERVICES", true))
4407 JMenuItem enableJws2 = new JMenuItem(
4408 "Discover Web Services");
4409 enableJws2.setToolTipText(
4410 "Select to start JABA Web Service discovery (or enable option in Web Service preferences)");
4411 enableJws2.setEnabled(true);
4412 enableJws2.addActionListener(new ActionListener()
4416 public void actionPerformed(ActionEvent e)
4418 // start service discoverer, but ignore preference
4419 Desktop.instance.startServiceDiscovery(false,
4423 webService.add(enableJws2);
4427 build_urlServiceMenu(me.webService);
4428 build_fetchdbmenu(webService);
4429 for (JMenu item : wsmenu)
4431 if (item.getItemCount() == 0)
4433 item.setEnabled(false);
4437 item.setEnabled(true);
4440 } catch (Exception e)
4443 "Exception during web service menu building process.",
4448 } catch (Exception e)
4451 buildingMenu = false;
4458 * construct any groupURL type service menu entries.
4462 protected void build_urlServiceMenu(JMenu webService)
4464 // TODO: remove this code when 2.7 is released
4465 // DEBUG - alignmentView
4467 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4468 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4470 * @Override public void actionPerformed(ActionEvent e) {
4471 * jalview.datamodel.AlignmentView
4472 * .testSelectionViews(af.viewport.getAlignment(),
4473 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4475 * }); webService.add(testAlView);
4477 // TODO: refactor to RestClient discoverer and merge menu entries for
4478 // rest-style services with other types of analysis/calculation service
4479 // SHmmr test client - still being implemented.
4480 // DEBUG - alignmentView
4482 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4485 client.attachWSMenuEntry(
4486 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4492 * Searches the alignment sequences for xRefs and builds the Show
4493 * Cross-References menu (formerly called Show Products), with database
4494 * sources for which cross-references are found (protein sources for a
4495 * nucleotide alignment and vice versa)
4497 * @return true if Show Cross-references menu should be enabled
4499 public boolean canShowProducts()
4501 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4502 AlignmentI dataset = viewport.getAlignment().getDataset();
4504 showProducts.removeAll();
4505 final boolean dna = viewport.getAlignment().isNucleotide();
4507 if (seqs == null || seqs.length == 0)
4509 // nothing to see here.
4513 boolean showp = false;
4516 List<String> ptypes = new CrossRef(seqs, dataset)
4517 .findXrefSourcesForSequences(dna);
4519 for (final String source : ptypes)
4522 final AlignFrame af = this;
4523 JMenuItem xtype = new JMenuItem(source);
4524 xtype.addActionListener(new ActionListener()
4527 public void actionPerformed(ActionEvent e)
4529 showProductsFor(af.viewport.getSequenceSelection(), dna,
4533 showProducts.add(xtype);
4535 showProducts.setVisible(showp);
4536 showProducts.setEnabled(showp);
4537 } catch (Exception e)
4540 "canShowProducts threw an exception - please report to help@jalview.org",
4548 * Finds and displays cross-references for the selected sequences (protein
4549 * products for nucleotide sequences, dna coding sequences for peptides).
4552 * the sequences to show cross-references for
4554 * true if from a nucleotide alignment (so showing proteins)
4556 * the database to show cross-references for
4558 protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
4559 final String source)
4561 new Thread(CrossRefAction.getHandlerFor(sel, _odna, source, this))
4566 * Construct and display a new frame containing the translation of this
4567 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4570 public void showTranslation_actionPerformed(GeneticCodeI codeTable)
4572 AlignmentI al = null;
4575 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4577 al = dna.translateCdna(codeTable);
4578 } catch (Exception ex)
4580 Console.error("Exception during translation. Please report this !",
4582 final String msg = MessageManager.getString(
4583 "label.error_when_translating_sequences_submit_bug_report");
4584 final String errorTitle = MessageManager
4585 .getString("label.implementation_error")
4586 + MessageManager.getString("label.translation_failed");
4587 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4588 JvOptionPane.ERROR_MESSAGE);
4591 if (al == null || al.getHeight() == 0)
4593 final String msg = MessageManager.getString(
4594 "label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4595 final String errorTitle = MessageManager
4596 .getString("label.translation_failed");
4597 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4598 JvOptionPane.WARNING_MESSAGE);
4602 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4603 af.setFileFormat(this.currentFileFormat);
4604 final String newTitle = MessageManager
4605 .formatMessage("label.translation_of_params", new Object[]
4606 { this.getTitle(), codeTable.getId() });
4607 af.setTitle(newTitle);
4608 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4610 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4611 viewport.openSplitFrame(af, new Alignment(seqs));
4615 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4622 * Set the file format
4626 public void setFileFormat(FileFormatI format)
4628 this.currentFileFormat = format;
4632 * Try to load a features file onto the alignment.
4635 * contents or path to retrieve file or a File object
4637 * access mode of file (see jalview.io.AlignFile)
4638 * @return true if features file was parsed correctly.
4640 public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
4643 return avc.parseFeaturesFile(file, sourceType,
4644 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4649 public void refreshFeatureUI(boolean enableIfNecessary)
4651 // note - currently this is only still here rather than in the controller
4652 // because of the featureSettings hard reference that is yet to be
4654 if (enableIfNecessary)
4656 viewport.setShowSequenceFeatures(true);
4657 showSeqFeatures.setSelected(true);
4663 public void dragEnter(DropTargetDragEvent evt)
4668 public void dragExit(DropTargetEvent evt)
4673 public void dragOver(DropTargetDragEvent evt)
4678 public void dropActionChanged(DropTargetDragEvent evt)
4683 public void drop(DropTargetDropEvent evt)
4685 // JAL-1552 - acceptDrop required before getTransferable call for
4686 // Java's Transferable for native dnd
4687 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4688 Transferable t = evt.getTransferable();
4690 final AlignFrame thisaf = this;
4691 final List<Object> files = new ArrayList<>();
4692 List<DataSourceType> protocols = new ArrayList<>();
4696 Desktop.transferFromDropTarget(files, protocols, evt, t);
4697 } catch (Exception e)
4699 e.printStackTrace();
4703 new Thread(new Runnable()
4710 // check to see if any of these files have names matching sequences
4713 SequenceIdMatcher idm = new SequenceIdMatcher(
4714 viewport.getAlignment().getSequencesArray());
4716 * Object[] { String,SequenceI}
4718 ArrayList<Object[]> filesmatched = new ArrayList<>();
4719 ArrayList<Object> filesnotmatched = new ArrayList<>();
4720 for (int i = 0; i < files.size(); i++)
4723 Object file = files.get(i);
4724 String fileName = file.toString();
4726 DataSourceType protocol = (file instanceof File
4727 ? DataSourceType.FILE
4728 : FormatAdapter.checkProtocol(fileName));
4729 if (protocol == DataSourceType.FILE)
4732 if (file instanceof File)
4735 Platform.cacheFileData(fl);
4739 fl = new File(fileName);
4741 pdbfn = fl.getName();
4743 else if (protocol == DataSourceType.URL)
4745 URL url = new URL(fileName);
4746 pdbfn = url.getFile();
4748 if (pdbfn.length() > 0)
4750 // attempt to find a match in the alignment
4751 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4752 int l = 0, c = pdbfn.indexOf(".");
4753 while (mtch == null && c != -1)
4758 } while ((c = pdbfn.indexOf(".", l)) > l);
4761 pdbfn = pdbfn.substring(0, l);
4763 mtch = idm.findAllIdMatches(pdbfn);
4770 type = new IdentifyFile().identify(file, protocol);
4771 } catch (Exception ex)
4775 if (type != null && type.isStructureFile())
4777 filesmatched.add(new Object[] { file, protocol, mtch });
4781 // File wasn't named like one of the sequences or wasn't a PDB
4783 filesnotmatched.add(file);
4787 if (filesmatched.size() > 0)
4789 boolean autoAssociate = Cache
4790 .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
4793 String msg = MessageManager.formatMessage(
4794 "label.automatically_associate_structure_files_with_sequences_same_name",
4796 { Integer.valueOf(filesmatched.size())
4798 String ttl = MessageManager.getString(
4799 "label.automatically_associate_structure_files_by_name");
4800 int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
4801 ttl, JvOptionPane.YES_NO_OPTION);
4802 autoAssociate = choice == JvOptionPane.YES_OPTION;
4806 for (Object[] fm : filesmatched)
4808 // try and associate
4809 // TODO: may want to set a standard ID naming formalism for
4810 // associating PDB files which have no IDs.
4811 for (SequenceI toassoc : (SequenceI[]) fm[2])
4813 PDBEntry pe = new AssociatePdbFileWithSeq()
4814 .associatePdbWithSeq(fm[0].toString(),
4815 (DataSourceType) fm[1], toassoc, false,
4819 System.err.println("Associated file : "
4820 + (fm[0].toString()) + " with "
4821 + toassoc.getDisplayId(true));
4825 // TODO: do we need to update overview ? only if features are
4827 alignPanel.paintAlignment(true, false);
4833 * add declined structures as sequences
4835 for (Object[] o : filesmatched)
4837 filesnotmatched.add(o[0]);
4841 if (filesnotmatched.size() > 0)
4843 if (assocfiles > 0 && (Cache.getDefault(
4844 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
4845 || JvOptionPane.showConfirmDialog(thisaf,
4846 "<html>" + MessageManager.formatMessage(
4847 "label.ignore_unmatched_dropped_files_info",
4850 filesnotmatched.size())
4853 MessageManager.getString(
4854 "label.ignore_unmatched_dropped_files"),
4855 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4859 for (Object fn : filesnotmatched)
4861 loadJalviewDataFile(fn, null, null, null);
4865 } catch (Exception ex)
4867 ex.printStackTrace();
4875 * Attempt to load a "dropped" file or URL string, by testing in turn for
4877 * <li>an Annotation file</li>
4878 * <li>a JNet file</li>
4879 * <li>a features file</li>
4880 * <li>else try to interpret as an alignment file</li>
4884 * either a filename or a URL string.
4886 public void loadJalviewDataFile(Object file, DataSourceType sourceType,
4887 FileFormatI format, SequenceI assocSeq)
4889 // BH 2018 was String file
4892 if (sourceType == null)
4894 sourceType = FormatAdapter.checkProtocol(file);
4896 // if the file isn't identified, or not positively identified as some
4897 // other filetype (PFAM is default unidentified alignment file type) then
4898 // try to parse as annotation.
4899 boolean isAnnotation = (format == null
4900 || FileFormat.Pfam.equals(format))
4901 ? new AnnotationFile().annotateAlignmentView(viewport,
4907 // first see if its a T-COFFEE score file
4908 TCoffeeScoreFile tcf = null;
4911 tcf = new TCoffeeScoreFile(file, sourceType);
4914 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4918 new TCoffeeColourScheme(viewport.getAlignment()));
4919 isAnnotation = true;
4920 setStatus(MessageManager.getString(
4921 "label.successfully_pasted_tcoffee_scores_to_alignment"));
4925 // some problem - if no warning its probable that the ID matching
4926 // process didn't work
4927 JvOptionPane.showMessageDialog(Desktop.desktop,
4928 tcf.getWarningMessage() == null
4929 ? MessageManager.getString(
4930 "label.check_file_matches_sequence_ids_alignment")
4931 : tcf.getWarningMessage(),
4932 MessageManager.getString(
4933 "label.problem_reading_tcoffee_score_file"),
4934 JvOptionPane.WARNING_MESSAGE);
4941 } catch (Exception x)
4944 "Exception when processing data source as T-COFFEE score file",
4950 // try to see if its a JNet 'concise' style annotation file *before*
4952 // try to parse it as a features file
4955 format = new IdentifyFile().identify(file, sourceType);
4957 if (FileFormat.ScoreMatrix == format)
4959 ScoreMatrixFile sm = new ScoreMatrixFile(
4960 new FileParse(file, sourceType));
4962 // todo: i18n this message
4963 setStatus(MessageManager.formatMessage(
4964 "label.successfully_loaded_matrix",
4965 sm.getMatrixName()));
4967 else if (FileFormat.Jnet.equals(format))
4969 JPredFile predictions = new JPredFile(file, sourceType);
4970 new JnetAnnotationMaker();
4971 JnetAnnotationMaker.add_annotation(predictions,
4972 viewport.getAlignment(), 0, false);
4973 viewport.getAlignment().setupJPredAlignment();
4974 isAnnotation = true;
4976 // else if (IdentifyFile.FeaturesFile.equals(format))
4977 else if (FileFormat.Features.equals(format))
4979 if (parseFeaturesFile(file, sourceType))
4981 SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
4982 if (splitFrame != null)
4984 splitFrame.repaint();
4988 alignPanel.paintAlignment(true, true);
4994 new FileLoader().LoadFile(viewport, file, sourceType, format);
5001 alignPanel.adjustAnnotationHeight();
5002 viewport.updateSequenceIdColours();
5003 buildSortByAnnotationScoresMenu();
5004 alignPanel.paintAlignment(true, true);
5006 } catch (Exception ex)
5008 ex.printStackTrace();
5009 } catch (OutOfMemoryError oom)
5014 } catch (Exception x)
5019 + (sourceType != null
5020 ? (sourceType == DataSourceType.PASTE
5022 : "using " + sourceType + " from "
5026 ? "(parsing as '" + format + "' file)"
5028 oom, Desktop.desktop);
5033 * Method invoked by the ChangeListener on the tabbed pane, in other words
5034 * when a different tabbed pane is selected by the user or programmatically.
5037 public void tabSelectionChanged(int index)
5042 * update current Overview window title (if there is one)
5043 * to add view name "Original" if necessary
5045 alignPanel.setOverviewTitle(this);
5048 * switch panels and set Overview title (if there is one
5049 * because it was opened automatically)
5051 alignPanel = alignPanels.get(index);
5052 alignPanel.setOverviewTitle(this);
5054 viewport = alignPanel.av;
5055 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
5056 setMenusFromViewport(viewport);
5057 if (featureSettings != null && featureSettings.isOpen()
5058 && featureSettings.fr.getViewport() != viewport)
5060 if (viewport.isShowSequenceFeatures())
5062 // refresh the featureSettings to reflect UI change
5063 showFeatureSettingsUI();
5067 // close feature settings for this view.
5068 featureSettings.close();
5075 * 'focus' any colour slider that is open to the selected viewport
5077 if (viewport.getConservationSelected())
5079 SliderPanel.setConservationSlider(alignPanel,
5080 viewport.getResidueShading(), alignPanel.getViewName());
5084 SliderPanel.hideConservationSlider();
5086 if (viewport.getAbovePIDThreshold())
5088 SliderPanel.setPIDSliderSource(alignPanel,
5089 viewport.getResidueShading(), alignPanel.getViewName());
5093 SliderPanel.hidePIDSlider();
5097 * If there is a frame linked to this one in a SplitPane, switch it to the
5098 * same view tab index. No infinite recursion of calls should happen, since
5099 * tabSelectionChanged() should not get invoked on setting the selected
5100 * index to an unchanged value. Guard against setting an invalid index
5101 * before the new view peer tab has been created.
5103 final AlignViewportI peer = viewport.getCodingComplement();
5106 AlignFrame linkedAlignFrame = ((AlignViewport) peer)
5107 .getAlignPanel().alignFrame;
5108 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
5110 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
5116 * On right mouse click on view tab, prompt for and set new view name.
5119 public void tabbedPane_mousePressed(MouseEvent e)
5121 if (e.isPopupTrigger())
5123 String msg = MessageManager.getString("label.enter_view_name");
5124 String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
5125 String reply = JvOptionPane.showInputDialog(msg, ttl);
5129 viewport.setViewName(reply);
5130 // TODO warn if reply is in getExistingViewNames()?
5131 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
5136 public AlignViewport getCurrentView()
5142 * Open the dialog for regex description parsing.
5145 protected void extractScores_actionPerformed(ActionEvent e)
5147 ParseProperties pp = new jalview.analysis.ParseProperties(
5148 viewport.getAlignment());
5149 // TODO: verify regex and introduce GUI dialog for version 2.5
5150 // if (pp.getScoresFromDescription("col", "score column ",
5151 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
5153 if (pp.getScoresFromDescription("description column",
5154 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
5156 buildSortByAnnotationScoresMenu();
5164 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
5168 protected void showDbRefs_actionPerformed(ActionEvent e)
5170 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
5176 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
5180 protected void showNpFeats_actionPerformed(ActionEvent e)
5182 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
5186 * find the viewport amongst the tabs in this alignment frame and close that
5191 public boolean closeView(AlignViewportI av)
5195 this.closeMenuItem_actionPerformed(false);
5198 Component[] comp = tabbedPane.getComponents();
5199 for (int i = 0; comp != null && i < comp.length; i++)
5201 if (comp[i] instanceof AlignmentPanel)
5203 if (((AlignmentPanel) comp[i]).av == av)
5206 closeView((AlignmentPanel) comp[i]);
5214 protected void build_fetchdbmenu(JMenu webService)
5216 // Temporary hack - DBRef Fetcher always top level ws entry.
5217 // TODO We probably want to store a sequence database checklist in
5218 // preferences and have checkboxes.. rather than individual sources selected
5220 final JMenu rfetch = new JMenu(
5221 MessageManager.getString("action.fetch_db_references"));
5222 rfetch.setToolTipText(MessageManager.getString(
5223 "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
5224 webService.add(rfetch);
5226 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
5227 MessageManager.getString("option.trim_retrieved_seqs"));
5228 trimrs.setToolTipText(
5229 MessageManager.getString("label.trim_retrieved_sequences"));
5231 Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
5232 trimrs.addActionListener(new ActionListener()
5235 public void actionPerformed(ActionEvent e)
5237 trimrs.setSelected(trimrs.isSelected());
5238 Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
5239 Boolean.valueOf(trimrs.isSelected()).toString());
5243 JMenuItem fetchr = new JMenuItem(
5244 MessageManager.getString("label.standard_databases"));
5245 fetchr.setToolTipText(
5246 MessageManager.getString("label.fetch_embl_uniprot"));
5247 fetchr.addActionListener(new ActionListener()
5251 public void actionPerformed(ActionEvent e)
5253 new Thread(new Runnable()
5258 boolean isNucleotide = alignPanel.alignFrame.getViewport()
5259 .getAlignment().isNucleotide();
5260 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5261 alignPanel.av.getSequenceSelection(),
5262 alignPanel.alignFrame, null,
5263 alignPanel.alignFrame.featureSettings, isNucleotide);
5264 dbRefFetcher.addListener(new FetchFinishedListenerI()
5267 public void finished()
5270 for (FeatureSettingsModelI srcSettings : dbRefFetcher
5271 .getFeatureSettingsModels())
5274 alignPanel.av.mergeFeaturesStyle(srcSettings);
5276 AlignFrame.this.setMenusForViewport();
5279 dbRefFetcher.fetchDBRefs(false);
5287 new Thread(new Runnable()
5292 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
5293 .getSequenceFetcherSingleton();
5294 javax.swing.SwingUtilities.invokeLater(new Runnable()
5299 String[] dbclasses = sf.getNonAlignmentSources();
5300 List<DbSourceProxy> otherdb;
5301 JMenu dfetch = new JMenu();
5302 JMenu ifetch = new JMenu();
5303 JMenuItem fetchr = null;
5304 int comp = 0, icomp = 0, mcomp = 15;
5305 String mname = null;
5307 for (String dbclass : dbclasses)
5309 otherdb = sf.getSourceProxy(dbclass);
5310 // add a single entry for this class, or submenu allowing 'fetch
5312 if (otherdb == null || otherdb.size() < 1)
5318 mname = "From " + dbclass;
5320 if (otherdb.size() == 1)
5322 final DbSourceProxy[] dassource = otherdb
5323 .toArray(new DbSourceProxy[0]);
5324 DbSourceProxy src = otherdb.get(0);
5325 fetchr = new JMenuItem(src.getDbSource());
5326 fetchr.addActionListener(new ActionListener()
5330 public void actionPerformed(ActionEvent e)
5332 new Thread(new Runnable()
5338 boolean isNucleotide = alignPanel.alignFrame
5339 .getViewport().getAlignment()
5341 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5342 alignPanel.av.getSequenceSelection(),
5343 alignPanel.alignFrame, dassource,
5344 alignPanel.alignFrame.featureSettings,
5347 .addListener(new FetchFinishedListenerI()
5350 public void finished()
5352 FeatureSettingsModelI srcSettings = dassource[0]
5353 .getFeatureColourScheme();
5354 alignPanel.av.mergeFeaturesStyle(
5356 AlignFrame.this.setMenusForViewport();
5359 dbRefFetcher.fetchDBRefs(false);
5365 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5366 MessageManager.formatMessage(
5367 "label.fetch_retrieve_from", new Object[]
5368 { src.getDbName() })));
5374 final DbSourceProxy[] dassource = otherdb
5375 .toArray(new DbSourceProxy[0]);
5377 DbSourceProxy src = otherdb.get(0);
5378 fetchr = new JMenuItem(MessageManager
5379 .formatMessage("label.fetch_all_param", new Object[]
5380 { src.getDbSource() }));
5381 fetchr.addActionListener(new ActionListener()
5384 public void actionPerformed(ActionEvent e)
5386 new Thread(new Runnable()
5392 boolean isNucleotide = alignPanel.alignFrame
5393 .getViewport().getAlignment()
5395 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5396 alignPanel.av.getSequenceSelection(),
5397 alignPanel.alignFrame, dassource,
5398 alignPanel.alignFrame.featureSettings,
5401 .addListener(new FetchFinishedListenerI()
5404 public void finished()
5406 AlignFrame.this.setMenusForViewport();
5409 dbRefFetcher.fetchDBRefs(false);
5415 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5416 MessageManager.formatMessage(
5417 "label.fetch_retrieve_from_all_sources",
5419 { Integer.valueOf(otherdb.size())
5421 src.getDbSource(), src.getDbName() })));
5424 // and then build the rest of the individual menus
5425 ifetch = new JMenu(MessageManager.formatMessage(
5426 "label.source_from_db_source", new Object[]
5427 { src.getDbSource() }));
5429 String imname = null;
5431 for (DbSourceProxy sproxy : otherdb)
5433 String dbname = sproxy.getDbName();
5434 String sname = dbname.length() > 5
5435 ? dbname.substring(0, 5) + "..."
5437 String msname = dbname.length() > 10
5438 ? dbname.substring(0, 10) + "..."
5442 imname = MessageManager
5443 .formatMessage("label.from_msname", new Object[]
5446 fetchr = new JMenuItem(msname);
5447 final DbSourceProxy[] dassrc = { sproxy };
5448 fetchr.addActionListener(new ActionListener()
5452 public void actionPerformed(ActionEvent e)
5454 new Thread(new Runnable()
5460 boolean isNucleotide = alignPanel.alignFrame
5461 .getViewport().getAlignment()
5463 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5464 alignPanel.av.getSequenceSelection(),
5465 alignPanel.alignFrame, dassrc,
5466 alignPanel.alignFrame.featureSettings,
5469 .addListener(new FetchFinishedListenerI()
5472 public void finished()
5474 AlignFrame.this.setMenusForViewport();
5477 dbRefFetcher.fetchDBRefs(false);
5483 fetchr.setToolTipText(
5484 "<html>" + MessageManager.formatMessage(
5485 "label.fetch_retrieve_from", new Object[]
5489 if (++icomp >= mcomp || i == (otherdb.size()))
5491 ifetch.setText(MessageManager.formatMessage(
5492 "label.source_to_target", imname, sname));
5494 ifetch = new JMenu();
5502 if (comp >= mcomp || dbi >= (dbclasses.length))
5504 dfetch.setText(MessageManager.formatMessage(
5505 "label.source_to_target", mname, dbclass));
5507 dfetch = new JMenu();
5520 * Left justify the whole alignment.
5523 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5525 AlignmentI al = viewport.getAlignment();
5527 viewport.firePropertyChange("alignment", null, al);
5531 * Right justify the whole alignment.
5534 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5536 AlignmentI al = viewport.getAlignment();
5538 viewport.firePropertyChange("alignment", null, al);
5542 public void setShowSeqFeatures(boolean b)
5544 showSeqFeatures.setSelected(b);
5545 viewport.setShowSequenceFeatures(b);
5552 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5553 * awt.event.ActionEvent)
5556 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5558 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5559 alignPanel.paintAlignment(false, false);
5566 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5570 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5572 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5573 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5581 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5582 * .event.ActionEvent)
5585 protected void showGroupConservation_actionPerformed(ActionEvent e)
5587 viewport.setShowGroupConservation(showGroupConservation.getState());
5588 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5595 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5596 * .event.ActionEvent)
5599 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5601 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5602 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5609 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5610 * .event.ActionEvent)
5613 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5615 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5616 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5620 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5622 showSequenceLogo.setState(true);
5623 viewport.setShowSequenceLogo(true);
5624 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5625 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5629 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5631 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5638 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5639 * .event.ActionEvent)
5642 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5644 if (avc.makeGroupsFromSelection())
5646 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5647 alignPanel.updateAnnotation();
5648 alignPanel.paintAlignment(true,
5649 viewport.needToUpdateStructureViews());
5653 public void clearAlignmentSeqRep()
5655 // TODO refactor alignmentseqrep to controller
5656 if (viewport.getAlignment().hasSeqrep())
5658 viewport.getAlignment().setSeqrep(null);
5659 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5660 alignPanel.updateAnnotation();
5661 alignPanel.paintAlignment(true, true);
5666 protected void createGroup_actionPerformed(ActionEvent e)
5668 if (avc.createGroup())
5670 if (applyAutoAnnotationSettings.isSelected())
5672 alignPanel.updateAnnotation(true, false);
5674 alignPanel.alignmentChanged();
5679 protected void unGroup_actionPerformed(ActionEvent e)
5683 alignPanel.alignmentChanged();
5688 * make the given alignmentPanel the currently selected tab
5690 * @param alignmentPanel
5692 public void setDisplayedView(AlignmentPanel alignmentPanel)
5694 if (!viewport.getSequenceSetId()
5695 .equals(alignmentPanel.av.getSequenceSetId()))
5697 throw new Error(MessageManager.getString(
5698 "error.implementation_error_cannot_show_view_alignment_frame"));
5700 if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
5701 .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
5703 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5708 * Action on selection of menu options to Show or Hide annotations.
5711 * @param forSequences
5712 * update sequence-related annotations
5713 * @param forAlignment
5714 * update non-sequence-related annotations
5717 public void setAnnotationsVisibility(boolean visible,
5718 boolean forSequences, boolean forAlignment)
5720 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5721 .getAlignmentAnnotation();
5726 for (AlignmentAnnotation aa : anns)
5729 * don't display non-positional annotations on an alignment
5731 if (aa.annotations == null)
5735 boolean apply = (aa.sequenceRef == null && forAlignment)
5736 || (aa.sequenceRef != null && forSequences);
5739 aa.visible = visible;
5742 alignPanel.validateAnnotationDimensions(true);
5743 alignPanel.alignmentChanged();
5747 * Store selected annotation sort order for the view and repaint.
5750 protected void sortAnnotations_actionPerformed()
5752 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5754 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5755 alignPanel.paintAlignment(false, false);
5760 * @return alignment panels in this alignment frame
5762 public List<? extends AlignmentViewPanel> getAlignPanels()
5764 // alignPanels is never null
5765 // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5770 * Open a new alignment window, with the cDNA associated with this (protein)
5771 * alignment, aligned as is the protein.
5773 protected void viewAsCdna_actionPerformed()
5775 // TODO no longer a menu action - refactor as required
5776 final AlignmentI alignment = getViewport().getAlignment();
5777 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5778 if (mappings == null)
5782 List<SequenceI> cdnaSeqs = new ArrayList<>();
5783 for (SequenceI aaSeq : alignment.getSequences())
5785 for (AlignedCodonFrame acf : mappings)
5787 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5791 * There is a cDNA mapping for this protein sequence - add to new
5792 * alignment. It will share the same dataset sequence as other mapped
5793 * cDNA (no new mappings need to be created).
5795 final Sequence newSeq = new Sequence(dnaSeq);
5796 newSeq.setDatasetSequence(dnaSeq);
5797 cdnaSeqs.add(newSeq);
5801 if (cdnaSeqs.size() == 0)
5803 // show a warning dialog no mapped cDNA
5806 AlignmentI cdna = new Alignment(
5807 cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
5808 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5809 AlignFrame.DEFAULT_HEIGHT);
5810 cdna.alignAs(alignment);
5811 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5813 Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
5814 AlignFrame.DEFAULT_HEIGHT);
5818 * Set visibility of dna/protein complement view (available when shown in a
5824 protected void showComplement_actionPerformed(boolean show)
5826 SplitContainerI sf = getSplitViewContainer();
5829 sf.setComplementVisible(this, show);
5834 * Generate the reverse (optionally complemented) of the selected sequences,
5835 * and add them to the alignment
5838 protected void showReverse_actionPerformed(boolean complement)
5840 AlignmentI al = null;
5843 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5844 al = dna.reverseCdna(complement);
5845 viewport.addAlignment(al, "");
5846 addHistoryItem(new EditCommand(
5847 MessageManager.getString("label.add_sequences"), Action.PASTE,
5848 al.getSequencesArray(), 0, al.getWidth(),
5849 viewport.getAlignment()));
5850 } catch (Exception ex)
5852 System.err.println(ex.getMessage());
5858 * Try to run a script in the Groovy console, having first ensured that this
5859 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5860 * be targeted at this alignment.
5863 protected void runGroovy_actionPerformed()
5865 Jalview.setCurrentAlignFrame(this);
5866 groovy.ui.Console console = Desktop.getGroovyConsole();
5867 if (console != null)
5871 console.runScript();
5872 } catch (Exception ex)
5874 System.err.println((ex.toString()));
5875 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
5876 MessageManager.getString("label.couldnt_run_groovy_script"),
5877 MessageManager.getString("label.groovy_support_failed"),
5878 JvOptionPane.ERROR_MESSAGE);
5883 System.err.println("Can't run Groovy script as console not found");
5888 * Hides columns containing (or not containing) a specified feature, provided
5889 * that would not leave all columns hidden
5891 * @param featureType
5892 * @param columnsContaining
5895 public boolean hideFeatureColumns(String featureType,
5896 boolean columnsContaining)
5898 boolean notForHiding = avc.markColumnsContainingFeatures(
5899 columnsContaining, false, false, featureType);
5902 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5903 false, featureType))
5905 getViewport().hideSelectedColumns();
5913 protected void selectHighlightedColumns_actionPerformed(
5914 ActionEvent actionEvent)
5916 // include key modifier check in case user selects from menu
5917 avc.markHighlightedColumns(
5918 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
5919 (actionEvent.getModifiers() & (ActionEvent.META_MASK
5920 | ActionEvent.CTRL_MASK)) != 0);
5924 protected void copyHighlightedColumns_actionPerformed(
5925 ActionEvent actionEvent)
5927 avc.copyHighlightedRegionsToClipboard();
5931 * Rebuilds the Colour menu, including any user-defined colours which have
5932 * been loaded either on startup or during the session
5934 public void buildColourMenu()
5936 colourMenu.removeAll();
5938 colourMenu.add(applyToAllGroups);
5939 colourMenu.add(textColour);
5940 colourMenu.addSeparator();
5942 ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
5943 viewport.getAlignment(), false);
5945 colourMenu.add(annotationColour);
5946 bg.add(annotationColour);
5947 colourMenu.addSeparator();
5948 colourMenu.add(conservationMenuItem);
5949 colourMenu.add(modifyConservation);
5950 colourMenu.add(abovePIDThreshold);
5951 colourMenu.add(modifyPID);
5953 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5954 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5958 * Open a dialog (if not already open) that allows the user to select and
5959 * calculate PCA or Tree analysis
5961 protected void openTreePcaDialog()
5963 if (alignPanel.getCalculationDialog() == null)
5965 new CalculationChooser(AlignFrame.this);
5970 protected void loadVcf_actionPerformed()
5972 JalviewFileChooser chooser = new JalviewFileChooser(
5973 Cache.getProperty("LAST_DIRECTORY"));
5974 chooser.setFileView(new JalviewFileView());
5975 chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
5976 chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
5977 final AlignFrame us = this;
5978 chooser.setResponseHandler(0, () -> {
5979 String choice = chooser.getSelectedFile().getPath();
5980 Cache.setProperty("LAST_DIRECTORY", choice);
5981 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
5982 new VCFLoader(choice).loadVCF(seqs, us);
5985 chooser.showOpenDialog(null);
5989 private Rectangle lastFeatureSettingsBounds = null;
5992 public void setFeatureSettingsGeometry(Rectangle bounds)
5994 lastFeatureSettingsBounds = bounds;
5998 public Rectangle getFeatureSettingsGeometry()
6000 return lastFeatureSettingsBounds;
6005 class PrintThread extends Thread
6009 public PrintThread(AlignmentPanel ap)
6014 static PageFormat pf;
6019 PrinterJob printJob = PrinterJob.getPrinterJob();
6023 printJob.setPrintable(ap, pf);
6027 printJob.setPrintable(ap);
6030 if (printJob.printDialog())
6035 } catch (Exception PrintException)
6037 PrintException.printStackTrace();