import java.awt.Shape;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
+import java.util.Iterator;
+ import java.util.List;
import javax.swing.JComponent;
if (av.hasHiddenColumns() && av.getShowHiddenMarkers())
{
- g.setColor(Color.blue);
- int res;
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
-
- Iterator<Integer> it = hidden.getBoundedStartIterator(startRes,
- endx + 1);
- while (it.hasNext())
- {
- res = it.next() - startRes;
- gg.fillPolygon(
- new int[]
- { res * charWidth - charHeight / 4,
- res * charWidth + charHeight / 4, res * charWidth },
- new int[]
- { ypos - (charHeight / 2), ypos - (charHeight / 2),
- ypos - (charHeight / 2) + 8 }, 3);
- }
+ drawHiddenColumnMarkers(g, ypos, startCol, endColumn);
}
- // When printing we have an extra clipped region,
- // the Printable page which we need to account for here
- Shape clip = g.getClip();
+ g.translate(-labelWidthWest, 0);
- if (clip == null)
- {
- g.setClip(0, 0, cWidth * charWidth, canvasHeight);
- }
- else
- {
- g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth,
- (int) clip.getBounds().getHeight());
- }
+ ypos += wrappedRepeatHeightPx;
+ startCol += viewportWidth;
+ widthsDrawn++;
+ }
+ }
- drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos);
+ /**
+ * Draws markers (triangles) above hidden column positions between startColumn
+ * and endColumn.
+ *
+ * @param g
+ * @param ypos
+ * @param startColumn
+ * @param endColumn
+ */
+ protected void drawHiddenColumnMarkers(Graphics g, int ypos,
+ int startColumn, int endColumn)
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
- if (av.isShowAnnotation())
- {
- g.translate(0, cHeight + ypos + 3);
- if (annotations == null)
- {
- annotations = new AnnotationPanel(av);
- }
+ g.setColor(Color.blue);
++ int res;
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- List<Integer> positions = hidden.findHiddenRegionPositions();
- for (int pos : positions)
+
- annotations.renderer.drawComponent(annotations, av, g, -1, startRes,
- endx + 1);
- g.translate(0, -cHeight - ypos - 3);
- }
- g.setClip(clip);
- g.translate(-labelWidthWest, 0);
++ Iterator<Integer> it = hidden.getBoundedStartIterator(startColumn,
++ endColumn);
++ while (it.hasNext())
+ {
- int res = pos - startColumn;
++ res = it.next() - startColumn;
- ypos += cHeight + annotationHeight + hgap;
+ if (res < 0 || res > endColumn - startColumn + 1)
+ {
+ continue;
+ }
- startRes += cWidth;
+ /*
+ * draw a downward-pointing triangle at the hidden columns location
+ * (before the following visible column)
+ */
+ int xMiddle = res * charWidth;
+ int[] xPoints = new int[] { xMiddle - charHeight / 4,
+ xMiddle + charHeight / 4, xMiddle };
+ int yTop = ypos - (charHeight / 2);
+ int[] yPoints = new int[] { yTop, yTop, yTop + 8 };
+ g.fillPolygon(xPoints, yPoints, 3);
}
}
}
@Test(groups = { "Functional" })
+ public void testGapBitset()
+ {
+ SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--");
+ BitSet bs = sq.gapBitset();
+ BitSet expected = new BitSet();
+ expected.set(0);
+ expected.set(4, 7);
+ expected.set(9);
+ expected.set(11, 13);
+
+ assertTrue(bs.equals(expected));
+
+ }
++
+ public void testFindFeatures_largeEndPos()
+ {
+ /*
+ * imitate a PDB sequence where end is larger than end position
+ */
+ SequenceI sq = new Sequence("test", "-ABC--DEF--", 1, 20);
+ sq.createDatasetSequence();
+
+ assertTrue(sq.findFeatures(1, 9).isEmpty());
+ // should be no array bounds exception - JAL-2772
+ assertTrue(sq.findFeatures(1, 15).isEmpty());
+
+ // add feature on BCD
+ SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 2, 4, 2f,
+ null);
+ sq.addSequenceFeature(sfBCD);
+
+ // no features in columns 1-2 (-A)
+ List<SequenceFeature> found = sq.findFeatures(1, 2);
+ assertTrue(found.isEmpty());
+
+ // columns 1-6 (-ABC--) includes BCD
+ found = sq.findFeatures(1, 6);
+ assertEquals(1, found.size());
+ assertTrue(found.contains(sfBCD));
+
+ // columns 10-11 (--) should find nothing
+ found = sq.findFeatures(10, 11);
+ assertEquals(0, found.size());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetName()
+ {
+ SequenceI sq = new Sequence("test", "-ABC---DE-F--");
+ assertEquals("test", sq.getName());
+ assertEquals(1, sq.getStart());
+ assertEquals(6, sq.getEnd());
+
+ sq.setName("testing");
+ assertEquals("testing", sq.getName());
+
+ sq.setName("test/8-10");
+ assertEquals("test", sq.getName());
+ assertEquals(8, sq.getStart());
+ assertEquals(13, sq.getEnd()); // note end is recomputed
+
+ sq.setName("testing/7-99");
+ assertEquals("testing", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd()); // end may be beyond physical end
+
+ sq.setName("/2-3");
+ assertEquals("", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/"); // invalid
+ assertEquals("test/", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/6-13/7-99");
+ assertEquals("test/6-13", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/0-5"); // 0 is invalid - ignored
+ assertEquals("test/0-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/a-5"); // a is invalid - ignored
+ assertEquals("test/a-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/6-5"); // start > end is invalid - ignored
+ assertEquals("test/6-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5"); // invalid - ignored
+ assertEquals("test/5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/-5"); // invalid - ignored
+ assertEquals("test/-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-"); // invalid - ignored
+ assertEquals("test/5-", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-6-7"); // invalid - ignored
+ assertEquals("test/5-6-7", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName(null); // invalid, gets converted to space
+ assertEquals("", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCheckValidRange()
+ {
+ Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--");
+ assertEquals(7, sq.getStart());
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * checkValidRange ensures end is at least the last residue position
+ */
+ PA.setValue(sq, "end", 2);
+ sq.checkValidRange();
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * end may be beyond the last residue position
+ */
+ PA.setValue(sq, "end", 22);
+ sq.checkValidRange();
+ assertEquals(22, sq.getEnd());
+ }
}