Null pointers removed
[jalview.git] / src / jalview / gui / AnnotationPanel.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.event.*;\r
25 import java.awt.image.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 import javax.swing.*;\r
30 \r
31 \r
32 /**\r
33  * DOCUMENT ME!\r
34  *\r
35  * @author $author$\r
36  * @version $Revision$\r
37  */\r
38 public class AnnotationPanel extends JPanel implements MouseListener,\r
39     MouseMotionListener, ActionListener, AdjustmentListener\r
40 {\r
41     static String HELIX = "Helix";\r
42     static String SHEET = "Sheet";\r
43     static String LABEL = "Label";\r
44     static String REMOVE = "Remove Annotation";\r
45     static String COLOUR = "Colour";\r
46     static Color HELIX_COLOUR = Color.red.darker();\r
47     static Color SHEET_COLOUR = Color.green.darker().darker();\r
48 \r
49     /** DOCUMENT ME!! */\r
50     public static int GRAPH_HEIGHT = 40;\r
51     AlignViewport av;\r
52     AlignmentPanel ap;\r
53     int activeRow = -1;\r
54     Vector activeRes;\r
55     BufferedImage image;\r
56     Graphics2D gg;\r
57     FontMetrics fm;\r
58     int imgWidth = 0;\r
59     boolean fastPaint = false;\r
60 \r
61     /**\r
62      * Creates a new AnnotationPanel object.\r
63      *\r
64      * @param ap DOCUMENT ME!\r
65      */\r
66     public AnnotationPanel(AlignmentPanel ap)\r
67     {\r
68         ToolTipManager.sharedInstance().registerComponent(this);\r
69         ToolTipManager.sharedInstance().setInitialDelay(0);\r
70         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
71         this.ap = ap;\r
72         av = ap.av;\r
73         this.setLayout(null);\r
74         addMouseListener(this);\r
75         addMouseMotionListener(this);\r
76         ap.annotationScroller.getVerticalScrollBar().addAdjustmentListener(this);\r
77     }\r
78 \r
79     /**\r
80      * DOCUMENT ME!\r
81      *\r
82      * @param evt DOCUMENT ME!\r
83      */\r
84     public void adjustmentValueChanged(AdjustmentEvent evt)\r
85     {\r
86         ap.alabels.setScrollOffset(-evt.getValue());\r
87     }\r
88 \r
89     /**\r
90      * DOCUMENT ME!\r
91      */\r
92     public void adjustPanelHeight()\r
93     {\r
94         // setHeight of panels\r
95         image = null;\r
96         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
97         int height = 0;\r
98 \r
99         if (aa != null)\r
100         {\r
101             for (int i = 0; i < aa.length; i++)\r
102             {\r
103                 if (!aa[i].visible)\r
104                 {\r
105                     continue;\r
106                 }\r
107 \r
108                 aa[i].height = 0;\r
109 \r
110                 if (aa[i].hasText)\r
111                 {\r
112                     aa[i].height += av.charHeight;\r
113                 }\r
114 \r
115                 if (aa[i].hasIcons)\r
116                 {\r
117                     aa[i].height += 16;\r
118                 }\r
119 \r
120                 if (aa[i].isGraph)\r
121                 {\r
122                     aa[i].height += GRAPH_HEIGHT;\r
123                 }\r
124 \r
125                 if (aa[i].height == 0)\r
126                 {\r
127                     aa[i].height = 20;\r
128                 }\r
129 \r
130                 height += aa[i].height;\r
131             }\r
132         }\r
133         else\r
134         {\r
135             height = 20;\r
136         }\r
137 \r
138         this.setPreferredSize(new Dimension(1, height));\r
139     }\r
140 \r
141     /**\r
142      * DOCUMENT ME!\r
143      *\r
144      * @param col DOCUMENT ME!\r
145      */\r
146     public void removeEditableColumn(int col)\r
147     {\r
148         if (activeRow == -1)\r
149         {\r
150             AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
151             if(aa!=null)\r
152             for (int j = 0; j < aa.length; j++)\r
153             {\r
154                 if (aa[j].editable)\r
155                 {\r
156                     activeRow = j;\r
157 \r
158                     break;\r
159                 }\r
160             }\r
161         }\r
162 \r
163         if ((activeRes != null) && activeRes.contains(String.valueOf(col)))\r
164         {\r
165             activeRes.removeElement(String.valueOf(col));\r
166         }\r
167 \r
168         repaint();\r
169     }\r
170 \r
171     /**\r
172      * DOCUMENT ME!\r
173      *\r
174      * @param col DOCUMENT ME!\r
175      */\r
176     public void addEditableColumn(int col)\r
177     {\r
178         if (activeRow == -1)\r
179         {\r
180             AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
181             if(aa==null)\r
182               return;\r
183 \r
184             for (int j = 0; j < aa.length; j++)\r
185             {\r
186                 if (aa[j].editable)\r
187                 {\r
188                     activeRow = j;\r
189 \r
190                     break;\r
191                 }\r
192             }\r
193         }\r
194 \r
195         if (activeRes == null)\r
196         {\r
197             activeRes = new Vector();\r
198         }\r
199 \r
200         if (!activeRes.contains(String.valueOf(col)))\r
201         {\r
202             activeRes.addElement(String.valueOf(col));\r
203         }\r
204 \r
205         repaint();\r
206     }\r
207 \r
208     /**\r
209      * DOCUMENT ME!\r
210      *\r
211      * @param evt DOCUMENT ME!\r
212      */\r
213     public void actionPerformed(ActionEvent evt)\r
214     {\r
215         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
216         Annotation[] anot = aa[activeRow].annotations;\r
217 \r
218         if (evt.getActionCommand().equals(REMOVE))\r
219         {\r
220             for (int i = 0; i < activeRes.size(); i++)\r
221             {\r
222                 anot[Integer.parseInt(activeRes.get(i).toString())] = null;\r
223                 anot[Integer.parseInt(activeRes.get(i).toString())] = null;\r
224             }\r
225         }\r
226         else if (evt.getActionCommand().equals(LABEL))\r
227         {\r
228             String label = JOptionPane.showInputDialog(this, "Enter Label ",\r
229                     "Enter label", JOptionPane.QUESTION_MESSAGE);\r
230 \r
231             if (label == null)\r
232             {\r
233                 return;\r
234             }\r
235 \r
236             if ((label.length() > 0) && !aa[activeRow].hasText)\r
237             {\r
238                 aa[activeRow].hasText = true;\r
239             }\r
240 \r
241             for (int i = 0; i < activeRes.size(); i++)\r
242             {\r
243                 int index = Integer.parseInt(activeRes.get(i).toString());\r
244 \r
245                 if (anot[index] == null)\r
246                 {\r
247                     anot[index] = new Annotation(label, "", ' ', 0);\r
248                 }\r
249 \r
250                 anot[index].displayCharacter = label;\r
251             }\r
252         }\r
253         else if (evt.getActionCommand().equals(COLOUR))\r
254         {\r
255             Color col = JColorChooser.showDialog(this,\r
256                     "Choose foreground colour", Color.black);\r
257 \r
258             for (int i = 0; i < activeRes.size(); i++)\r
259             {\r
260                 int index = Integer.parseInt(activeRes.get(i).toString());\r
261 \r
262                 if (anot[index] == null)\r
263                 {\r
264                     anot[index] = new Annotation("", "", ' ', 0);\r
265                 }\r
266 \r
267                 anot[index].colour = col;\r
268             }\r
269         }\r
270         else // HELIX OR SHEET\r
271         {\r
272             char type = 0;\r
273             String symbol = "\u03B1";\r
274 \r
275             if (evt.getActionCommand().equals(HELIX))\r
276             {\r
277                 type = 'H';\r
278             }\r
279             else if (evt.getActionCommand().equals(SHEET))\r
280             {\r
281                 type = 'E';\r
282                 symbol = "\u03B2";\r
283             }\r
284 \r
285             if (!aa[activeRow].hasIcons)\r
286             {\r
287                 aa[activeRow].hasIcons = true;\r
288             }\r
289 \r
290             String label = JOptionPane.showInputDialog("Enter a label for the structure?",\r
291                     symbol);\r
292 \r
293             if (label == null)\r
294             {\r
295                 return;\r
296             }\r
297 \r
298             if ((label.length() > 0) && !aa[activeRow].hasText)\r
299             {\r
300                 aa[activeRow].hasText = true;\r
301             }\r
302 \r
303             for (int i = 0; i < activeRes.size(); i++)\r
304             {\r
305                 int index = Integer.parseInt(activeRes.get(i).toString());\r
306 \r
307                 if (anot[index] == null)\r
308                 {\r
309                     anot[index] = new Annotation(label, "", type, 0);\r
310                 }\r
311 \r
312                 anot[index].secondaryStructure = type;\r
313                 anot[index].displayCharacter = label;\r
314             }\r
315         }\r
316 \r
317         adjustPanelHeight();\r
318         activeRes = null;\r
319         repaint();\r
320 \r
321         return;\r
322     }\r
323 \r
324     /**\r
325      * DOCUMENT ME!\r
326      *\r
327      * @param evt DOCUMENT ME!\r
328      */\r
329     public void mousePressed(MouseEvent evt)\r
330     {\r
331         int height = 0;\r
332         activeRow = -1;\r
333 \r
334         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
335 \r
336         for (int i = 0; i < aa.length; i++)\r
337         {\r
338             if (aa[i].visible)\r
339             {\r
340               height += aa[i].height;\r
341             }\r
342 \r
343             if (evt.getY() < height)\r
344             {\r
345                 if (aa[i].editable)\r
346                 {\r
347                     activeRow = i;\r
348                 }\r
349                 else\r
350                 {\r
351                     activeRes = null;\r
352                 }\r
353 \r
354                 break;\r
355             }\r
356         }\r
357 \r
358         if (SwingUtilities.isRightMouseButton(evt))\r
359         {\r
360             if (activeRes == null)\r
361             {\r
362                 return;\r
363             }\r
364 \r
365             JPopupMenu pop = new JPopupMenu("Structure type");\r
366             JMenuItem item = new JMenuItem(HELIX);\r
367             item.addActionListener(this);\r
368             pop.add(item);\r
369             item = new JMenuItem(SHEET);\r
370             item.addActionListener(this);\r
371             pop.add(item);\r
372             item = new JMenuItem(LABEL);\r
373             item.addActionListener(this);\r
374             pop.add(item);\r
375             item = new JMenuItem(COLOUR);\r
376             item.addActionListener(this);\r
377             pop.add(item);\r
378             item = new JMenuItem(REMOVE);\r
379             item.addActionListener(this);\r
380             pop.add(item);\r
381             pop.show(this, evt.getX(), evt.getY());\r
382 \r
383             return;\r
384         }\r
385 \r
386         if (aa == null)\r
387         {\r
388             return;\r
389         }\r
390 \r
391         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
392 \r
393         if (evt.isControlDown() || evt.isAltDown())\r
394         {\r
395             addEditableColumn(res);\r
396         }\r
397         else if (evt.isShiftDown())\r
398         {\r
399             if (activeRes == null)\r
400             {\r
401                 activeRes = new Vector();\r
402             }\r
403             else\r
404             {\r
405                 int start = Integer.parseInt(activeRes.get(activeRes.size() -\r
406                             1).toString());\r
407                 int end = res;\r
408 \r
409                 if (end < start)\r
410                 {\r
411                     int temp = end;\r
412                     end = start;\r
413                     start = temp;\r
414                 }\r
415 \r
416                 for (int n = start; n <= end; n++)\r
417                 {\r
418                     addEditableColumn(n);\r
419                 }\r
420             }\r
421         }\r
422         else\r
423         {\r
424             activeRes = new Vector();\r
425             activeRes.addElement(String.valueOf(res));\r
426         }\r
427 \r
428         repaint();\r
429     }\r
430 \r
431     /**\r
432      * DOCUMENT ME!\r
433      *\r
434      * @param evt DOCUMENT ME!\r
435      */\r
436     public void mouseReleased(MouseEvent evt)\r
437     {\r
438     }\r
439 \r
440     /**\r
441      * DOCUMENT ME!\r
442      *\r
443      * @param evt DOCUMENT ME!\r
444      */\r
445     public void mouseEntered(MouseEvent evt)\r
446     {\r
447     }\r
448 \r
449     /**\r
450      * DOCUMENT ME!\r
451      *\r
452      * @param evt DOCUMENT ME!\r
453      */\r
454     public void mouseExited(MouseEvent evt)\r
455     {\r
456     }\r
457 \r
458     /**\r
459      * DOCUMENT ME!\r
460      *\r
461      * @param evt DOCUMENT ME!\r
462      */\r
463     public void mouseDragged(MouseEvent evt)\r
464     {\r
465     }\r
466 \r
467     /**\r
468      * DOCUMENT ME!\r
469      *\r
470      * @param evt DOCUMENT ME!\r
471      */\r
472     public void mouseMoved(MouseEvent evt)\r
473     {\r
474         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
475 \r
476         if (aa == null)\r
477         {\r
478             return;\r
479         }\r
480 \r
481         int row = -1;\r
482         int height = 0;\r
483 \r
484         for (int i = 0; i < aa.length; i++)\r
485         {\r
486             if (aa[i].visible)\r
487             {\r
488                 height += aa[i].height;\r
489             }\r
490 \r
491             if (evt.getY() < height)\r
492             {\r
493                 row = i;\r
494 \r
495                 break;\r
496             }\r
497         }\r
498 \r
499         int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
500 \r
501         if ((row > -1) && (res < aa[row].annotations.length) &&\r
502                 (aa[row].annotations[res] != null))\r
503         {\r
504             this.setToolTipText(aa[row].annotations[res].description);\r
505 \r
506             StringBuffer text = new StringBuffer("Sequence position " +\r
507                     (res + 1) + "  " + aa[row].annotations[res].description);\r
508             ap.alignFrame.statusBar.setText(text.toString());\r
509         }\r
510     }\r
511 \r
512     /**\r
513      * DOCUMENT ME!\r
514      *\r
515      * @param evt DOCUMENT ME!\r
516      */\r
517     public void mouseClicked(MouseEvent evt)\r
518     {\r
519     }\r
520 \r
521     /**\r
522      * DOCUMENT ME!\r
523      *\r
524      * @param g DOCUMENT ME!\r
525      */\r
526     public void paintComponent(Graphics g)\r
527     {\r
528       g.setColor(Color.white);\r
529       g.fillRect(0, 0, getWidth(), getHeight());\r
530 \r
531       if (fastPaint)\r
532       {\r
533         g.drawImage(image, 0, 0, this);\r
534         fastPaint = false;\r
535         return;\r
536       }\r
537 \r
538       imgWidth = (av.endRes - av.startRes + 1) * av.charWidth;\r
539 \r
540       if (image == null || imgWidth != image.getWidth())\r
541       {\r
542         image = new BufferedImage(imgWidth, ap.annotationPanel.getHeight(),\r
543                                   BufferedImage.TYPE_INT_RGB);\r
544         gg = (Graphics2D) image.getGraphics();\r
545         gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
546                             RenderingHints.VALUE_ANTIALIAS_ON);\r
547 \r
548         gg.setFont(av.getFont());\r
549         fm = gg.getFontMetrics();\r
550       }\r
551 \r
552       drawComponent(gg, av.startRes, av.endRes + 1);\r
553       g.drawImage(image, 0, 0, this);\r
554     }\r
555 \r
556     /**\r
557      * DOCUMENT ME!\r
558      *\r
559      * @param horizontal DOCUMENT ME!\r
560      */\r
561     public void fastPaint(int horizontal)\r
562     {\r
563         if ((horizontal == 0) ||\r
564                 (av.alignment.getAlignmentAnnotation() == null) ||\r
565                 (av.alignment.getAlignmentAnnotation().length < 1))\r
566         {\r
567             repaint();\r
568 \r
569             return;\r
570         }\r
571 \r
572         gg.copyArea(0, 0, imgWidth, getHeight(), -horizontal * av.charWidth, 0);\r
573 \r
574         int sr = av.startRes;\r
575         int er = av.endRes + 1;\r
576         int transX = 0;\r
577 \r
578         if (horizontal > 0) // scrollbar pulled right, image to the left\r
579         {\r
580             transX = (er - sr - horizontal) * av.charWidth;\r
581             sr = er - horizontal;\r
582         }\r
583         else if (horizontal < 0)\r
584         {\r
585             er = sr - horizontal;\r
586         }\r
587 \r
588         gg.translate(transX, 0);\r
589 \r
590         drawComponent(gg, sr, er);\r
591 \r
592         gg.translate(-transX, 0);\r
593 \r
594         fastPaint = true;\r
595 \r
596         repaint();\r
597 \r
598     }\r
599 \r
600     /**\r
601      * DOCUMENT ME!\r
602      *\r
603      * @param g DOCUMENT ME!\r
604      * @param startRes DOCUMENT ME!\r
605      * @param endRes DOCUMENT ME!\r
606      */\r
607     public void drawComponent(Graphics2D g, int startRes, int endRes)\r
608     {\r
609         g.setColor(Color.white);\r
610         g.fillRect(0, 0, (endRes - startRes) * av.charWidth, getHeight());\r
611 \r
612         if ((av.alignment.getAlignmentAnnotation() == null) ||\r
613                 (av.alignment.getAlignmentAnnotation().length < 1))\r
614         {\r
615             g.setColor(Color.white);\r
616             g.fillRect(0, 0, getWidth(), getHeight());\r
617             g.setColor(Color.black);\r
618             g.drawString("Alignment has no annotations", 20, 15);\r
619 \r
620             return;\r
621         }\r
622 \r
623         AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();\r
624 \r
625         int j;\r
626         int x = 0;\r
627         int y = 0;\r
628         char[] lastSS = new char[aa.length];\r
629         int[] lastSSX = new int[aa.length];\r
630         int iconOffset = av.charHeight / 2;\r
631         boolean validRes = false;\r
632 \r
633         //\u03B2 \u03B1\r
634         for (int i = 0; i < aa.length; i++)\r
635         {\r
636             AlignmentAnnotation row = aa[i];\r
637 \r
638             if (!row.visible)\r
639             {\r
640                 continue;\r
641             }\r
642 \r
643 \r
644             if (row.isGraph)\r
645             {\r
646                 // this is so that we draw the characters below the graph\r
647                 y += row.height;\r
648 \r
649                 if (row.hasText)\r
650                 {\r
651                     y -= av.charHeight;\r
652                 }\r
653             }\r
654 \r
655             if (row.hasText)\r
656             {\r
657                 iconOffset = av.charHeight / 2;\r
658             }\r
659             else\r
660             {\r
661                 iconOffset = 0;\r
662             }\r
663 \r
664             for (j = startRes; j < endRes; j++)\r
665             {\r
666                 if ((row.annotations.length <= j) ||\r
667                         (row.annotations[j] == null))\r
668                 {\r
669                     validRes = false;\r
670                 }\r
671                 else\r
672                 {\r
673                     validRes = true;\r
674                 }\r
675 \r
676                 x = (j - startRes) * av.charWidth;\r
677 \r
678                 if (activeRow == i)\r
679                 {\r
680                     g.setColor(Color.red);\r
681 \r
682                     if (activeRes != null)\r
683                     {\r
684                         for (int n = 0; n < activeRes.size(); n++)\r
685                         {\r
686                             int v = Integer.parseInt(activeRes.get(n).toString());\r
687 \r
688                             if (v == j)\r
689                             {\r
690                                 g.fillRect((j - startRes) * av.charWidth, y,\r
691                                     av.charWidth, row.height);\r
692                             }\r
693                         }\r
694                     }\r
695                 }\r
696 \r
697                 if (validRes &&\r
698                         (row.annotations[j].displayCharacter.length() > 0))\r
699                 {\r
700 \r
701                     int charOffset = (av.charWidth -\r
702                         fm.charWidth(row.annotations[j].displayCharacter.charAt(\r
703                                 0))) / 2;\r
704                     g.setColor(row.annotations[j].colour);\r
705 \r
706                     if (j == 0 || row.isGraph)\r
707                     {\r
708                         g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
709                             y + iconOffset + 3);\r
710                     }\r
711                     else if (((row.annotations[j - 1] == null) ||\r
712                             (row.annotations[j].displayCharacter != row.annotations[j -\r
713                             1].displayCharacter)))\r
714                     {\r
715                         g.drawString(row.annotations[j].displayCharacter, x+charOffset,\r
716                             y + iconOffset + 3);\r
717                     }\r
718                 }\r
719 \r
720                 if (row.hasIcons)\r
721                 {\r
722                     if (!validRes ||\r
723                             (row.annotations[j].secondaryStructure != lastSS[i]))\r
724                     {\r
725                         switch (lastSS[i])\r
726                         {\r
727                         case 'H':\r
728                             g.setColor(HELIX_COLOUR);\r
729                             g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
730                                 x - lastSSX[i], 7, 8, 8);\r
731 \r
732                             break;\r
733 \r
734                         case 'E':\r
735                             g.setColor(SHEET_COLOUR);\r
736                             g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
737                                 x - lastSSX[i] - 4, 7);\r
738                             g.fillPolygon(new int[] { x - 4, x - 4, x },\r
739                                 new int[]\r
740                                 {\r
741                                     y + iconOffset, y + 14 + iconOffset,\r
742                                     y + 8 + iconOffset\r
743                                 }, 3);\r
744 \r
745                             break;\r
746 \r
747                         case 'C':\r
748                             break;\r
749 \r
750                         default:\r
751                             g.setColor(Color.gray);\r
752                             g.fillRect(lastSSX[i], y + 6 + iconOffset,\r
753                                 x - lastSSX[i], 2);\r
754 \r
755                             break;\r
756                         }\r
757 \r
758                         if (validRes)\r
759                         {\r
760                             lastSS[i] = row.annotations[j].secondaryStructure;\r
761                         }\r
762                         else\r
763                         {\r
764                             lastSS[i] = ' ';\r
765                         }\r
766 \r
767                         lastSSX[i] = x;\r
768                     }\r
769                 }\r
770 \r
771                 if (validRes && row.isGraph)\r
772                 {\r
773                     g.setColor(new Color(0, 0, 180));\r
774 \r
775                     int height = (int) ((row.annotations[j].value / row.graphMax) * GRAPH_HEIGHT);\r
776 \r
777                     if (row.windowLength > 1)\r
778                     {\r
779                         int total = 0;\r
780 \r
781                         for (int i2 = j - (row.windowLength / 2);\r
782                                 i2 < (j + (row.windowLength / 2)); i2++)\r
783                         {\r
784                             if ((i2 < 0) || (i2 >= av.alignment.getWidth()))\r
785                             {\r
786                                 continue;\r
787                             }\r
788 \r
789                             total += row.annotations[i2].value;\r
790                         }\r
791 \r
792                         total /= row.windowLength;\r
793                         height = (int) ((total / row.graphMax) * GRAPH_HEIGHT);\r
794                     }\r
795 \r
796                     g.setColor(row.annotations[j].colour);\r
797                     g.fillRect(x, y - height, av.charWidth, height);\r
798                 }\r
799             }\r
800 \r
801             x += av.charWidth;\r
802 \r
803             if (row.hasIcons)\r
804             {\r
805                 switch (lastSS[i])\r
806                 {\r
807                 case 'H':\r
808                     g.setColor(HELIX_COLOUR);\r
809                     g.fillRoundRect(lastSSX[i], y + 4 + iconOffset,\r
810                         x - lastSSX[i], 7, 8, 8);\r
811 \r
812                     break;\r
813 \r
814                 case 'E':\r
815                     g.setColor(SHEET_COLOUR);\r
816                     g.fillRect(lastSSX[i], y + 4 + iconOffset,\r
817                         x - lastSSX[i] - 4, 7);\r
818                     g.fillPolygon(new int[] { x - 4, x - 4, x },\r
819                         new int[]\r
820                         {\r
821                             y + iconOffset, y + 14 + iconOffset,\r
822                             y + 7 + iconOffset\r
823                         }, 3);\r
824 \r
825                     break;\r
826 \r
827                 case 'C':\r
828                     break;\r
829 \r
830                 default:\r
831                     g.setColor(Color.gray);\r
832                     g.fillRect(lastSSX[i], y + 6 + iconOffset, x - lastSSX[i], 2);\r
833 \r
834                     break;\r
835                 }\r
836             }\r
837 \r
838             if (row.isGraph && row.hasText)\r
839             {\r
840                 y += av.charHeight;\r
841             }\r
842 \r
843             if (!row.isGraph)\r
844             {\r
845                 y += aa[i].height;\r
846             }\r
847         }\r
848     }\r
849 \r
850     // used by overview window\r
851     public void drawGraph(Graphics g, AlignmentAnnotation aa, int width, int y, int sRes, int eRes)\r
852     {\r
853         g.setColor(Color.white);\r
854         g.fillRect(0, 0, width, y);\r
855         g.setColor(new Color(0, 0, 180));\r
856 \r
857 \r
858         int x = 0, height;\r
859 \r
860         for (int j = sRes; j < eRes; j++)\r
861         {\r
862             g.setColor(new Color(0, 0, 180));\r
863 \r
864             height = (int) ((aa.annotations[j].value / aa.graphMax) * GRAPH_HEIGHT);\r
865             if(height>y)\r
866               height = y;\r
867 \r
868             g.fillRect(x, y - height, av.charWidth, height);\r
869             x += av.charWidth;\r
870         }\r
871     }\r
872 }\r