import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.ListIterator;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/*
* set status bar message, returning residue position in sequence
*/
+ boolean isGapped = Comparison.isGap(sequence.getCharAt(column));
final int pos = setStatusMessage(sequence, column, seq);
- if (ssm != null && pos > -1)
+ if (ssm != null && !isGapped)
{
mouseOverSequence(sequence, column, pos);
}
}
}
- if (av.isShowSequenceFeatures() && pos != -1)
+ /*
+ * add any features at the position to the tooltip; if over a gap, only
+ * add features that straddle the gap (pos may be the residue before or
+ * after the gap)
+ */
+ if (av.isShowSequenceFeatures())
{
List<SequenceFeature> features = ap.getFeatureRenderer()
.findFeaturesAtRes(sequence.getDatasetSequence(), pos);
+ if (isGapped)
+ {
+ removeAdjacentFeatures(features, column + 1, sequence);
+ }
seqARep.appendFeatures(tooltipText, pos, features,
this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
}
}
+ /**
+ * Removes from the list of features any that start after, or end before, the
+ * given column position. This allows us to retain only those features
+ * adjacent to a gapped position that straddle the position.
+ *
+ * @param features
+ * @param column
+ * alignment column (1..)
+ * @param sequence
+ */
+ protected void removeAdjacentFeatures(List<SequenceFeature> features,
+ final int column, SequenceI sequence)
+ {
+ // TODO should this be an AlignViewController method (and reused by applet)?
+ ListIterator<SequenceFeature> it = features.listIterator();
+ while (it.hasNext())
+ {
+ SequenceFeature sf = it.next();
+ if (sequence.findIndex(sf.getBegin()) > column
+ || sequence.findIndex(sf.getEnd()) < column)
+ {
+ it.remove();
+ }
+ }
+ }
+
private Point lastp = null;
/*
/**
* Sets the status message in alignment panel, showing the sequence number
- * (index) and id, residue and residue position for the given sequence and
- * column position. Returns the calculated residue position in the sequence,
- * or -1 for a gapped column position.
+ * (index) and id, and residue and residue position if not at a gap, for the
+ * given sequence and column position. Returns the residue position returned
+ * by Sequence.findPosition. Note this may be for the nearest adjacent residue
+ * if at a gapped position.
*
* @param sequence
* aligned sequence object
* alignment column
* @param seq
* index of sequence in alignment
- * @return position of column in sequence or -1 if at a gap
+ * @return sequence position of residue at column, or adjacent residue if at a
+ * gap
*/
int setStatusMessage(SequenceI sequence, final int column, int seq)
{
.append(sequence.getName());
String residue = null;
+
/*
* Try to translate the display character to residue name (null for gap).
*/
final String displayChar = String.valueOf(sequence.getCharAt(column));
- if (av.getAlignment().isNucleotide())
+ boolean isGapped = Comparison.isGap(sequence.getCharAt(column));
+ int pos = sequence.findPosition(column);
+
+ if (!isGapped)
{
- residue = ResidueProperties.nucleotideName.get(displayChar);
- if (residue != null)
+ boolean nucleotide = av.getAlignment().isNucleotide();
+ if (nucleotide)
{
- text.append(" Nucleotide: ").append(residue);
+ residue = ResidueProperties.nucleotideName.get(displayChar);
}
- }
- else
- {
- residue = "X".equalsIgnoreCase(displayChar) ? "X" : ("*"
- .equals(displayChar) ? "STOP" : ResidueProperties.aa2Triplet
- .get(displayChar));
- if (residue != null)
+ else
{
- text.append(" Residue: ").append(residue);
+ residue = "X".equalsIgnoreCase(displayChar) ? "X" : ("*"
+ .equals(displayChar) ? "STOP"
+ : ResidueProperties.aa2Triplet.get(displayChar));
}
- }
+ text.append(" ").append(nucleotide ? "Nucleotide" : "Residue")
+ .append(": ").append(residue == null ? displayChar : residue);
- int pos = -1;
- if (residue != null)
- {
- pos = sequence.findPosition(column);
text.append(" (").append(Integer.toString(pos)).append(")");
}
ap.alignFrame.statusBar.setText(text.toString());
+
return pos;
}
av.setSelectionGroup(null);
}
+ int column = findColumn(evt);
+ boolean isGapped = Comparison.isGap(sequence.getCharAt(column));
+
+ /*
+ * find features at the position (if not gapped), or straddling
+ * the position (if at a gap)
+ */
List<SequenceFeature> features = seqCanvas.getFeatureRenderer()
.findFeaturesAtRes(sequence.getDatasetSequence(),
- sequence.findPosition(findColumn(evt)));
+ sequence.findPosition(column));
+ if (isGapped)
+ {
+ removeAdjacentFeatures(features, column, sequence);
+ }
if (!features.isEmpty())
{