label.settings_for_param = Settings for {0}
label.view_params = View {0}
label.select_all_views = Select all views
+label.all_views = All Views
label.align_sequences_to_existing_alignment = Align sequences to an existing alignment
label.realign_with_params = Realign with {0}
label.calcname_with_default_settings = {0} with Defaults
*/
package jalview.analysis;
-import java.util.*;
-
-import jalview.datamodel.*;
-import jalview.util.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.QuickSort;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* Routines for manipulating the order of a multiple sequence alignment TODO:
* @param tmp
* sequences as a vector
*/
- private static void setOrder(AlignmentI align, Vector tmp)
+ private static void setOrder(AlignmentI align, List<SequenceI> tmp)
{
setOrder(align, vectorSubsetToArray(tmp, align.getSequences()));
}
{
// MAINTAINS ORIGNAL SEQUENCE ORDER,
// ORDERS BY GROUP SIZE
- Vector groups = new Vector();
+ List<SequenceGroup> groups = new ArrayList<SequenceGroup>();
if (groups.hashCode() != lastGroupHash)
{
{
for (int j = 0; j < groups.size(); j++)
{
- SequenceGroup sg2 = (SequenceGroup) groups.elementAt(j);
+ SequenceGroup sg2 = groups.get(j);
if (sg.getSize() > sg2.getSize())
{
- groups.insertElementAt(sg, j);
+ groups.add(j, sg);
break;
}
if (!groups.contains(sg))
{
- groups.addElement(sg);
+ groups.add(sg);
}
}
// NOW ADD SEQUENCES MAINTAINING ALIGNMENT ORDER
// /////////////////////////////////////////////
- Vector seqs = new Vector();
+ List<SequenceI> seqs = new ArrayList<SequenceI>();
for (int i = 0; i < groups.size(); i++)
{
- SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
+ SequenceGroup sg = groups.get(i);
SequenceI[] orderedseqs = sg.getSequencesInOrder(align);
for (int j = 0; j < orderedseqs.length; j++)
{
- seqs.addElement(orderedseqs[j]);
+ seqs.add(orderedseqs[j]);
}
}
}
/**
- * Converts Vector to array. java 1.18 does not have Vector.toArray()
- *
- * @param tmp
- * Vector of SequenceI objects
- *
- * @return array of Sequence[]
- */
- private static SequenceI[] vectorToArray(Vector tmp)
- {
- SequenceI[] seqs = new SequenceI[tmp.size()];
-
- for (int i = 0; i < tmp.size(); i++)
- {
- seqs[i] = (SequenceI) tmp.elementAt(i);
- }
-
- return seqs;
- }
-
- /**
* Select sequences in order from tmp that is present in mask, and any
- * remaining seqeunces in mask not in tmp
+ * remaining sequences in mask not in tmp
*
* @param tmp
* thread safe collection of sequences
private static SequenceI[] vectorSubsetToArray(List<SequenceI> tmp,
List<SequenceI> mask)
{
+ // or?
+ // tmp2 = tmp.retainAll(mask);
+ // return tmp2.addAll(mask.removeAll(tmp2))
+
ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
int i, idx;
boolean[] tmask = new boolean[mask.size()];
public static void sortBy(AlignmentI align, AlignmentOrder order)
{
// Get an ordered vector of sequences which may also be present in align
- Vector tmp = order.getOrder();
+ List<SequenceI> tmp = order.getOrder();
if (lastOrder == order)
{
*
* @return DOCUMENT ME!
*/
- private static Vector getOrderByTree(AlignmentI align, NJTree tree)
+ private static List<SequenceI> getOrderByTree(AlignmentI align,
+ NJTree tree)
{
int nSeq = align.getHeight();
- Vector tmp = new Vector();
+ List<SequenceI> tmp = new ArrayList<SequenceI>();
tmp = _sortByTree(tree.getTopNode(), tmp, align.getSequences());
*/
public static void sortByTree(AlignmentI align, NJTree tree)
{
- Vector tmp = getOrderByTree(align, tree);
+ List<SequenceI> tmp = getOrderByTree(align, tree);
// tmp should properly permute align with tree.
if (lastTree != tree)
*
* @param align
* DOCUMENT ME!
- * @param seqs
+ * @param tmp
* DOCUMENT ME!
*/
- private static void addStrays(AlignmentI align, Vector seqs)
+ private static void addStrays(AlignmentI align, List<SequenceI> tmp)
{
int nSeq = align.getHeight();
for (int i = 0; i < nSeq; i++)
{
- if (!seqs.contains(align.getSequenceAt(i)))
+ if (!tmp.contains(align.getSequenceAt(i)))
{
- seqs.addElement(align.getSequenceAt(i));
+ tmp.add(align.getSequenceAt(i));
}
}
- if (nSeq != seqs.size())
+ if (nSeq != tmp.size())
{
System.err
.println("ERROR: Size still not right even after addStrays");
*
* @return DOCUMENT ME!
*/
- private static Vector _sortByTree(SequenceNode node, Vector tmp,
+ private static List<SequenceI> _sortByTree(SequenceNode node,
+ List<SequenceI> tmp,
List<SequenceI> seqset)
{
if (node == null)
// seqset.size()==0 ||
// seqset.contains(tmp)))
{
- tmp.addElement(node.element());
+ tmp.add((SequenceI) node.element());
}
}
}
/**
* Align sequence 'alignTo' the same way as 'alignFrom', using the mapping to
- * match residues and codons.
+ * match residues and codons. Flags control whether existing gaps in unmapped
+ * (intron) and mapped (exon) regions are preserved or not. Gaps linking intro
+ * and exon are only retained if both flags are set.
*
* @param alignTo
* @param alignFrom
/*
* Traverse the aligned protein sequence.
*/
- int sourceGapLength = 0;
+ int sourceGapMappedLength = 0;
+ boolean inExon = false;
for (char sourceChar : thatAligned)
{
if (sourceChar == sourceGap)
{
- sourceGapLength++;
+ sourceGapMappedLength += ratio;
continue;
}
int mappedCodonStart = mappedPos[0]; // position (1...) of codon start
int mappedCodonEnd = mappedPos[mappedPos.length - 1]; // codon end pos
- int trailingCopiedGapLength = 0;
+ StringBuilder trailingCopiedGap = new StringBuilder();
/*
* Copy dna sequence up to and including this codon. Optionally, include
* Note this only works for 'linear' splicing, not reverse or interleaved.
* But then 'align dna as protein' doesn't make much sense otherwise.
*/
- boolean inCodon = false;
+ int intronLength = 0;
while (basesWritten < mappedCodonEnd && thisSeqPos < thisSeq.length)
{
final char c = thisSeq[thisSeqPos++];
{
basesWritten++;
- /*
- * Is this the start of the mapped codon? If so, add in any extra gap
- * due to the protein alignment.
- */
- if (basesWritten == mappedCodonStart)
+ if (basesWritten < mappedCodonStart)
{
- inCodon = true;
- int gapsToAdd = Math.max(0, ratio * sourceGapLength
- - trailingCopiedGapLength);
+ /*
+ * Found an unmapped (intron) base. First add in any preceding gaps
+ * (if wanted).
+ */
+ if (preserveUnmappedGaps && trailingCopiedGap.length() > 0)
+ {
+ thisAligned.append(trailingCopiedGap.toString());
+ intronLength += trailingCopiedGap.length();
+ trailingCopiedGap = new StringBuilder();
+ }
+ intronLength++;
+ inExon = false;
+ }
+ else
+ {
+ final boolean startOfCodon = basesWritten == mappedCodonStart;
+ int gapsToAdd = calculateGapsToInsert(preserveMappedGaps,
+ preserveUnmappedGaps, sourceGapMappedLength, inExon,
+ trailingCopiedGap.length(), intronLength, startOfCodon);
for (int i = 0; i < gapsToAdd; i++)
{
thisAligned.append(myGapChar);
}
- sourceGapLength = 0;
+ sourceGapMappedLength = 0;
+ inExon = true;
}
thisAligned.append(c);
- trailingCopiedGapLength = 0;
+ trailingCopiedGap = new StringBuilder();
}
- else if ((!inCodon && preserveUnmappedGaps)
- || (inCodon && preserveMappedGaps))
+ else
{
- thisAligned.append(c);
- trailingCopiedGapLength++;
+ if (inExon && preserveMappedGaps)
+ {
+ trailingCopiedGap.append(myGapChar);
+ }
+ else if (!inExon && preserveUnmappedGaps)
+ {
+ trailingCopiedGap.append(myGapChar);
+ }
}
}
-
- /*
- * Expand (if necessary) the trailing gap to the size of the aligned gap.
- */
- int gapsToAdd = (ratio * sourceGapLength - trailingCopiedGapLength);
- for (int i = 0; i < gapsToAdd; i++)
- {
- thisAligned.append(myGapChar);
- }
}
/*
*/
alignTo.setSequence(new String(thisAligned));
}
+
+ /**
+ * Helper method to work out how many gaps to insert when realigning.
+ *
+ * @param preserveMappedGaps
+ * @param preserveUnmappedGaps
+ * @param sourceGapMappedLength
+ * @param inExon
+ * @param trailingCopiedGap
+ * @param intronLength
+ * @param startOfCodon
+ * @return
+ */
+ protected static int calculateGapsToInsert(boolean preserveMappedGaps,
+ boolean preserveUnmappedGaps, int sourceGapMappedLength,
+ boolean inExon, int trailingGapLength,
+ int intronLength, final boolean startOfCodon)
+ {
+ int gapsToAdd = 0;
+ if (startOfCodon)
+ {
+ /*
+ * Reached start of codon. Ignore trailing gaps in intron unless we are
+ * preserving gaps in both exon and intron. Ignore them anyway if the
+ * protein alignment introduces a gap at least as large as the intronic
+ * region.
+ */
+ if (inExon && !preserveMappedGaps)
+ {
+ trailingGapLength = 0;
+ }
+ if (!inExon && !(preserveMappedGaps && preserveUnmappedGaps))
+ {
+ trailingGapLength = 0;
+ }
+ if (inExon)
+ {
+ gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength);
+ }
+ else
+ {
+ if (intronLength + trailingGapLength <= sourceGapMappedLength)
+ {
+ gapsToAdd = sourceGapMappedLength - intronLength;
+ }
+ else
+ {
+ gapsToAdd = Math.min(intronLength + trailingGapLength
+ - sourceGapMappedLength, trailingGapLength);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * second or third base of codon; check for any gaps in dna
+ */
+ if (!preserveMappedGaps)
+ {
+ trailingGapLength = 0;
+ }
+ gapsToAdd = Math.max(sourceGapMappedLength, trailingGapLength);
+ }
+ return gapsToAdd;
+ }
}
*/
package jalview.api;
-import java.awt.Color;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
import jalview.analysis.Conservation;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeI;
+import java.awt.Color;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
/**
* @author jimp
*
List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
boolean selectedOnly);
+ /**
+ * Returns a viewport which is a 'slave of' this one i.e. updated in
+ * tandem in some sense, or null if none is set.
+ *
+ * @return
+ */
+ AlignViewportI getSlave();
+
+ void setSlave(AlignViewportI sl);
}
private static FeatureFetcher startFeatureFetching(final Vector dasSources)
{
FeatureFetcher ff = new FeatureFetcher();
- AlignFrame afs[] = Desktop.getAlignframes();
+ AlignFrame afs[] = Desktop.getAlignFrames();
if (afs == null || afs.length == 0)
{
return null;
{
public enum Action
{
- INSERT_GAP, DELETE_GAP, CUT, PASTE, REPLACE, INSERT_NUC
+ INSERT_GAP()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return DELETE_GAP;
+ }
+ },
+ DELETE_GAP()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return INSERT_GAP;
+ }
+ },
+ CUT()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return PASTE;
+ }
+ },
+ PASTE()
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return CUT;
+ }
+ },
+ REPLACE
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return REPLACE;
+ }
+ },
+ INSERT_NUC
+ {
+ @Override
+ public Action getUndoAction()
+ {
+ return null;
+ }
+ };
+ public abstract Action getUndoAction();
};
private List<Edit> edits = new ArrayList<Edit>();
if (command.seqs[i].getLength() < 1)
{
// ie this sequence was deleted, we need to
- // read it to the alignment
+ // readd it to the alignment
if (command.alIndex[i] < command.al.getHeight())
{
List<SequenceI> sequences;
}
else
{
- throw new IllegalStateException("Can't undo edit action " + action);
+ System.err.println("Can't undo edit action " + action);
+ // throw new IllegalStateException("Can't undo edit action " +
+ // action);
}
}
}
*/
package jalview.commands;
-import jalview.analysis.*;
-import jalview.datamodel.*;
+import jalview.analysis.AlignmentSorter;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+/**
+ * An undoable command to reorder the sequences in an alignment.
+ *
+ * @author gmcarstairs
+ *
+ */
public class OrderCommand implements CommandI
{
String description;
+ /*
+ * The sequence order before sorting (target order for an undo)
+ */
SequenceI[] seqs;
+ /*
+ * The sequence order specified by this command
+ */
SequenceI[] seqs2;
+ /*
+ * The alignment the command acts on
+ */
AlignmentI al;
+ /**
+ * Constructor given the 'undo' sequence order, and the (already) sorted
+ * alignment.
+ *
+ * @param description
+ * a text label for the 'undo' menu option
+ * @param seqs
+ * the sequence order for undo
+ * @param al
+ * the alignment as ordered by this command
+ */
public OrderCommand(String description, SequenceI[] seqs, AlignmentI al)
{
this.description = description;
{
AlignmentSorter.setOrder(al, seqs);
}
+
+ /**
+ * Returns the sequence order used to sort, or before sorting if undo=true.
+ *
+ * @param undo
+ * @return
+ */
+ public SequenceI[] getSequenceOrder(boolean undo)
+ {
+ return undo ? seqs : seqs2;
+ }
}
}
/**
+ * Make a 'copy' alignment - sequences have new copies of features and
+ * annotations, but share the original dataset sequences.
+ */
+ public Alignment(AlignmentI al)
+ {
+ SequenceI[] seqs = al.getSequencesArray();
+ for (int i = 0; i < seqs.length; i++)
+ {
+ seqs[i] = new Sequence(seqs[i]);
+ }
+ initAlignment(seqs);
+ }
+
+ /**
* Make an alignment from an array of Sequences.
*
* @param sequences
return dataset;
}
+ /**
+ * Align this alignment like the given (mapped) one.
+ */
@Override
public int alignAs(AlignmentI al)
{
- return alignAs(al, true, true);
+ /*
+ * Currently retains unmapped gaps (in introns), regaps mapped regions
+ * (exons)
+ */
+ return alignAs(al, false, true);
}
/**
* nucleotide bases. Does nothing if alignment of protein from cDNA is
* requested (not yet implemented).
*
+ * Parameters control whether gaps in exon (mapped) and intron (unmapped)
+ * regions are preserved. Gaps that connect introns to exons are treated
+ * conservatively, i.e. only preserved if both intron and exon gaps are
+ * preserved.
+ *
* @param al
+ * @param preserveMappedGaps
+ * if true, gaps within and between mapped codons are preserved
+ * @param preserveUnmappedGaps
+ * if true, gaps within and between unmapped codons are preserved
*/
// @Override
public int alignAs(AlignmentI al, boolean preserveMappedGaps,
*/
package jalview.datamodel;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class AlignmentOrder
{
private String Name;
- private Vector Order = null;
+ private List<SequenceI> Order = null;
/**
* Creates a new AlignmentOrder object.
* AlignmentOrder
*
* @param anOrder
- * Vector
*/
- public AlignmentOrder(Vector anOrder)
+ public AlignmentOrder(List<SequenceI> anOrder)
{
Order = anOrder;
}
*/
public AlignmentOrder(AlignmentI orderFrom)
{
- Order = new Vector();
+ Order = new ArrayList<SequenceI>();
- for (int i = 0, ns = orderFrom.getHeight(); i < ns; i++)
+ for (SequenceI seq : orderFrom.getSequences())
{
- Order.addElement(orderFrom.getSequenceAt(i));
+ Order.add(seq);
}
}
*/
public AlignmentOrder(SequenceI[] orderFrom)
{
- Order = new Vector();
-
- for (int i = 0, ns = orderFrom.length; i < ns; i++)
- {
- Order.addElement(orderFrom[i]);
- }
+ Order = new ArrayList<SequenceI>(Arrays.asList(orderFrom));
}
/**
* @param Order
* DOCUMENT ME!
*/
- public void setOrder(Vector Order)
+ public void setOrder(List<SequenceI> Order)
{
this.Order = Order;
}
*
* @return DOCUMENT ME!
*/
- public Vector getOrder()
+ public List<SequenceI> getOrder()
{
return Order;
}
int found = Order.indexOf(oldref);
if (found > -1)
{
- Order.setElementAt(newref, found);
+ Order.set(found, newref);
}
return found > -1;
}
* @param o
* @return true if o orders the same sequenceI objects in the same way
*/
- public boolean equals(AlignmentOrder o)
+ @Override
+ public boolean equals(Object o)
{
- return equals(o, true);
+ if (o == null || !(o instanceof AlignmentOrder))
+ {
+ return false;
+ }
+ return equals((AlignmentOrder) o, true);
}
/**
{
for (int i = 0, j = o.Order.size(); i < j; i++)
{
- if (Order.elementAt(i) != o.Order.elementAt(i))
+ if (Order.get(i) != o.Order.get(i))
{
return false;
}
}
if (Order != null && o.Order != null)
{
- Vector c, s;
+ List<SequenceI> c, s;
if (o.Order.size() > Order.size())
{
c = o.Order;
int last = -1;
for (int i = 0, j = s.size(); i < j; i++)
{
- int pos = c.indexOf(s.elementAt(i)); // JBPNote - optimize by
+ int pos = c.indexOf(s.get(i)); // JBPNote - optimize by
// incremental position search
if (pos > last)
{
import java.awt.Color;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
{
if (seqsel != null)
{
- sequences = new Vector();
- Enumeration<SequenceI> sq = seqsel.sequences.elements();
- while (sq.hasMoreElements())
+ for (SequenceI seq : seqsel.sequences)
{
- sequences.addElement(sq.nextElement());
+ sequences.addElement(seq);
}
- ;
if (seqsel.groupName != null)
{
groupName = new String(seqsel.groupName);
{
SequenceGroup sgroup = new SequenceGroup(this);
SequenceI[] insect = getSequencesInOrder(alignment);
- sgroup.sequences = new Vector();
- for (int s = 0; insect != null && s < insect.length; s++)
+ sgroup.sequences = new Vector<SequenceI>();
+ if (insect != null)
{
- if (map == null || map.containsKey(insect[s]))
+ for (SequenceI seq : insect)
{
- sgroup.sequences.addElement(insect[s]);
+ if (map == null || map.containsKey(seq))
+ {
+ sgroup.sequences.addElement(seq);
+ }
}
}
// Enumeration en =getSequences(hashtable).elements();
import jalview.analysis.Conservation;
import jalview.analysis.CrossRef;
import jalview.analysis.Dna;
-import jalview.analysis.NJTree;
import jalview.analysis.ParseProperties;
import jalview.analysis.SequenceIdMatcher;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.api.analysis.ScoreModelI;
import jalview.bin.Cache;
public AlignViewControllerI avc;
- Vector alignPanels = new Vector();
+ List<AlignmentPanel> alignPanels = new ArrayList<AlignmentPanel>();
/**
* Last format used to load or save alignments in this window
avc = new jalview.controller.AlignViewController(this, viewport,
alignPanel);
- alignPanels.addElement(ap);
+ alignPanels.add(ap);
PaintRefresher.Register(ap, ap.av.getSequenceSetId());
expandViews.setEnabled(true);
gatherViews.setEnabled(true);
tabbedPane.setVisible(true);
- AlignmentPanel first = (AlignmentPanel) alignPanels.firstElement();
+ AlignmentPanel first = alignPanels.get(0);
tabbedPane.addTab(first.av.viewName, first);
this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
}
int alreadyLinkedCount = 0;
final AlignmentI thisAlignment = this.alignPanel.getAlignment();
- for (AlignFrame af : Desktop.getAlignframes())
+ for (AlignFrame af : Desktop.getAlignFrames())
{
if (af.alignPanel != null)
{
int seqCount = 0;
int alignCount = 0;
final AlignmentI thisAlignment = this.alignPanel.getAlignment();
- for (AlignFrame af : Desktop.getAlignframes())
+ for (AlignFrame af : Desktop.getAlignFrames())
{
if (af.alignPanel != null)
{
// setClosed(true) is called
for (int i = 0; i < alignPanels.size(); i++)
{
- AlignmentPanel ap = (AlignmentPanel) alignPanels.elementAt(i);
+ AlignmentPanel ap = alignPanels.get(i);
ap.closePanel();
}
}
{
int index = tabbedPane.getSelectedIndex();
int closedindex = tabbedPane.indexOfComponent(alignPanel2);
- alignPanels.removeElement(alignPanel2);
+ alignPanels.remove(alignPanel2);
// Unnecessary
// if (viewport == alignPanel2.av)
// {
{
if (alignPanels != null)
{
- Enumeration e = alignPanels.elements();
AlignmentI[] als = new AlignmentI[alignPanels.size()];
- for (int i = 0; e.hasMoreElements(); i++)
+ int i = 0;
+ for (AlignmentPanel ap : alignPanels)
{
- als[i] = ((AlignmentPanel) e.nextElement()).av.getAlignment();
+ als[i++] = ap.av.getAlignment();
}
return als;
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
viewport.getHiddenRepSequences(), up);
alignPanel.paintAlignment(true);
+
+ final AlignViewportI slave = viewport.getSlave();
+ if (slave != null)
+ {
+ final SequenceGroup selectionGroup = viewport.getSlave()
+ .getSelectionGroup();
+ if (selectionGroup != null)
+ {
+ viewport.getSlave()
+ .getAlignment()
+ .moveSelectedSequencesByOne(
+ viewport.getSlave().getSelectionGroup(),
+ viewport.getSlave().getHiddenRepSequences(), up);
+ }
+ }
}
synchronized void slideSequences(boolean right, int size)
alignment.getSequences());
if (alignPanels != null)
{
- for (AlignmentPanel ap : ((Vector<AlignmentPanel>) alignPanels))
+ for (AlignmentPanel ap : alignPanels)
{
ap.validateAnnotationDimensions(false);
}
{
final TreePanel tp = (TreePanel) treePanels.elementAt(i);
final JMenuItem item = new JMenuItem(tp.getTitle());
- final NJTree tree = ((TreePanel) treePanels.elementAt(i)).getTree();
item.addActionListener(new java.awt.event.ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- tp.sortByTree_actionPerformed(null);
+ tp.sortByTree_actionPerformed();
addHistoryItem(tp.sortAlignmentIn(alignPanel));
}
{
if (index > -1)
{
- alignPanel = (AlignmentPanel) alignPanels.elementAt(index);
+ alignPanel = alignPanels.get(index);
viewport = alignPanel.av;
avc.setViewportAndAlignmentPanel(viewport, alignPanel);
setMenusFromViewport(viewport);
*
* @return alignment panels in this alignment frame
*/
- public List<AlignmentViewPanel> getAlignPanels()
+ public List<? extends AlignmentViewPanel> getAlignPanels()
{
return alignPanels == null ? Arrays.asList(alignPanel)
: alignPanels;
import jalview.api.AlignViewportI;
import jalview.bin.Cache;
import jalview.commands.CommandI;
-import jalview.commands.EditCommand;
+import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.PDBEntry;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Hashtable;
-import java.util.List;
import java.util.Set;
import java.util.Vector;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
-import javax.swing.JSplitPane;
/**
* DOCUMENT ME!
boolean showSeqFeaturesHeight;
+ /**
+ * Send the current selection to be broadcast to any selection listeners.
+ */
public void sendSelection()
{
jalview.structure.StructureSelectionManager
*/
@Override
public void mirrorCommand(CommandI command, boolean undo,
- StructureSelectionManager ssm)
+ StructureSelectionManager ssm, VamsasSource source)
{
/*
- * Only EditCommand is currently handled by listeners.
+ * ...work in progress... do nothing unless we are a 'slave' of the source
+ * May replace this with direct calls not via SSM.
*/
- if (!(command instanceof EditCommand))
+ if (source instanceof AlignViewportI
+ && ((AlignViewportI) source).getSlave() == this)
+ {
+ // ok to continue;
+ }
+ else
{
return;
}
- EditCommand edit = (EditCommand) command;
- List<SequenceI> seqs = getAlignment().getSequences();
- EditCommand mappedCommand = ssm.mapEditCommand(edit, undo, seqs,
+ CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(),
getGapCharacter());
- AlignmentI[] views = getAlignPanel().alignFrame.getViewAlignments();
- mappedCommand.performEdit(0, views);
- getAlignPanel().alignmentChanged();
+ if (mappedCommand != null)
+ {
+ AlignmentI[] views = getAlignPanel().alignFrame.getViewAlignments();
+ mappedCommand.doCommand(views);
+ getAlignPanel().alignmentChanged();
+ }
}
@Override
/**
* Add the sequences from the given alignment to this viewport. Optionally,
- * may give the user the option to open a new frame or panel linking cDNA and
- * protein.
+ * may give the user the option to open a new frame, or split panel, with cDNA
+ * and protein linked.
*
* @param al
* @param title
/**
* Show a dialog with the option to open and link (cDNA <-> protein) as a new
- * alignment. Returns true if the new alignment was opened, false if not -
- * either because the user declined the offer, or because no mapping could be
- * made.
+ * alignment. Returns true if the new alignment was opened, false if not,
+ * because the user declined the offer.
*
* @param title
*/
MessageManager.getString("label.open_linked_alignment"),
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
- // int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,
- // question,
- // MessageManager.getString("label.open_linked_alignment"),
- // JOptionPane.YES_NO_OPTION,
- // JOptionPane.QUESTION_MESSAGE);
if (response != 1 && response != 2)
{
* Create the AlignFrame first (which creates the new alignment's datasets),
* before attempting sequence mapping.
*/
- AlignFrame alignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame newAlignFrame = new AlignFrame(al, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
- final AlignmentI protein = al.isNucleotide() ? getAlignment() : al;
- final AlignmentI cdna = al.isNucleotide() ? al : getAlignment();
+ /*
+ * Identify protein and dna alignments. Make a copy of this one if opening
+ * in a new split pane.
+ */
+ AlignmentI thisAlignment = openSplitPane ? new Alignment(getAlignment())
+ : getAlignment();
+ final AlignmentI protein = al.isNucleotide() ? thisAlignment : al;
+ final AlignmentI cdna = al.isNucleotide() ? al : thisAlignment;
- alignFrame.statusBar.setText(MessageManager.formatMessage(
+ newAlignFrame.statusBar.setText(MessageManager.formatMessage(
"label.successfully_loaded_file", new Object[]
{ title }));
// {
// alignFrame.setFileName(file, format);
// }
+
if (openInNewWindow)
{
- /*
- * open in new window
- */
- Desktop.addInternalFrame(alignFrame, title, AlignFrame.DEFAULT_WIDTH,
+ Desktop.addInternalFrame(newAlignFrame, title,
+ AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
}
* Try to find mappings for at least one sequence.
*/
MappingResult mapped = AlignmentUtils.mapProteinToCdna(protein, cdna);
+ final StructureSelectionManager ssm = StructureSelectionManager
+ .getStructureSelectionManager(Desktop.instance);
if (mapped == MappingResult.Mapped)
{
* Register the mappings (held on the protein alignment) with the
* StructureSelectionManager (for mouseover linking).
*/
- final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
ssm.addMappings(protein.getCodonFrames());
-
- /*
- * Set the cDNA to listen for edits on the protein.
- */
- ssm.addCommandListener(al.isNucleotide() ? alignFrame.getViewport()
- : this);
}
else
{
try
{
- alignFrame.setMaximum(jalview.bin.Cache.getDefault("SHOW_FULLSCREEN",
+ newAlignFrame.setMaximum(jalview.bin.Cache.getDefault(
+ "SHOW_FULLSCREEN",
false));
} catch (java.beans.PropertyVetoException ex)
{
if (openSplitPane)
{
/*
- * Open in split pane. Original sequence above, new one below.
+ * Open in split pane. DNA sequence above, protein below.
*/
- JInternalFrame splitFrame = new JInternalFrame();
- splitFrame.setSize(AlignFrame.DEFAULT_WIDTH,
- AlignFrame.DEFAULT_HEIGHT);
- // TODO not quite right to 'move' AlignPanel from 'this' to the split
- // pane
- // TODO probably want linked editing set up here
- JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
- getAlignPanel(), alignFrame.alignPanel);
- splitPane.setDividerLocation(0.5d);
- splitFrame.setSize(AlignFrame.DEFAULT_WIDTH,
- AlignFrame.DEFAULT_HEIGHT);
- splitFrame.add(splitPane);
+ AlignFrame copyMe = new AlignFrame(thisAlignment,
+ AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
+ copyMe.setTitle(""); // TODO would like this AlignFrame.title here
+ final AlignFrame proteinFrame = al.isNucleotide() ? copyMe
+ : newAlignFrame;
+ final AlignFrame cdnaFrame = al.isNucleotide() ? newAlignFrame
+ : copyMe;
+ newAlignFrame.setTitle(title);
+
+ cdnaFrame.setVisible(true);
+ proteinFrame.setVisible(true);
+ JInternalFrame splitFrame = new SplitFrame(cdnaFrame, proteinFrame);
Desktop.addInternalFrame(splitFrame, title, AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
+
+ /*
+ * Set the cDNA to list for edits on the protein.
+ */
+ ssm.addCommandListener(cdnaFrame.getViewport());
+
+ /*
+ * cDNA is 'slaved' to edits, selection, sorting, show/hide on protein
+ */
+ proteinFrame.getViewport().setSlave(cdnaFrame.getViewport());
}
return true;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
*/
public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
{
- int count = 0;
if (Desktop.desktop == null)
{
// no frames created and in headless mode
// TODO: verify that frames are recoverable when in headless mode
return null;
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
- ArrayList aps = new ArrayList();
- for (int t = 0; t < frames.length; t++)
+ List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
+ AlignFrame[] frames = getAlignFrames();
+ if (frames == null)
+ {
+ return null;
+ }
+ for (AlignFrame af : frames)
{
- if (frames[t] instanceof AlignFrame)
+ for (AlignmentPanel ap : af.alignPanels)
{
- AlignFrame af = (AlignFrame) frames[t];
- for (int a = 0; a < af.alignPanels.size(); a++)
+ if (alignmentId.equals(ap.av.getSequenceSetId()))
{
- if (alignmentId.equals(((AlignmentPanel) af.alignPanels
- .elementAt(a)).av.getSequenceSetId()))
- {
- aps.add(af.alignPanels.elementAt(a));
- }
+ aps.add(ap);
}
}
+ // for (int a = 0; a < af.alignPanels.size(); a++)
+ // {
+ // if (alignmentId.equals(af.alignPanels
+ // .get(a).av.getSequenceSetId()))
+ // {
+ // aps.add(af.alignPanels.get(a));
+ // }
+ // }
}
if (aps.size() == 0)
{
return null;
}
- AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
- for (int t = 0; t < vap.length; t++)
- {
- vap[t] = (AlignmentPanel) aps.get(t);
- }
+ AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
return vap;
}
{
for (int a = 0; a < afr.alignPanels.size(); a++)
{
- if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
- .elementAt(a)).av.getSequenceSetId()))
+ if (sequenceSetId.equals(afr.alignPanels.get(a).av
+ .getSequenceSetId()))
{
- viewp.addElement(((AlignmentPanel) afr.alignPanels
- .elementAt(a)).av);
+ viewp.addElement(afr.alignPanels.get(a).av);
}
}
}
for (int i = 0; i < size; i++)
{
- AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
+ AlignmentPanel ap = af.alignPanels.get(i);
AlignFrame newaf = new AlignFrame(ap);
if (ap.av.explodedPosition != null
&& !ap.av.explodedPosition.equals(af.getBounds()))
boolean gatherThis = false;
for (int a = 0; a < af.alignPanels.size(); a++)
{
- AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
+ AlignmentPanel ap = af.alignPanels.get(a);
if (viewId.equals(ap.av.getSequenceSetId()))
{
gatherThis = true;
/**
* Accessor method to quickly get all the AlignmentFrames loaded.
*/
- public static AlignFrame[] getAlignframes()
+ public static AlignFrame[] getAlignFrames()
{
JInternalFrame[] frames = Desktop.desktop.getAllFrames();
{
return null;
}
- Vector avp = new Vector();
- try
+ List<AlignFrame> avp = new ArrayList<AlignFrame>();
+ // REVERSE ORDER
+ for (int i = frames.length - 1; i > -1; i--)
{
- // REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--)
+ if (frames[i] instanceof AlignFrame)
{
- if (frames[i] instanceof AlignFrame)
+ avp.add((AlignFrame) frames[i]);
+ }
+ else if (frames[i] instanceof SplitFrame)
+ {
+ /*
+ * Also check for a split frame containing an AlignFrame
+ */
+ SplitFrame sf = (SplitFrame) frames[i];
+ if (sf.getTopComponent() instanceof AlignFrame)
{
- AlignFrame af = (AlignFrame) frames[i];
- avp.addElement(af);
+ avp.add((AlignFrame) sf.getTopComponent());
+ }
+ if (sf.getBottomComponent() instanceof AlignFrame)
+ {
+ avp.add((AlignFrame) sf.getBottomComponent());
}
}
- } catch (Exception ex)
- {
- ex.printStackTrace();
}
if (avp.size() == 0)
{
return null;
}
- AlignFrame afs[] = new AlignFrame[avp.size()];
- for (int i = 0, j = avp.size(); i < j; i++)
- {
- afs[i] = (AlignFrame) avp.elementAt(i);
- }
- avp.clear();
+ AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
return afs;
}
+ /**
+ * Returns an array of any AppJmol frames in the Desktop (or null if none).
+ *
+ * @return
+ */
public AppJmol[] getJmols()
{
JInternalFrame[] frames = Desktop.desktop.getAllFrames();
{
return null;
}
- Vector avp = new Vector();
- try
+ List<AppJmol> avp = new ArrayList<AppJmol>();
+ // REVERSE ORDER
+ for (int i = frames.length - 1; i > -1; i--)
{
- // REVERSE ORDER
- for (int i = frames.length - 1; i > -1; i--)
+ if (frames[i] instanceof AppJmol)
{
- if (frames[i] instanceof AppJmol)
- {
- AppJmol af = (AppJmol) frames[i];
- avp.addElement(af);
- }
+ AppJmol af = (AppJmol) frames[i];
+ avp.add(af);
}
- } catch (Exception ex)
- {
- ex.printStackTrace();
}
if (avp.size() == 0)
{
return null;
}
- AppJmol afs[] = new AppJmol[avp.size()];
- for (int i = 0, j = avp.size(); i < j; i++)
- {
- afs[i] = (AppJmol) avp.elementAt(i);
- }
- avp.clear();
+ AppJmol afs[] = avp.toArray(new AppJmol[avp.size()]);
return afs;
}
/**
* This will return the first AlignFrame viewing AlignViewport av. It will
- * break if there are more than one AlignFrames viewing a particular av. This
+ * break if there are more than one AlignFrames viewing a particular av.
*
* @param av
* @return alignFrame for av
*/
package jalview.gui;
-import java.awt.*;
-import java.awt.image.*;
+import jalview.datamodel.SequenceI;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
import java.util.List;
-import javax.swing.*;
-
-import jalview.datamodel.*;
+import javax.swing.JPanel;
/**
* DOCUMENT ME!
for (ap = 0; ap < apSize; ap++)
{
- AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
- .elementAt(ap);
+ AlignmentPanel apanel = af.alignPanels.get(ap);
String fileName = apSize == 1 ? shortName : ap + shortName;
if (!fileName.endsWith(".xml"))
{
Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
for (ap = 0; ap < apSize; ap++)
{
- AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
- .elementAt(ap);
+ AlignmentPanel apanel = af.alignPanels
+ .get(ap);
String jfileName = apSize == 1 ? fileName : fileName + ap;
if (!jfileName.endsWith(".xml"))
{
}
int gsize = sg.getSize();
- SequenceI[] hseqs;
-
- hseqs = new SequenceI[gsize];
-
- int index = 0;
- for (int i = 0; i < gsize; i++)
- {
- hseqs[index++] = sg.getSequenceAt(i);
- }
+ SequenceI[] hseqs = sg.getSequences().toArray(new SequenceI[gsize]);
ap.av.hideSequence(hseqs);
// refresh(); TODO: ? needed ?
*/
package jalview.gui;
+import jalview.api.AlignViewportI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
import jalview.commands.EditCommand.Edit;
+import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SearchResults;
import jalview.datamodel.Sequence;
// handles selection messages...
// TODO: extend config options to allow user to control if selections may be
// shared between viewports.
- if (av == source
- || !av.followSelection
- || (av.isSelectionGroupChanged(false) || av
- .isColSelChanged(false))
+ boolean iSentTheSelection = (av == source
|| (source instanceof AlignViewport && ((AlignViewport) source)
- .getSequenceSetId().equals(av.getSequenceSetId())))
+ .getSequenceSetId().equals(av.getSequenceSetId())));
+ if (iSentTheSelection || !av.followSelection)
{
return;
}
+
+ /*
+ * Ignore the selection if there is one of our own pending.
+ */
+ if (av.isSelectionGroupChanged(false) || av.isColSelChanged(false))
+ {
+ return;
+ }
+
+ /*
+ * Check for selection in a view of which this one is a 'slave'.
+ */
+ if (selectionAsSlave(seqsel, colsel, source))
+ {
+ return;
+ }
+
// do we want to thread this ? (contention with seqsel and colsel locks, I
// suspect)
// rules are: colsel is copied if there is a real intersection between
// sequence selection
- boolean repaint = false, copycolsel = true;
- // if (!av.isSelectionGroupChanged(false))
+ boolean repaint = false;
+ boolean copycolsel = true;
+
+ SequenceGroup sgroup = null;
+ if (seqsel != null && seqsel.getSize() > 0)
{
- SequenceGroup sgroup = null;
- if (seqsel != null && seqsel.getSize() > 0)
- {
- if (av.getAlignment() == null)
- {
- jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
- + av.getSequenceSetId() + " ViewId=" + av.getViewId()
- + " 's alignment is NULL! returning immediatly.");
- return;
- }
- sgroup = seqsel.intersect(av.getAlignment(),
- (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
- if ((sgroup == null || sgroup.getSize() == 0)
- || (colsel == null || colsel.size() == 0))
- {
- // don't copy columns if the region didn't intersect.
- copycolsel = false;
- }
- }
- if (sgroup != null && sgroup.getSize() > 0)
+ if (av.getAlignment() == null)
{
- av.setSelectionGroup(sgroup);
+ jalview.bin.Cache.log.warn("alignviewport av SeqSetId="
+ + av.getSequenceSetId() + " ViewId=" + av.getViewId()
+ + " 's alignment is NULL! returning immediately.");
+ return;
}
- else
+ sgroup = seqsel.intersect(av.getAlignment(),
+ (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
+ if ((sgroup == null || sgroup.getSize() == 0)
+ || (colsel == null || colsel.size() == 0))
{
- av.setSelectionGroup(null);
+ // don't copy columns if the region didn't intersect.
+ copycolsel = false;
}
- av.isSelectionGroupChanged(true);
- repaint = true;
}
+ if (sgroup != null && sgroup.getSize() > 0)
+ {
+ av.setSelectionGroup(sgroup);
+ }
+ else
+ {
+ av.setSelectionGroup(null);
+ }
+ av.isSelectionGroupChanged(true);
+ repaint = true;
+
if (copycolsel)
{
// the current selection is unset or from a previous message
av.isColSelChanged(true);
repaint = true;
}
+
if (copycolsel
&& av.hasHiddenColumns()
&& (av.getColumnSelection() == null || av.getColumnSelection()
{
System.err.println("Bad things");
}
- if (repaint)
+ if (repaint) // always true!
{
// probably finessing with multiple redraws here
PaintRefresher.Refresh(this, av.getSequenceSetId());
// ap.paintAlignment(false);
}
}
+
+ /**
+ * If this panel is a 'slave' of the selection source, tries to map the source
+ * selection to a local one, and returns true. Else returns false.
+ *
+ * @param seqsel
+ * @param colsel
+ * @param source
+ */
+ protected boolean selectionAsSlave(SequenceGroup seqsel,
+ ColumnSelection colsel, SelectionSource source)
+ {
+ if (!(source instanceof AlignViewportI)) {
+ return false;
+ }
+ final AlignViewportI sourceAv = (AlignViewportI) source;
+ if (sourceAv.getSlave() != av)
+ {
+ return false;
+ }
+
+ /*
+ * Map sequence selection. Note the SequenceGroup holds aligned sequences,
+ * the mappings hold dataset sequences.
+ */
+ AlignedCodonFrame[] codonFrames = sourceAv.getAlignment()
+ .getCodonFrames();
+ SequenceGroup sg = new SequenceGroup();
+ for (SequenceI selected : seqsel.getSequences())
+ {
+ for (AlignedCodonFrame acf : codonFrames)
+ {
+ SequenceI dnaSeq = acf.getDnaForAaSeq(selected);
+ if (dnaSeq != null)
+ {
+ for (SequenceI seq : av.getAlignment().getSequences())
+ {
+ if (seq.getDatasetSequence() == dnaSeq)
+ {
+ sg.addSequence(seq, false);
+ break;
+ }
+ }
+ }
+ }
+ }
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+ // ((AlignmentViewport) slave).firePropertyChange("alignment", null, slave
+ // .getAlignment()
+ // .getSequences());
+
+ /*
+ * Map column selection
+ */
+ // TODO
+
+ AlignmentPanel ap = av.getAlignPanel();
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+
+ return true;
+ }
}
--- /dev/null
+package jalview.gui;
+
+import jalview.jbgui.GSplitFrame;
+
+import javax.swing.JComponent;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+public class SplitFrame extends GSplitFrame
+{
+ private static final long serialVersionUID = 1L;
+
+ public SplitFrame(JComponent top, JComponent bottom)
+ {
+ super(top, bottom);
+ init();
+ }
+
+ /**
+ * Initialise this frame.
+ */
+ protected void init()
+ {
+ setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 10);
+
+ /*
+ * Add a listener to tidy up when the frame is closed.
+ */
+ addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
+ if (getTopComponent() instanceof AlignFrame)
+ {
+ ((AlignFrame) getTopComponent())
+ .closeMenuItem_actionPerformed(true);
+ }
+ if (getBottomComponent() instanceof AlignFrame)
+ {
+ ((AlignFrame) getBottomComponent())
+ .closeMenuItem_actionPerformed(true);
+ }
+ };
+ });
+
+ }
+
+}
*/
package jalview.gui;
-import java.util.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.print.*;
-import javax.swing.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-import jalview.schemes.*;
-import jalview.util.*;
+import jalview.analysis.Conservation;
+import jalview.analysis.NJTree;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.schemes.ColourSchemeI;
+import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.ResidueProperties;
+import jalview.schemes.UserColourScheme;
+import jalview.structure.SelectionSource;
+import jalview.util.Format;
+import jalview.util.MappingUtils;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.awt.print.PrinterException;
+import java.awt.print.PrinterJob;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.JColorChooser;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
/**
* DOCUMENT ME!
* @version $Revision$
*/
public class TreeCanvas extends JPanel implements MouseListener, Runnable,
- Printable, MouseMotionListener
+ Printable, MouseMotionListener, SelectionSource
{
/** DOCUMENT ME!! */
public static final String PLACEHOLDER = " * ";
if (node.element() instanceof SequenceI)
{
- SequenceI seq = (SequenceI) ((SequenceNode) node).element();
+ SequenceI seq = (SequenceI) node.element();
if (av.getSequenceColour(seq) == Color.white)
{
Rectangle rect = new Rectangle(xend + 10, ypos - charHeight / 2,
charWidth, charHeight);
- nameHash.put((SequenceI) node.element(), rect);
+ nameHash.put(node.element(), rect);
// Colour selected leaves differently
SequenceGroup selected = av.getSelectionGroup();
if ((selected != null)
&& selected.getSequences(null).contains(
- (SequenceI) node.element()))
+ node.element()))
{
g.setColor(Color.gray);
int xend = (int) (height * scale) + offx;
int ypos = (int) (node.ycount * chunk) + offy;
- g.setColor(((SequenceNode) node).color.darker());
+ g.setColor(node.color.darker());
// Draw horizontal line
g.drawLine(xstart, ypos, xend, ypos);
{
for (int a = 0; a < aps.length; a++)
{
- aps[a].av.setSequenceColour((SequenceI) node.element(), c);
+ final SequenceI seq = (SequenceI) node.element();
+ aps[a].av.setSequenceColour(seq, c);
}
}
}
labelLength = fm.stringWidth(longestName) + 20; // 20 allows for scrollbar
- float wscale = (float) (width - labelLength - (offx * 2))
+ float wscale = (width - labelLength - (offx * 2))
/ tree.getMaxHeight();
SequenceNode top = tree.getTopNode();
g2.setColor(Color.gray);
}
- int x = (int) ((threshold * (float) (getWidth() - labelLength - (2 * offx))) + offx);
+ int x = (int) ((threshold * (getWidth() - labelLength - (2 * offx))) + offx);
g2.drawLine(x, 0, x, getHeight());
}
AlignmentPanel[] aps = getAssociatedPanels();
+ // TODO push calls below into a single AlignViewportI method?
+ // see also AlignViewController.deleteGroups
for (int a = 0; a < aps.length; a++)
{
aps[a].av.setSelectionGroup(null);
aps[a].av.getAlignment().deleteAllGroups();
aps[a].av.clearSequenceColours();
}
+ if (av.getSlave() != null)
+ {
+ av.getSlave().setSelectionGroup(null);
+ av.getSlave().getAlignment().deleteAllGroups();
+ av.getSlave().clearSequenceColours();
+ }
colourGroups();
}
// sg.recalcConservation();
sg.setName("JTreeGroup:" + sg.hashCode());
sg.setIdColour(col);
+
for (int a = 0; a < aps.length; a++)
{
if (aps[a].av.getGlobalColourScheme() != null
aps[a].av.getAlignment().addGroup(new SequenceGroup(sg));
}
+
+ // TODO can we push all of the below into AlignViewportI?
+ av.getAlignment().addGroup(sg);
+ if (av.getSlave() != null)
+ {
+ SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av,
+ av.getSlave());
+ if (mappedGroup.getSequences().size() > 0)
+ {
+ av.getSlave().getAlignment().addGroup(mappedGroup);
+ for (SequenceI seq : mappedGroup.getSequences())
+ {
+ av.getSlave().setSequenceColour(seq,
+ mappedGroup.getIdColour().brighter());
+ }
+ }
+ }
+
}
+
// notify the panel to redo any group specific stuff.
for (int a = 0; a < aps.length; a++)
{
// to any Jmols listening in
}
+ if (av.getSlave() != null)
+ {
+ ((AlignViewport) av.getSlave()).getAlignPanel().updateAnnotation();
+ /*
+ * idPanel. repaint ()
+ */
+ }
}
/**
*/
package jalview.gui;
-import java.beans.*;
-import java.io.*;
-import java.util.*;
-import java.util.List;
-
-import javax.imageio.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import javax.swing.*;
-
-import org.jibble.epsgraphics.*;
-import jalview.analysis.*;
+import jalview.analysis.AlignmentSorter;
+import jalview.analysis.NJTree;
import jalview.commands.CommandI;
import jalview.commands.OrderCommand;
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.jbgui.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.NodeTransformI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.io.NewickFile;
+import jalview.jbgui.GTreePanel;
import jalview.util.MessageManager;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+import javax.swing.ButtonGroup;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+
+import org.jibble.epsgraphics.EpsGraphics2D;
+
/**
* DOCUMENT ME!
*
associateLeavesMenu.add(item);
}
- final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views");
+ final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem(
+ MessageManager.getString("label.all_views"));
buttonGroup.add(itemf);
itemf.setSelected(treeCanvas.applyToAllViews);
itemf.addActionListener(new ActionListener()
av.setCurrentTree(tree);
if (av.getSortByTree())
{
- sortByTree_actionPerformed(null);
+ sortByTree_actionPerformed();
}
}
}
*
* @param e
*/
- public void sortByTree_actionPerformed(ActionEvent e)
+ @Override
+ public void sortByTree_actionPerformed()
{
if (treeCanvas.applyToAllViews)
*/
protected void updateWebServiceMenus()
{
- for (AlignFrame alignFrame : Desktop.getAlignframes())
+ for (AlignFrame alignFrame : Desktop.getAlignFrames())
{
alignFrame.BuildWebServiceMenu();
}
private void buildSkipList()
{
skipList = new Hashtable();
- AlignFrame[] al = Desktop.getAlignframes();
+ AlignFrame[] al = Desktop.getAlignFrames();
for (int f = 0; al != null && f < al.length; f++)
{
skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
--- /dev/null
+package jalview.jbgui;
+
+import javax.swing.JComponent;
+import javax.swing.JInternalFrame;
+import javax.swing.JSplitPane;
+
+public class GSplitFrame extends JInternalFrame
+{
+ private static final long serialVersionUID = 1L;
+
+ private JComponent topComponent;
+
+ private JComponent bottomComponent;
+
+ /**
+ * Constructor
+ *
+ * @param top
+ * @param bottom
+ */
+ public GSplitFrame(JComponent top, JComponent bottom)
+ {
+ this.topComponent = top;
+ this.bottomComponent = bottom;
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, top,
+ bottom);
+ splitPane.setVisible(true);
+ add(splitPane);
+ splitPane.setDividerLocation(0.5d);
+ splitPane.setResizeWeight(0.5d);
+ splitPane.setDividerSize(0);
+ }
+
+ public JComponent getTopComponent()
+ {
+ return topComponent;
+ }
+
+ public JComponent getBottomComponent()
+ {
+ return bottomComponent;
+ }
+}
import jalview.util.MessageManager;
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-import javax.swing.event.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JInternalFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
public class GTreePanel extends JInternalFrame
{
{
public void actionPerformed(ActionEvent e)
{
- sortByTree_actionPerformed(e);
+ sortByTree_actionPerformed();
}
});
font.setText(MessageManager.getString("action.font"));
{
}
- public void sortByTree_actionPerformed(ActionEvent e)
+ public void sortByTree_actionPerformed()
{
}
* @param command
* @param undo
* @param ssm
+ * @param source
+ * the originator of the command
*/
public void mirrorCommand(CommandI command, boolean undo,
- StructureSelectionManager ssm);
+ StructureSelectionManager ssm, VamsasSource source);
/**
* Temporary workaround to make check for source == listener work.
import jalview.api.StructureSelectionManagerProvider;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
-import jalview.commands.EditCommand.Action;
-import jalview.commands.EditCommand.Edit;
+import jalview.commands.OrderCommand;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
import jalview.datamodel.Annotation;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SearchResults;
-import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
+import jalview.util.MappingUtils;
import jalview.util.MessageManager;
-import jalview.util.StringUtils;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.IdentityHashMap;
-import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.Vector;
{
static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
- StructureMapping[] mappings;
+ private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
private boolean processSecondaryStructure = false;
private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
+ private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
+
/**
* @return true if will try to use external services for processing secondary
* structure
*/
public void reportMapping()
{
- if (mappings == null)
+ if (mappings.isEmpty())
{
System.err.println("reportMapping: No PDB/Sequence mappings.");
}
else
{
- System.err.println("reportMapping: There are " + mappings.length
+ System.err.println("reportMapping: There are " + mappings.size()
+ " mappings.");
- for (int m = 0; m < mappings.length; m++)
+ int i = 0;
+ for (StructureMapping sm : mappings)
{
- System.err.println("mapping " + m + " : " + mappings[m].pdbfile);
+ System.err.println("mapping " + i++ + " : " + sm.pdbfile);
}
}
}
}
}
+ /**
+ * Returns the file name for a mapped PDB id (or null if not mapped).
+ *
+ * @param pdbid
+ * @return
+ */
public String alreadyMappedToFile(String pdbid)
{
- if (mappings != null)
+ for (StructureMapping sm : mappings)
{
- for (int i = 0; i < mappings.length; i++)
+ if (sm.getPdbId().equals(pdbid))
{
- if (mappings[i].getPdbId().equals(pdbid))
- {
- return mappings[i].pdbfile;
- }
+ return sm.pdbfile;
}
}
return null;
mappingDetails.toString());
if (forStructureView)
{
-
- if (mappings == null)
- {
- mappings = new StructureMapping[1];
- }
- else
- {
- StructureMapping[] tmp = new StructureMapping[mappings.length + 1];
- System.arraycopy(mappings, 0, tmp, 0, mappings.length);
- mappings = tmp;
- }
-
- mappings[mappings.length - 1] = newMapping;
+ mappings.add(newMapping);
}
maxChain.transferResidueAnnotation(newMapping, sqmpping);
}
}
}
- if (pdbs.size() > 0 && mappings != null)
+ if (pdbs.size() > 0)
{
- Vector tmp = new Vector();
- for (int i = 0; i < mappings.length; i++)
+ List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ for (StructureMapping sm : mappings)
{
- if (!pdbs.contains(mappings[i].pdbfile))
+ if (!pdbs.contains(sm.pdbfile))
{
- tmp.addElement(mappings[i]);
+ tmp.add(sm);
}
}
- mappings = new StructureMapping[tmp.size()];
- tmp.copyInto(mappings);
+ mappings = tmp;
}
}
// old or prematurely sent event
return;
}
- boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
SearchResults results = null;
SequenceI lastseq = null;
int lastipos = -1, indexpos;
{
results = new SearchResults();
}
- if (mappings != null)
+ for (StructureMapping sm : mappings)
{
- for (int j = 0; j < mappings.length; j++)
+ if (sm.pdbfile.equals(pdbfile) && sm.pdbchain.equals(chain))
{
- if (mappings[j].pdbfile.equals(pdbfile)
- && mappings[j].pdbchain.equals(chain))
+ indexpos = sm.getSeqPos(pdbResNum);
+ if (lastipos != indexpos && lastseq != sm.sequence)
{
- indexpos = mappings[j].getSeqPos(pdbResNum);
- if (lastipos != indexpos && lastseq != mappings[j].sequence)
+ results.addResult(sm.sequence, indexpos, indexpos);
+ lastipos = indexpos;
+ lastseq = sm.sequence;
+ // construct highlighted sequence list
+ for (AlignedCodonFrame acf : seqmappings)
{
- results.addResult(mappings[j].sequence, indexpos, indexpos);
- lastipos = indexpos;
- lastseq = mappings[j].sequence;
- // construct highlighted sequence list
- if (seqmappings != null)
- {
- for (AlignedCodonFrame acf : seqmappings)
- {
- acf.markMappedRegion(mappings[j].sequence, indexpos,
- results);
- }
- }
+ acf.markMappedRegion(sm.sequence, indexpos, results);
}
}
}
public void mouseOverSequence(SequenceI seq, int indexpos, int index,
VamsasSource source)
{
- boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
+ boolean hasSequenceListeners = handlingVamsasMo
+ || !seqmappings.isEmpty();
SearchResults results = null;
if (index == -1)
{
{
if (results == null)
{
- results = buildSearchResults(seq, index);
+ results = MappingUtils.buildSearchResults(seq, index,
+ seqmappings);
+ }
+ if (handlingVamsasMo)
+ {
+ results.addResult(seq, index, index);
+
}
seqListener.highlightSequence(results);
}
}
/**
- * Returns a SearchResults object describing the mapped region corresponding
- * to the specified sequence position.
- *
- * @param seq
- * @param index
- * @return
- */
- protected SearchResults buildSearchResults(SequenceI seq, int index)
- {
- SearchResults results;
- results = new SearchResults();
- if (index >= seq.getStart() && index <= seq.getEnd())
- {
- if (seqmappings != null)
- {
- for (AlignedCodonFrame acf : seqmappings)
- {
- acf.markMappedRegion(seq, index, results);
- }
- }
- // hasSequenceListeners = results.getSize() > 0;
- if (handlingVamsasMo)
- {
- // maybe have to resolve seq to a dataset sequence...
- // add in additional direct sequence and/or dataset sequence
- // highlighting
- results.addResult(seq, index, index);
- }
- }
- return results;
- }
-
- /**
* Send suitable messages to a StructureListener to highlight atoms
* corresponding to the given sequence position.
*
int index)
{
int atomNo;
- if (mappings != null)
+ List<AtomSpec> atoms = new ArrayList<AtomSpec>();
+ for (StructureMapping sm : mappings)
{
- List<AtomSpec> atoms = new ArrayList<AtomSpec>();
- for (int j = 0; j < mappings.length; j++)
+ if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence())
{
- if (mappings[j].sequence == seq
- || mappings[j].sequence == seq.getDatasetSequence())
- {
- atomNo = mappings[j].getAtomNum(index);
+ atomNo = sm.getAtomNum(index);
- if (atomNo > 0)
- {
- atoms.add(new AtomSpec(mappings[j].pdbfile,
- mappings[j].pdbchain, mappings[j].getPDBResNum(index),
- atomNo));
- }
+ if (atomNo > 0)
+ {
+ atoms.add(new AtomSpec(sm.pdbfile, sm.pdbchain, sm
+ .getPDBResNum(index), atomNo));
}
}
- sl.highlightAtoms(atoms);
}
+ sl.highlightAtoms(atoms);
}
/**
public StructureMapping[] getMapping(String pdbfile)
{
- Vector tmp = new Vector();
- if (mappings != null)
- {
- for (int i = 0; i < mappings.length; i++)
+ List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ for (StructureMapping sm : mappings)
{
- if (mappings[i].pdbfile.equals(pdbfile))
+ if (sm.pdbfile.equals(pdbfile))
{
- tmp.addElement(mappings[i]);
+ tmp.add(sm);
}
- }
- }
- StructureMapping[] ret = new StructureMapping[tmp.size()];
- for (int i = 0; i < tmp.size(); i++)
- {
- ret[i] = (StructureMapping) tmp.elementAt(i);
}
-
- return ret;
+ return tmp.toArray(new StructureMapping[tmp.size()]);
}
public String printMapping(String pdbfile)
{
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < mappings.length; i++)
+ StringBuilder sb = new StringBuilder(64);
+ for (StructureMapping sm : mappings)
{
- if (mappings[i].pdbfile.equals(pdbfile))
+ if (sm.pdbfile.equals(pdbfile))
{
- sb.append(mappings[i].mappingDetails);
+ sb.append(sm.mappingDetails);
}
}
}
}
- Vector<SelectionListener> sel_listeners = new Vector<SelectionListener>();
-
public void addSelectionListener(SelectionListener selecter)
{
if (!sel_listeners.contains(selecter))
{
- sel_listeners.addElement(selecter);
+ sel_listeners.add(selecter);
}
}
{
if (sel_listeners.contains(toremove))
{
- sel_listeners.removeElement(toremove);
+ sel_listeners.remove(toremove);
}
}
jalview.datamodel.SequenceGroup selection,
jalview.datamodel.ColumnSelection colsel, SelectionSource source)
{
- if (sel_listeners != null && sel_listeners.size() > 0)
+ for (SelectionListener slis : sel_listeners)
{
- Enumeration listeners = sel_listeners.elements();
- while (listeners.hasMoreElements())
+ if (slis != source)
{
- SelectionListener slis = ((SelectionListener) listeners
- .nextElement());
- if (slis != source)
- {
- slis.selection(selection, colsel, source);
- }
- ;
+ slis.selection(selection, colsel, source);
}
}
}
{
for (CommandListener listener : commandListeners)
{
- if (listener.getVamsasSource() != source)
- {
- listener.mirrorCommand(command, undo, this);
- }
+ listener.mirrorCommand(command, undo, this, source);
}
}
/**
- * Returns a new EditCommand representing the given command as mapped to the
- * given sequences. If there is no mapping, returns an empty EditCommand.
+ * Returns a new CommandI representing the given command as mapped to the
+ * given sequences. If no mapping could be made, or the command is not of a
+ * mappable kind, returns null.
*
* @param command
* @param undo
- * @param targetSeqs
+ * @param alignmentI
* @param gapChar
* @return
*/
- public EditCommand mapEditCommand(EditCommand command, boolean undo,
- final List<SequenceI> targetSeqs, char gapChar)
+ public CommandI mapCommand(CommandI command,
+ boolean undo,
+ final AlignmentI alignmentI, char gapChar)
{
- /*
- * Cache a copy of the target sequences so we can mimic successive edits on
- * them. This lets us compute mappings for all edits in the set.
- */
- Map<SequenceI, SequenceI> targetCopies = new HashMap<SequenceI, SequenceI>();
- for (SequenceI seq : targetSeqs)
+ if (command instanceof EditCommand)
{
- SequenceI ds = seq.getDatasetSequence();
- if (ds != null)
- {
- final Sequence copy = new Sequence("", new String(seq.getSequence()));
- copy.setDatasetSequence(ds);
- targetCopies.put(ds, copy);
- }
+ return MappingUtils.mapEditCommand((EditCommand) command, undo,
+ alignmentI, gapChar,
+ seqmappings);
}
-
- /*
- * Compute 'source' sequences as they were before applying edits:
- */
- Map<SequenceI, SequenceI> originalSequences = command.priorState(undo);
-
- EditCommand result = new EditCommand();
- Iterator<Edit> edits = command.getEditIterator(!undo);
- while (edits.hasNext())
+ else if (command instanceof OrderCommand)
{
- Edit edit = edits.next();
- Action action = edit.getAction();
-
- /*
- * Invert sense of action if an Undo.
- */
- if (undo)
- {
- action = action == Action.INSERT_GAP ? Action.DELETE_GAP
- : (action == Action.DELETE_GAP ? Action.INSERT_GAP : action);
- }
- final int count = edit.getNumber();
- final int editPos = edit.getPosition();
- for (SequenceI seq : edit.getSequences())
- {
- /*
- * Get residue position at (or to right of) edit location. Note we use
- * our 'copy' of the sequence before editing for this.
- */
- SequenceI ds = seq.getDatasetSequence();
- if (ds == null)
- {
- continue;
- }
- final SequenceI actedOn = originalSequences.get(ds);
- final int seqpos = actedOn.findPosition(editPos);
-
- /*
- * Determine all mappings from this position to mapped sequences.
- */
- SearchResults sr = buildSearchResults(seq, seqpos);
-
- if (!sr.isEmpty())
- {
- for (SequenceI targetSeq : targetSeqs)
- {
- ds = targetSeq.getDatasetSequence();
- if (ds == null)
- {
- continue;
- }
- SequenceI copyTarget = targetCopies.get(ds);
- final int[] match = sr.getResults(copyTarget, 0,
- copyTarget.getLength());
- if (match != null)
- {
- final int ratio = 3; // TODO: compute this - how?
- final int mappedCount = count * ratio;
-
- /*
- * Shift Delete start position left, as it acts on positions to
- * its right.
- */
- int mappedEditPos = action == Action.DELETE_GAP ? match[0]
- - mappedCount : match[0];
- Edit e = new EditCommand().new Edit(action, new SequenceI[]
- { targetSeq }, mappedEditPos, mappedCount, gapChar);
- result.addEdit(e);
-
- /*
- * and 'apply' the edit to our copy of its target sequence
- */
- if (action == Action.INSERT_GAP)
- {
- copyTarget.setSequence(new String(StringUtils.insertCharAt(
- copyTarget.getSequence(), mappedEditPos,
- mappedCount,
- gapChar)));
- }
- else if (action == Action.DELETE_GAP)
- {
- copyTarget.setSequence(new String(StringUtils.deleteChars(
- copyTarget.getSequence(), mappedEditPos,
- mappedEditPos + mappedCount)));
- }
- }
- }
- }
- /*
- * and 'apply' the edit to our copy of its source sequence
- */
- if (action == Action.INSERT_GAP) {
- actedOn.setSequence(new String(StringUtils.insertCharAt(
- actedOn.getSequence(), editPos, count, gapChar)));
- }
- else if (action == Action.DELETE_GAP)
- {
- actedOn.setSequence(new String(StringUtils.deleteChars(
- actedOn.getSequence(), editPos, editPos + count)));
- }
- }
+ return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
+ alignmentI, seqmappings);
}
- return result;
+ return null;
}
}
--- /dev/null
+package jalview.util;
+
+import jalview.analysis.AlignmentSorter;
+import jalview.api.AlignViewportI;
+import jalview.commands.CommandI;
+import jalview.commands.EditCommand;
+import jalview.commands.EditCommand.Action;
+import jalview.commands.EditCommand.Edit;
+import jalview.commands.OrderCommand;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Helper methods for manipulations involving sequence mappings.
+ *
+ * @author gmcarstairs
+ *
+ */
+public final class MappingUtils
+{
+
+ /**
+ * Helper method to map a CUT or PASTE command.
+ *
+ * @param edit
+ * the original command
+ * @param undo
+ * if true, the command is to be undone
+ * @param targetSeqs
+ * the mapped sequences to apply the mapped command to
+ * @param result
+ * the mapped EditCommand to add to
+ * @param mappings
+ */
+ protected static void mapCutOrPaste(Edit edit, boolean undo,
+ List<SequenceI> targetSeqs, EditCommand result,
+ Set<AlignedCodonFrame> mappings)
+ {
+ Action action = edit.getAction();
+ if (undo)
+ {
+ action = action.getUndoAction();
+ }
+ // TODO write this
+ System.err.println("MappingUtils.mapCutOrPaste not yet implemented");
+ }
+
+ /**
+ * Returns a new EditCommand representing the given command as mapped to the
+ * given sequences. If there is no mapping, returns null.
+ *
+ * @param command
+ * @param undo
+ * @param alignment
+ * @param gapChar
+ * @param mappings
+ * @return
+ */
+ public static EditCommand mapEditCommand(EditCommand command,
+ boolean undo, final AlignmentI alignment, char gapChar,
+ Set<AlignedCodonFrame> mappings)
+ {
+ /*
+ * Cache a copy of the target sequences so we can mimic successive edits on
+ * them. This lets us compute mappings for all edits in the set.
+ */
+ Map<SequenceI, SequenceI> targetCopies = new HashMap<SequenceI, SequenceI>();
+ for (SequenceI seq : alignment.getSequences())
+ {
+ SequenceI ds = seq.getDatasetSequence();
+ if (ds != null)
+ {
+ final SequenceI copy = new Sequence("", new String(
+ seq.getSequence()));
+ copy.setDatasetSequence(ds);
+ targetCopies.put(ds, copy);
+ }
+ }
+
+ /*
+ * Compute 'source' sequences as they were before applying edits:
+ */
+ Map<SequenceI, SequenceI> originalSequences = command.priorState(undo);
+
+ EditCommand result = new EditCommand();
+ Iterator<Edit> edits = command.getEditIterator(!undo);
+ while (edits.hasNext())
+ {
+ Edit edit = edits.next();
+ if (edit.getAction() == Action.CUT
+ || edit.getAction() == Action.PASTE)
+ {
+ mapCutOrPaste(edit, undo, alignment.getSequences(), result,
+ mappings);
+ }
+ else if (edit.getAction() == Action.INSERT_GAP
+ || edit.getAction() == Action.DELETE_GAP)
+ {
+ mapInsertOrDelete(edit, undo, originalSequences,
+ alignment.getSequences(),
+ targetCopies, gapChar, result, mappings);
+ }
+ }
+ return result.getSize() > 0 ? result : null;
+ }
+
+ /**
+ * Helper method to map an edit command to insert or delete gaps.
+ *
+ * @param edit
+ * the original command
+ * @param undo
+ * if true, the action is to undo the command
+ * @param originalSequences
+ * the sequences the command acted on
+ * @param targetSeqs
+ * @param targetCopies
+ * @param gapChar
+ * @param result
+ * the new EditCommand to add mapped commands to
+ * @param mappings
+ */
+ protected static void mapInsertOrDelete(Edit edit, boolean undo,
+ Map<SequenceI, SequenceI> originalSequences,
+ final List<SequenceI> targetSeqs,
+ Map<SequenceI, SequenceI> targetCopies, char gapChar,
+ EditCommand result, Set<AlignedCodonFrame> mappings)
+ {
+ Action action = edit.getAction();
+
+ /*
+ * Invert sense of action if an Undo.
+ */
+ if (undo)
+ {
+ action = action.getUndoAction();
+ }
+ final int count = edit.getNumber();
+ final int editPos = edit.getPosition();
+ for (SequenceI seq : edit.getSequences())
+ {
+ /*
+ * Get residue position at (or to right of) edit location. Note we use our
+ * 'copy' of the sequence before editing for this.
+ */
+ SequenceI ds = seq.getDatasetSequence();
+ if (ds == null)
+ {
+ continue;
+ }
+ final SequenceI actedOn = originalSequences.get(ds);
+ final int seqpos = actedOn.findPosition(editPos);
+
+ /*
+ * Determine all mappings from this position to mapped sequences.
+ */
+ SearchResults sr = buildSearchResults(seq, seqpos, mappings);
+
+ if (!sr.isEmpty())
+ {
+ for (SequenceI targetSeq : targetSeqs)
+ {
+ ds = targetSeq.getDatasetSequence();
+ if (ds == null)
+ {
+ continue;
+ }
+ SequenceI copyTarget = targetCopies.get(ds);
+ final int[] match = sr.getResults(copyTarget, 0,
+ copyTarget.getLength());
+ if (match != null)
+ {
+ final int ratio = 3; // TODO: compute this - how?
+ final int mappedCount = count * ratio;
+
+ /*
+ * Shift Delete start position left, as it acts on positions to its
+ * right.
+ */
+ int mappedEditPos = action == Action.DELETE_GAP ? match[0]
+ - mappedCount : match[0];
+ Edit e = result.new Edit(action, new SequenceI[]
+ { targetSeq }, mappedEditPos, mappedCount, gapChar);
+ result.addEdit(e);
+
+ /*
+ * and 'apply' the edit to our copy of its target sequence
+ */
+ if (action == Action.INSERT_GAP)
+ {
+ copyTarget.setSequence(new String(StringUtils.insertCharAt(
+ copyTarget.getSequence(), mappedEditPos, mappedCount,
+ gapChar)));
+ }
+ else if (action == Action.DELETE_GAP)
+ {
+ copyTarget.setSequence(new String(StringUtils.deleteChars(
+ copyTarget.getSequence(), mappedEditPos,
+ mappedEditPos + mappedCount)));
+ }
+ }
+ }
+ }
+ /*
+ * and 'apply' the edit to our copy of its source sequence
+ */
+ if (action == Action.INSERT_GAP)
+ {
+ actedOn.setSequence(new String(StringUtils.insertCharAt(
+ actedOn.getSequence(), editPos, count, gapChar)));
+ }
+ else if (action == Action.DELETE_GAP)
+ {
+ actedOn.setSequence(new String(StringUtils.deleteChars(
+ actedOn.getSequence(), editPos, editPos + count)));
+ }
+ }
+ }
+
+ /**
+ * Returns a SearchResults object describing the mapped region corresponding
+ * to the specified sequence position.
+ *
+ * @param seq
+ * @param index
+ * @param seqmappings
+ * @return
+ */
+ public static SearchResults buildSearchResults(SequenceI seq, int index,
+ Set<AlignedCodonFrame> seqmappings)
+ {
+ SearchResults results;
+ results = new SearchResults();
+ if (index >= seq.getStart() && index <= seq.getEnd())
+ {
+ for (AlignedCodonFrame acf : seqmappings)
+ {
+ acf.markMappedRegion(seq, index, results);
+ }
+ results.addResult(seq, index, index);
+ }
+ return results;
+ }
+
+ /**
+ * Returns a (possibly empty) SequenceGroup containing any sequences the
+ * mapped viewport corresponding to the given group in the source viewport.
+ *
+ * @param sg
+ * @param av
+ * @param mapped
+ * @return
+ */
+ public static SequenceGroup mapSequenceGroup(SequenceGroup sg,
+ AlignViewportI av, AlignViewportI mapped)
+ {
+ /*
+ * Map sequence selection. Note the SequenceGroup holds aligned sequences,
+ * the mappings hold dataset sequences.
+ */
+ AlignedCodonFrame[] codonFrames = av.getAlignment()
+ .getCodonFrames();
+
+ /*
+ * Copy group name, colours, but not sequences
+ */
+ SequenceGroup mappedGroup = new SequenceGroup(sg);
+ mappedGroup.clear();
+ // TODO set width of mapped group
+
+ for (SequenceI selected : sg.getSequences())
+ {
+ for (AlignedCodonFrame acf : codonFrames)
+ {
+ SequenceI dnaSeq = acf.getDnaForAaSeq(selected);
+ if (dnaSeq != null)
+ {
+ for (SequenceI seq : mapped.getAlignment().getSequences())
+ {
+ if (seq.getDatasetSequence() == dnaSeq)
+ {
+ mappedGroup.addSequence(seq, false);
+ break;
+ }
+ }
+ }
+ }
+ }
+ return mappedGroup;
+ }
+
+ /**
+ * Returns an OrderCommand equivalent to the given one, but acting on mapped
+ * sequences as described by the mappings, or null if no mapping can be made.
+ *
+ * @param command
+ * the original order command
+ * @param undo
+ * if true, the action is to undo the sort
+ * @param mapTo
+ * the alignment we are mapping to
+ * @param mappings
+ * the mappings available
+ * @return
+ */
+ public static CommandI mapOrderCommand(OrderCommand command,
+ boolean undo, AlignmentI mapTo,
+ Set<AlignedCodonFrame> mappings)
+ {
+ SequenceI[] sortOrder = command.getSequenceOrder(undo);
+ List<SequenceI> mappedOrder = new ArrayList<SequenceI>();
+ int j = 0;
+ for (SequenceI seq : sortOrder)
+ {
+ for (AlignedCodonFrame acf : mappings)
+ {
+ SequenceI dnaSeq = acf.getDnaForAaSeq(seq);
+ if (dnaSeq != null)
+ {
+ for (SequenceI seq2 : mapTo.getSequences())
+ {
+ if (seq2.getDatasetSequence() == dnaSeq)
+ {
+ mappedOrder.add(seq2);
+ j++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Return null if no mappings made.
+ */
+ if (j == 0)
+ {
+ return null;
+ }
+
+ /*
+ * Add any unmapped sequences on the end of the sort in their original
+ * ordering.
+ */
+ if (j < mapTo.getHeight())
+ {
+ for (SequenceI seq : mapTo.getSequences())
+ {
+ if (!mappedOrder.contains(seq))
+ {
+ mappedOrder.add(seq);
+ }
+ }
+ }
+
+ /*
+ * Have to align the sequences before constructing the OrderCommand - which
+ * then realigns them?!?
+ */
+ final SequenceI[] mappedOrderArray = mappedOrder
+ .toArray(new SequenceI[mappedOrder.size()]);
+ SequenceI[] oldOrder = mapTo.getSequencesArray();
+ AlignmentSorter.sortBy(mapTo, new AlignmentOrder(mappedOrderArray));
+ final OrderCommand result = new OrderCommand(command.getDescription(),
+ oldOrder, mapTo);
+ return result;
+ }
+
+}
import java.awt.Color;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
*/
public abstract class AlignmentViewport implements AlignViewportI
{
+ /*
+ * A viewport that is a slave of (driven by) this one in some sense.
+ */
+ AlignViewportI slave = null;
+
/**
* alignment displayed in the viewport. Please use get/setter
*/
protected boolean showConsensus = true;
- Hashtable sequenceColours;
+ private Map<SequenceI, Color> sequenceColours = new HashMap<SequenceI, Color>();
/**
* Property change listener for changes in alignment
@Override
public Color getSequenceColour(SequenceI seq)
{
- Color sqc = Color.white;
- if (sequenceColours != null)
- {
- sqc = (Color) sequenceColours.get(seq);
- if (sqc == null)
- {
- sqc = Color.white;
- }
- }
- return sqc;
+ Color sqc = sequenceColours.get(seq);
+ return (sqc == null ? Color.white : sqc);
}
@Override
public void setSequenceColour(SequenceI seq, Color col)
{
- if (sequenceColours == null)
- {
- sequenceColours = new Hashtable();
- }
-
if (col == null)
{
sequenceColours.remove(seq);
@Override
public void updateSequenceIdColours()
{
- if (sequenceColours == null)
- {
- sequenceColours = new Hashtable();
- }
for (SequenceGroup sg : alignment.getGroups())
{
if (sg.idColour != null)
@Override
public void clearSequenceColours()
{
- sequenceColours = null;
+ sequenceColours.clear();
};
+
+ @Override
+ public AlignViewportI getSlave()
+ {
+ return this.slave;
+ }
+
+ @Override
+ public void setSlave(AlignViewportI sl)
+ {
+ if (this == sl.getSlave())
+ {
+ System.err.println("Ignoring recursive setSlave request");
+ }
+ else
+ {
+ this.slave = sl;
+ }
+ }
}
@Test
public void testAlignSequenceAs_withMapping_noIntrons()
{
- /*
- * Simple case: no gaps in dna
- */
- SequenceI dna = new Sequence("Seq1", "GGGAAA");
- dna.createDatasetSequence();
- SequenceI protein = new Sequence("Seq1", "-A-L-");
- protein.createDatasetSequence();
- AlignedCodonFrame acf = new AlignedCodonFrame();
MapList map = new MapList(new int[]
{ 1, 6 }, new int[]
{ 1, 2 }, 3, 1);
- acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map);
/*
* No existing gaps in dna:
*/
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- false);
- assertEquals("---GGG---AAA", dna.getSequenceAsString());
+ checkAlignSequenceAs("GGGAAA", "-A-L-", false, false, map,
+ "---GGG---AAA");
/*
* Now introduce gaps in dna but ignore them when realigning.
*/
- dna.setSequence("-G-G-G-A-A-A-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- false);
- assertEquals("---GGG---AAA", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G-G-A-A-A-", "-A-L-", false, false, map,
+ "---GGG---AAA");
/*
* Now include gaps in dna when realigning. First retaining 'mapped' gaps
* only, i.e. those within the exon region.
*/
- dna.setSequence("-G-G--G-A--A-A-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', true,
- false);
- assertEquals("---G-G--G---A--A-A", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G--G-A--A-A-", "-A-L-", true, false, map,
+ "---G-G--G---A--A-A");
/*
* Include all gaps in dna when realigning (within and without the exon
* region). The leading gap, and the gaps between codons, are subsumed by
* the protein alignment gap.
*/
- dna.setSequence("-G-GG--AA-A-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', true,
- true);
- assertEquals("---G-GG---AA-A-", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", true, true, map,
+ "---G-GG---AA-A-");
/*
* Include only unmapped gaps in dna when realigning (outside the exon
* region). The leading gap, and the gaps between codons, are subsumed by
* the protein alignment gap.
*/
- dna.setSequence("-G-GG--AA-A-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- true);
- assertEquals("---GGG---AAA-", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-GG--AA-A-", "-A-L-", false, true, map,
+ "---GGG---AAA-");
}
/**
public void testAlignSequenceAs_withMapping_withIntrons()
{
/*
- * Simple case: no gaps in dna
- */
- SequenceI dna = new Sequence("Seq1", "GGGAAACCCTTTGGG");
- dna.createDatasetSequence();
- SequenceI protein = new Sequence("Seq1", "-A-L-");
- protein.createDatasetSequence();
- AlignedCodonFrame acf = new AlignedCodonFrame();
-
- /*
* Exons at codon 2 (AAA) and 4 (TTT)
*/
MapList map = new MapList(new int[]
{ 4, 6, 10, 12 }, new int[]
{ 1, 2 }, 3, 1);
- acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map);
/*
- * Align dna as "-A-L-". The protein 'gaps' follow the introns, i.e are
- * placed immediately before the mapped codons.
+ * Simple case: no gaps in dna
*/
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- false);
- assertEquals("GGG---AAACCC---TTTGGG", dna.getSequenceAsString());
+ checkAlignSequenceAs("GGGAAACCCTTTGGG", "--A-L-", false, false, map,
+ "GGG---AAACCCTTTGGG");
/*
* Add gaps to dna - but ignore when realigning.
*/
- dna.setSequence("-G-G-G--A--A---AC-CC-T-TT-GG-G-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- false);
- assertEquals("GGG---AAACCC---TTTGGG", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G-G--A--A---AC-CC-T-TT-GG-G-", "--A-L-",
+ false, false, map, "GGG---AAACCCTTTGGG");
/*
* Add gaps to dna - include within exons only when realigning.
*/
- dna.setSequence("-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', true,
- false);
- assertEquals("GGG---A--A---ACCC---T-TTGGG", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, false, map, "GGG---A--A---ACCCT-TTGGG");
/*
* Include gaps outside exons only when realigning.
*/
- dna.setSequence("-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- true);
- assertEquals("-G-G-G---AAA-C-CC---TTT-GG-G-", dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ false, true, map, "-G-G-GAAAC-CCTTT-GG-G-");
+
+ /*
+ * Include gaps following first intron if we are 'preserving mapped gaps'
+ */
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
/*
* Include all gaps in dna when realigning.
*/
- dna.setSequence("-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', true,
- true);
- assertEquals("-G-G-G---A--A---A-C-CC---T-TT-GG-G-",
- dna.getSequenceAsString());
+ checkAlignSequenceAs("-G-G-G--A--A---A-C-CC-T-TT-GG-G-", "--A-L-",
+ true, true, map, "-G-G-G--A--A---A-C-CC-T-TT-GG-G-");
}
/**
@Test
public void testAlignSequenceAs_withMapping_withUnmappedProtein()
{
- SequenceI dna = new Sequence("Seq1", "GGGAAACCCTTTGGG");
- dna.createDatasetSequence();
- SequenceI protein = new Sequence("Seq1", "-A-L-P-");
- protein.createDatasetSequence();
- AlignedCodonFrame acf = new AlignedCodonFrame();
-
+
/*
* Exons at codon 2 (AAA) and 4 (TTT) mapped to A and P
*/
- MapList map = new MapList(new int[]
+ final MapList map = new MapList(new int[]
{ 4, 6, 10, 12 }, new int[]
{ 1, 1, 3, 3 }, 3, 1);
+
+
+ /*
+ * Expect alignment does nothing (aborts realignment). Change this test
+ * first if different behaviour wanted.
+ */
+ checkAlignSequenceAs("GGGAAACCCTTTGGG", "-A-L-P-", false,
+ false, map, "GGGAAACCCTTTGGG");
+ }
+
+ /**
+ * Helper method that performs and verifies the method under test.
+ *
+ * @param dnaSeq
+ * @param proteinSeq
+ * @param preserveMappedGaps
+ * @param preserveUnmappedGaps
+ * @param map
+ * @param expected
+ */
+ protected void checkAlignSequenceAs(final String dnaSeq,
+ final String proteinSeq, final boolean preserveMappedGaps,
+ final boolean preserveUnmappedGaps, MapList map,
+ final String expected)
+ {
+ SequenceI dna = new Sequence("Seq1", dnaSeq);
+ dna.createDatasetSequence();
+ SequenceI protein = new Sequence("Seq1", proteinSeq);
+ protein.createDatasetSequence();
+ AlignedCodonFrame acf = new AlignedCodonFrame();
acf.addMap(dna.getDatasetSequence(), protein.getDatasetSequence(), map);
+ AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-',
+ preserveMappedGaps, preserveUnmappedGaps);
+ assertEquals(expected, dna.getSequenceAsString());
+ }
+
+ /**
+ * Test for the alignSequenceAs method where we preserve gaps in introns only.
+ */
+ @Test
+ public void testAlignSequenceAs_keepIntronGapsOnly()
+ {
+
/*
- * Align dna as "-A-L-P-". Currently, does nothing (aborts realignment).
- * Change this test first if different behaviour wanted.
+ * Intron GGGAAA followed by exon CCCTTT
*/
- AlignmentUtils.alignSequenceAs(dna, protein, acf, "---", '-', false,
- false);
- assertEquals("GGGAAACCCTTTGGG", dna.getSequenceAsString());
+ MapList map = new MapList(new int[]
+ { 7, 12 }, new int[]
+ { 1, 2 }, 3, 1);
+
+ checkAlignSequenceAs("GG-G-AA-A-C-CC-T-TT", "AL",
+ false, true, map, "GG-G-AA-ACCCTTT");
}
}
* </ul>
*/
@Test
- public void testUnwindCommand_multipleInserts()
+ public void testPriorState_multipleInserts()
{
EditCommand command = new EditCommand();
SequenceI seq = new Sequence("", "--A--B-CDEF");
* </ul>
*/
@Test
- public void testUnwindCommand_removeAllGaps()
+ public void testPriorState_removeAllGaps()
{
EditCommand command = new EditCommand();
SequenceI seq = new Sequence("", "ABC");
* Test for 'undoing' a single delete edit.
*/
@Test
- public void testUnwindCommand_singleDelete()
+ public void testPriorState_singleDelete()
{
EditCommand command = new EditCommand();
SequenceI seq = new Sequence("", "ABCDEF");
}
/**
- * Test method that 'restores' edit commands to hold the sequence as it was
- * before the edit was applied.
+ * Test 'undoing' a single gap insertion edit command.
*/
@Test
- public void testUnwindCommand_singleInsert()
+ public void testPriorState_singleInsert()
{
EditCommand command = new EditCommand();
SequenceI seq = new Sequence("", "AB---CDEF");
* for contiguous gaps in each sequence separately.
*/
@Test
- public void testUnwindCommand_removeGapsMultipleSeqs()
+ public void testPriorState_removeGapsMultipleSeqs()
{
EditCommand command = new EditCommand();
String original1 = "--ABC-DEF";
* column region.
*/
@Test
- public void testUnwindCommand_removeGappedCols()
+ public void testPriorState_removeGappedCols()
{
EditCommand command = new EditCommand();
String original1 = "--ABC--DEF";
@Test
public void gatherViewsHere() throws Exception
{
- int origCount = Desktop.getAlignframes() == null ? 0 : Desktop
- .getAlignframes().length;
+ int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
+ .getAlignFrames().length;
AlignFrame af = new jalview.io.FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", FormatAdapter.FILE);
assertTrue("Didn't read in the example file correctly.", af != null);
assertTrue("Didn't gather the views in the example file.",
- Desktop.getAlignframes().length == 1 + origCount);
+ Desktop.getAlignFrames().length == 1 + origCount);
}