Remove unnecessary ints
[jalview.git] / src / jalview / gui / SeqCanvas.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import java.awt.*;\r
24 import java.awt.image.*;\r
25 \r
26 import javax.swing.*;\r
27 \r
28 \r
29 /**\r
30  * DOCUMENT ME!\r
31  *\r
32  * @author $author$\r
33  * @version $Revision$\r
34  */\r
35 public class SeqCanvas extends JComponent\r
36 {\r
37     final FeatureRenderer fr;\r
38     final SequenceRenderer sr;\r
39     BufferedImage img;\r
40     Graphics2D gg;\r
41     int imgWidth;\r
42     int imgHeight;\r
43     AlignViewport av;\r
44     SearchResults searchResults = null;\r
45     boolean fastPaint = false;\r
46     int LABEL_WEST;\r
47     int LABEL_EAST;\r
48 \r
49 \r
50     int cursorX = 0;\r
51     int cursorY = 0;\r
52 \r
53 \r
54     /**\r
55      * Creates a new SeqCanvas object.\r
56      *\r
57      * @param av DOCUMENT ME!\r
58      */\r
59     public SeqCanvas(AlignViewport av)\r
60     {\r
61         this.av = av;\r
62         fr = new FeatureRenderer(av);\r
63         sr = new SequenceRenderer(av);\r
64         setLayout(new BorderLayout());\r
65         PaintRefresher.Register(this, av.alignment);\r
66         setBackground(Color.white);\r
67     }\r
68 \r
69     MCview.PDBCanvas pdbCanvas;\r
70     public SequenceRenderer getSequenceRenderer()\r
71     {\r
72       return sr;\r
73     }\r
74 \r
75     public FeatureRenderer getFeatureRenderer()\r
76     {\r
77       return fr;\r
78     }\r
79 \r
80     public void setPDBCanvas(MCview.PDBCanvas pc)\r
81     {\r
82       pdbCanvas = pc;\r
83     }\r
84 \r
85     public AlignViewport getViewport()\r
86     {\r
87       return av;\r
88     }\r
89 \r
90 \r
91     /**\r
92      * DOCUMENT ME!\r
93      *\r
94      * @param g DOCUMENT ME!\r
95      * @param startx DOCUMENT ME!\r
96      * @param endx DOCUMENT ME!\r
97      * @param ypos DOCUMENT ME!\r
98      */\r
99     void drawNorthScale(Graphics g, int startx, int endx, int ypos)\r
100     {\r
101         int scalestartx = startx - (startx % 10) + 10;\r
102 \r
103         g.setColor(Color.black);\r
104 \r
105         // NORTH SCALE\r
106         for (int i = scalestartx; i < endx; i += 10)\r
107         {\r
108             int value = i;\r
109             if(av.hasHiddenColumns)\r
110                 value = av.getColumnSelection().adjustForHiddenColumns(value);\r
111 \r
112             g.drawString( String.valueOf(value), (i - startx - 1) * av.charWidth,\r
113                 ypos - (av.charHeight / 2));\r
114 \r
115             g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2),\r
116                 (ypos + 2) - (av.charHeight / 2),\r
117                 ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), ypos -\r
118                 2);\r
119         }\r
120     }\r
121 \r
122     /**\r
123      * DOCUMENT ME!\r
124      *\r
125      * @param g DOCUMENT ME!\r
126      * @param startx DOCUMENT ME!\r
127      * @param endx DOCUMENT ME!\r
128      * @param ypos DOCUMENT ME!\r
129      */\r
130     void drawWestScale(Graphics g, int startx, int endx, int ypos)\r
131     {\r
132         FontMetrics fm = getFontMetrics(av.getFont());\r
133         ypos += av.charHeight;\r
134 \r
135         if(av.hasHiddenColumns)\r
136                 startx = av.getColumnSelection().adjustForHiddenColumns(startx);\r
137 \r
138         // EAST SCALE\r
139         for (int i = 0; i < av.alignment.getHeight(); i++)\r
140         {\r
141             SequenceI seq = av.alignment.getSequenceAt(i);\r
142             int index = startx;\r
143             int value = -1;\r
144 \r
145             while (index < endx)\r
146             {\r
147                 if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
148                 {\r
149                     index++;\r
150 \r
151                     continue;\r
152                 }\r
153 \r
154                 value = av.alignment.getSequenceAt(i).findPosition(index);\r
155 \r
156                 break;\r
157             }\r
158 \r
159             if (value != -1)\r
160             {\r
161                 int x = LABEL_WEST - fm.stringWidth(String.valueOf(value))-av.charWidth/2;\r
162                 g.drawString(value + "", x,\r
163                     (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
164             }\r
165         }\r
166     }\r
167 \r
168     /**\r
169      * DOCUMENT ME!\r
170      *\r
171      * @param g DOCUMENT ME!\r
172      * @param startx DOCUMENT ME!\r
173      * @param endx DOCUMENT ME!\r
174      * @param ypos DOCUMENT ME!\r
175      */\r
176     void drawEastScale(Graphics g, int startx, int endx, int ypos)\r
177     {\r
178         ypos += av.charHeight;\r
179 \r
180         if(av.hasHiddenColumns)\r
181                 endx = av.getColumnSelection().adjustForHiddenColumns(endx);\r
182 \r
183         SequenceI seq;\r
184         // EAST SCALE\r
185         for (int i = 0; i < av.alignment.getHeight(); i++)\r
186         {\r
187             seq = av.alignment.getSequenceAt(i);\r
188             int index = endx;\r
189             int value = -1;\r
190 \r
191             while (index > startx)\r
192             {\r
193                 if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
194                 {\r
195                     index--;\r
196 \r
197                     continue;\r
198                 }\r
199 \r
200                 value = seq.findPosition(index);\r
201 \r
202                 break;\r
203             }\r
204 \r
205             if (value != -1)\r
206             {\r
207                 g.drawString(String.valueOf(value), 0,\r
208                     (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
209             }\r
210         }\r
211     }\r
212 \r
213     /**\r
214      * DOCUMENT ME!\r
215      *\r
216      * @param horizontal DOCUMENT ME!\r
217      * @param vertical DOCUMENT ME!\r
218      */\r
219     public void fastPaint(int horizontal, int vertical)\r
220     {\r
221         if (gg == null)\r
222         {\r
223             return;\r
224         }\r
225 \r
226 \r
227         fastPaint = true;\r
228 \r
229         gg.copyArea(horizontal * av.charWidth,\r
230                     vertical * av.charHeight,\r
231                     imgWidth,\r
232                     imgHeight,\r
233                     -horizontal * av.charWidth,\r
234                     -vertical * av.charHeight);\r
235 \r
236         int sr = av.startRes;\r
237         int er = av.endRes;\r
238         int ss = av.startSeq;\r
239         int es = av.endSeq;\r
240         int transX = 0;\r
241         int transY = 0;\r
242 \r
243 \r
244         if (horizontal > 0) // scrollbar pulled right, image to the left\r
245         {\r
246             er ++;\r
247             transX = (er - sr - horizontal) * av.charWidth;\r
248             sr = er - horizontal;\r
249         }\r
250         else if (horizontal < 0)\r
251         {\r
252             er = sr - horizontal-1;\r
253         }\r
254         else if (vertical > 0) // scroll down\r
255         {\r
256             ss = es - vertical;\r
257 \r
258             if (ss < av.startSeq)\r
259             { // ie scrolling too fast, more than a page at a time\r
260                 ss = av.startSeq;\r
261             }\r
262             else\r
263             {\r
264                 transY = imgHeight - (vertical * av.charHeight);\r
265             }\r
266         }\r
267         else if (vertical < 0)\r
268         {\r
269             es = ss - vertical;\r
270 \r
271             if (es > av.endSeq)\r
272             {\r
273                 es = av.endSeq;\r
274             }\r
275         }\r
276 \r
277         gg.translate(transX, transY);\r
278         drawPanel(gg, sr, er, ss, es, 0);\r
279         gg.translate(-transX, -transY);\r
280 \r
281         repaint();\r
282     }\r
283 \r
284     /**\r
285      * Definitions of startx and endx (hopefully):\r
286      * SMJS This is what I'm working towards!\r
287      *   startx is the first residue (starting at 0) to display.\r
288      *   endx   is the last residue to display (starting at 0).\r
289      *   starty is the first sequence to display (starting at 0).\r
290      *   endy   is the last sequence to display (starting at 0).\r
291      * NOTE 1: The av limits are set in setFont in this class and\r
292      * in the adjustment listener in SeqPanel when the scrollbars move.\r
293      */\r
294 \r
295     // Set this to false to force a full panel paint\r
296     public void paintComponent(Graphics g)\r
297     {\r
298         super.paintComponent(g);\r
299 \r
300 \r
301 \r
302         if ( img != null && (fastPaint\r
303              || (getVisibleRect().width != g.getClipBounds().width)\r
304              || (getVisibleRect().height != g.getClipBounds().height)))\r
305         {\r
306             g.drawImage(img, 0, 0, this);\r
307             fastPaint = false;\r
308             return;\r
309         }\r
310 \r
311 \r
312         // this draws the whole of the alignment\r
313         imgWidth = getWidth();\r
314         imgHeight = getHeight();\r
315 \r
316         imgWidth -= (imgWidth % av.charWidth);\r
317         imgHeight -= (imgHeight % av.charHeight);\r
318 \r
319         if ((imgWidth < 1) || (imgHeight < 1))\r
320         {\r
321             return;\r
322         }\r
323 \r
324         img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);\r
325         gg = (Graphics2D) img.getGraphics();\r
326         gg.setFont(av.getFont());\r
327 \r
328         if (av.antiAlias)\r
329           gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
330                               RenderingHints.VALUE_ANTIALIAS_ON);\r
331 \r
332         gg.setColor(Color.white);\r
333         gg.fillRect(0, 0, imgWidth, imgHeight);\r
334 \r
335 \r
336         if (av.getWrapAlignment())\r
337         {\r
338             drawWrappedPanel(gg, getWidth(), getHeight(), av.startRes);\r
339         }\r
340         else\r
341         {\r
342             drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq, 0);\r
343         }\r
344 \r
345         g.drawImage(img, 0, 0, this);\r
346 \r
347         if (pdbCanvas != null)\r
348         {\r
349            pdbCanvas.updateSeqColours();\r
350         }\r
351 \r
352     }\r
353 \r
354     /**\r
355      * DOCUMENT ME!\r
356      *\r
357      * @param cwidth DOCUMENT ME!\r
358      *\r
359      * @return DOCUMENT ME!\r
360      */\r
361     public int getWrappedCanvasWidth(int cwidth)\r
362     {\r
363         FontMetrics fm = getFontMetrics(av.getFont());\r
364 \r
365         LABEL_EAST = 0;\r
366         LABEL_WEST = 0;\r
367 \r
368         if (av.scaleRightWrapped)\r
369         {\r
370             LABEL_EAST = fm.stringWidth(getMask());\r
371         }\r
372 \r
373         if (av.scaleLeftWrapped)\r
374         {\r
375             LABEL_WEST = fm.stringWidth(getMask());\r
376         }\r
377 \r
378         return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
379     }\r
380 \r
381 \r
382     /**\r
383      * Generates a string of zeroes.\r
384      * @return String\r
385      */\r
386     String getMask()\r
387     {\r
388       String mask = "00";\r
389       for (int i = av.alignment.getWidth(); i > 0; i /= 10)\r
390       {\r
391         mask += "0";\r
392       }\r
393       return mask;\r
394     }\r
395 \r
396     /**\r
397      * DOCUMENT ME!\r
398      *\r
399      * @param g DOCUMENT ME!\r
400      * @param canvasWidth DOCUMENT ME!\r
401      * @param canvasHeight DOCUMENT ME!\r
402      * @param startRes DOCUMENT ME!\r
403      */\r
404     public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,\r
405         int startRes)\r
406     {\r
407 \r
408         AlignmentI al = av.getAlignment();\r
409 \r
410         FontMetrics fm = getFontMetrics(av.getFont());\r
411 \r
412 \r
413         if (av.scaleRightWrapped)\r
414         {\r
415             LABEL_EAST = fm.stringWidth(getMask());\r
416         }\r
417 \r
418 \r
419         if (av.scaleLeftWrapped)\r
420         {\r
421             LABEL_WEST = fm.stringWidth(getMask());\r
422         }\r
423 \r
424         int hgap = av.charHeight;\r
425         if(av.scaleAboveWrapped)\r
426           hgap += av.charHeight;\r
427 \r
428         int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
429         int cHeight = av.getAlignment().getHeight() * av.charHeight;\r
430 \r
431         av.setWrappedWidth(cWidth);\r
432 \r
433         av.endRes = av.startRes + cWidth;\r
434 \r
435 \r
436         int endx;\r
437         int ypos = hgap;\r
438 \r
439         while ((ypos <= canvasHeight) && (startRes < av.alignment.getWidth()))\r
440         {\r
441           endx = startRes + cWidth -1;\r
442 \r
443           if (endx > al.getWidth())\r
444           {\r
445             endx = al.getWidth();\r
446           }\r
447 \r
448             g.setFont(av.getFont());\r
449             g.setColor(Color.black);\r
450 \r
451             if (av.scaleLeftWrapped)\r
452             {\r
453                 drawWestScale(g, startRes, endx, ypos);\r
454             }\r
455 \r
456             if (av.scaleRightWrapped)\r
457             {\r
458                 g.translate(canvasWidth - LABEL_EAST, 0);\r
459                 drawEastScale(g, startRes, endx, ypos);\r
460                 g.translate(-(canvasWidth - LABEL_EAST), 0);\r
461             }\r
462 \r
463             g.translate(LABEL_WEST, 0);\r
464 \r
465             if (av.scaleAboveWrapped)\r
466             {\r
467                 drawNorthScale(g, startRes, endx, ypos);\r
468             }\r
469 \r
470             // When printing we have an extra clipped region,\r
471             // the Printable page which we need to account for here\r
472             Shape clip = g.getClip();\r
473 \r
474             if (clip == null)\r
475             {\r
476                 g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);\r
477             }\r
478             else\r
479             {\r
480                 g.setClip(0, (int) clip.getBounds().getY(),\r
481                     cWidth * av.charWidth, (int) clip.getBounds().getHeight());\r
482             }\r
483 \r
484             drawPanel(g, startRes, endx, 0, al.getHeight(), ypos);\r
485 \r
486             if(av.showAnnotation)\r
487             {\r
488               g.translate(0, cHeight + ypos + 3);\r
489               if(annotations==null)\r
490                 annotations = new AnnotationPanel(av);\r
491 \r
492               annotations.drawComponent( (Graphics2D) g, startRes, endx+1);\r
493               g.translate(0, -cHeight - ypos);\r
494             }\r
495             g.setClip(clip);\r
496             g.translate(-LABEL_WEST, 0);\r
497 \r
498             ypos += cHeight+getAnnotationHeight()+hgap;\r
499             if(av.showAnnotation)\r
500               ypos -= 3;\r
501 \r
502             startRes += cWidth;\r
503         }\r
504     }\r
505 \r
506     AnnotationPanel annotations;\r
507     int getAnnotationHeight()\r
508     {\r
509       if(!av.showAnnotation)\r
510         return 0;\r
511 \r
512       if(annotations==null)\r
513         annotations = new AnnotationPanel(av);\r
514 \r
515       return annotations.adjustPanelHeight();\r
516     }\r
517 \r
518     /**\r
519      * DOCUMENT ME!\r
520      *\r
521      * @param g1 DOCUMENT ME!\r
522      * @param startRes DOCUMENT ME!\r
523      * @param endRes DOCUMENT ME!\r
524      * @param startSeq DOCUMENT ME!\r
525      * @param endSeq DOCUMENT ME!\r
526      * @param offset DOCUMENT ME!\r
527      */\r
528     void drawPanel(Graphics g1, int startRes, int endRes,\r
529                     int startSeq, int endSeq, int offset)\r
530     {\r
531       if(!av.hasHiddenColumns)\r
532       {\r
533         draw(g1, startRes, endRes, startSeq, endSeq, offset);\r
534       }\r
535       else\r
536       {\r
537         java.util.Vector regions = av.getColumnSelection().getHiddenColumns();\r
538 \r
539         int screenY = 0;\r
540         int blockStart = startRes;\r
541         int blockEnd = endRes;\r
542 \r
543         for (int i = 0; i < regions.size(); i++)\r
544         {\r
545           int[] region = (int[]) regions.elementAt(i);\r
546           int hideStart = region[0];\r
547           int hideEnd = region[1];\r
548 \r
549           if (hideStart <= blockStart)\r
550           {\r
551             blockStart += (hideEnd - hideStart) + 1;\r
552             continue;\r
553           }\r
554 \r
555           blockEnd = hideStart - 1;\r
556 \r
557           g1.translate(screenY * av.charWidth, 0);\r
558 \r
559           draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);\r
560 \r
561           g1.setColor(Color.blue);\r
562           g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth - 1,\r
563                       startSeq + offset,\r
564                       (blockEnd - blockStart + 1) * av.charWidth - 1,\r
565                       startSeq + (endSeq - startSeq) * av.charHeight + offset);\r
566           g1.drawLine( (blockEnd - blockStart + 1) * av.charWidth,\r
567                       startSeq + offset,\r
568                       (blockEnd - blockStart + 1) * av.charWidth,\r
569                       startSeq + (endSeq - startSeq) * av.charHeight + offset);\r
570 \r
571           g1.translate( -screenY * av.charWidth, 0);\r
572           screenY += blockEnd - blockStart + 1;\r
573           blockStart = hideEnd + 1;\r
574         }\r
575 \r
576         if (screenY <= (endRes - startRes))\r
577         {\r
578           blockEnd = blockStart + (endRes - startRes) - screenY;\r
579           g1.translate(screenY * av.charWidth, 0);\r
580           draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);\r
581           g1.translate( -screenY * av.charWidth, 0);\r
582         }\r
583       }\r
584 \r
585     }\r
586 \r
587 \r
588 \r
589 \r
590     //int startRes, int endRes, int startSeq, int endSeq, int x, int y,\r
591     // int x1, int x2, int y1, int y2, int startx, int starty,\r
592     void draw(Graphics g,\r
593                    int startRes, int endRes,\r
594                    int startSeq, int endSeq,\r
595                    int offset)\r
596    {\r
597       g.setFont(av.getFont());\r
598       sr.prepare(g, av.renderGaps);\r
599 \r
600       SequenceI nextSeq;\r
601 \r
602         /// First draw the sequences\r
603         /////////////////////////////\r
604         for (int i = startSeq; i < endSeq; i++)\r
605         {\r
606             nextSeq = av.alignment.getSequenceAt(i);\r
607 \r
608             sr.drawSequence(nextSeq, av.alignment.findAllGroups(nextSeq),\r
609                             startRes, endRes,\r
610                             offset + ( (i - startSeq) * av.charHeight));\r
611 \r
612             if (av.showSequenceFeatures)\r
613             {\r
614                 fr.drawSequence(g, nextSeq, startRes, endRes,\r
615                     offset + ((i - startSeq) * av.charHeight));\r
616             }\r
617 \r
618             /// Highlight search Results once all sequences have been drawn\r
619             //////////////////////////////////////////////////////////\r
620             if (searchResults != null)\r
621             {\r
622               int[] visibleResults = searchResults.getResults(nextSeq, startRes, endRes);\r
623               if (visibleResults != null)\r
624                 for (int r = 0; r < visibleResults.length; r += 2)\r
625                 {\r
626                   sr.drawHighlightedText(nextSeq, visibleResults[r],\r
627                                          visibleResults[r + 1],\r
628                                          (visibleResults[r] - startRes) * av.charWidth,\r
629                                          offset + ( (i - startSeq) * av.charHeight));\r
630                 }\r
631             }\r
632 \r
633             if(av.cursorMode && cursorY==i\r
634                && cursorX>=startRes && cursorX<=endRes)\r
635             {\r
636               sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * av.charWidth,\r
637                             offset + ( (i - startSeq) * av.charHeight));\r
638             }\r
639           }\r
640 \r
641           if(av.getSelectionGroup()!=null || av.alignment.getGroups().size()>0)\r
642             drawGroupsBoundaries(g, startRes, endRes, startSeq, endSeq, offset);\r
643 \r
644    }\r
645 \r
646    void drawGroupsBoundaries(Graphics g1,\r
647                    int startRes, int endRes,\r
648                    int startSeq, int endSeq,\r
649                    int offset)\r
650    {\r
651        Graphics2D g = (Graphics2D)g1;\r
652         //\r
653         /////////////////////////////////////\r
654         // Now outline any areas if necessary\r
655         /////////////////////////////////////\r
656         SequenceGroup group = av.getSelectionGroup();\r
657 \r
658         int sx = -1;\r
659         int sy = -1;\r
660         int ex = -1;\r
661         int groupIndex = -1;\r
662 \r
663         if ((group == null) && (av.alignment.getGroups().size() > 0))\r
664         {\r
665             group = (SequenceGroup) av.alignment.getGroups().elementAt(0);\r
666             groupIndex = 0;\r
667         }\r
668 \r
669         if (group != null)\r
670         {\r
671             do\r
672             {\r
673                 int oldY = -1;\r
674                 int i = 0;\r
675                 boolean inGroup = false;\r
676                 int top = -1;\r
677                 int bottom = -1;\r
678 \r
679                 for (i = startSeq; i < endSeq; i++)\r
680                 {\r
681                     sx = (group.getStartRes() - startRes) * av.charWidth;\r
682                     sy = offset + ((i - startSeq) * av.charHeight);\r
683                     ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) -\r
684                         1;\r
685 \r
686                     if(sx+ex<0 || sx>imgWidth)\r
687                     {\r
688                       continue;\r
689                     }\r
690 \r
691                     if ( (sx <= (endRes-startRes)*av.charWidth) &&\r
692                             group.sequences.contains(av.alignment.getSequenceAt(\r
693                                     i)))\r
694                     {\r
695                         if ((bottom == -1) &&\r
696                                 !group.sequences.contains(\r
697                                     av.alignment.getSequenceAt(i + 1)))\r
698                         {\r
699                             bottom = sy + av.charHeight;\r
700                         }\r
701 \r
702                         if (!inGroup)\r
703                         {\r
704                             if (((top == -1) && (i == 0)) ||\r
705                                     !group.sequences.contains(\r
706                                         av.alignment.getSequenceAt(i - 1)))\r
707                             {\r
708                                 top = sy;\r
709                             }\r
710 \r
711                             oldY = sy;\r
712                             inGroup = true;\r
713 \r
714                             if (group == av.getSelectionGroup())\r
715                             {\r
716                                 g.setStroke(new BasicStroke(1,\r
717                                         BasicStroke.CAP_BUTT,\r
718                                         BasicStroke.JOIN_ROUND, 3f,\r
719                                         new float[] { 5f, 3f }, 0f));\r
720                                 g.setColor(Color.RED);\r
721                             }\r
722                             else\r
723                             {\r
724                                 g.setStroke(new BasicStroke());\r
725                                 g.setColor(group.getOutlineColour());\r
726                             }\r
727                         }\r
728                     }\r
729                     else\r
730                     {\r
731                       if (inGroup)\r
732                       {\r
733                         if (sx >= 0 && sx < imgWidth)\r
734                           g.drawLine(sx, oldY, sx, sy);\r
735 \r
736                         if (sx + ex < imgWidth)\r
737                           g.drawLine(sx + ex, oldY, sx + ex, sy);\r
738 \r
739                         if (sx < 0)\r
740                         {\r
741                           ex += sx;\r
742                           sx = 0;\r
743                         }\r
744 \r
745                         if (sx + ex > imgWidth)\r
746                           ex = imgWidth;\r
747 \r
748                         else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
749                           ex = (endRes - startRes + 1) * av.charWidth;\r
750 \r
751                         if (top != -1)\r
752                         {\r
753                           g.drawLine(sx, top, sx + ex, top);\r
754                           top = -1;\r
755                         }\r
756 \r
757                         if (bottom != -1)\r
758                         {\r
759                           g.drawLine(sx, bottom, sx + ex, bottom);\r
760                           bottom = -1;\r
761                         }\r
762 \r
763                         inGroup = false;\r
764                         }\r
765                     }\r
766                 }\r
767 \r
768                 if (inGroup)\r
769                 {\r
770                   sy = offset + ( (i - startSeq) * av.charHeight);\r
771                   if (sx >= 0 && sx < imgWidth)\r
772                     g.drawLine(sx, oldY, sx, sy);\r
773 \r
774                   if (sx + ex < imgWidth)\r
775                     g.drawLine(sx + ex, oldY, sx + ex, sy);\r
776 \r
777                   if (sx < 0)\r
778                   {\r
779                     ex += sx;\r
780                     sx = 0;\r
781                   }\r
782 \r
783                   if (sx + ex > imgWidth)\r
784                     ex = imgWidth;\r
785                   else if (sx + ex >= (endRes - startRes + 1) * av.charWidth)\r
786                     ex = (endRes - startRes + 1) * av.charWidth;\r
787 \r
788                   if (top != -1)\r
789                   {\r
790                     g.drawLine(sx, top, sx + ex, top);\r
791                     top = -1;\r
792                   }\r
793 \r
794                   if (bottom != -1)\r
795                   {\r
796                     g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);\r
797                     bottom = -1;\r
798                   }\r
799 \r
800                     inGroup = false;\r
801                 }\r
802 \r
803                 groupIndex++;\r
804 \r
805                 if (groupIndex >= av.alignment.getGroups().size())\r
806                 {\r
807                     break;\r
808                 }\r
809 \r
810                 group = (SequenceGroup) av.alignment.getGroups().elementAt(groupIndex);\r
811 \r
812                 g.setStroke(new BasicStroke());\r
813             }\r
814             while (groupIndex < av.alignment.getGroups().size());\r
815 \r
816         }\r
817 \r
818     }\r
819 \r
820     /**\r
821      * DOCUMENT ME!\r
822      *\r
823      * @param results DOCUMENT ME!\r
824      */\r
825     public void highlightSearchResults(SearchResults results)\r
826     {\r
827         img = null;\r
828 \r
829         searchResults = results;\r
830 \r
831         repaint();\r
832     }\r
833 }\r