Formatting changes
[jalview.git] / src / jalview / gui / AlignmentPanel.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.analysis.*;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 import jalview.jbgui.*;\r
26 \r
27 import jalview.schemes.*;\r
28 \r
29 import org.jibble.epsgraphics.*;\r
30 \r
31 import java.awt.*;\r
32 import java.awt.event.*;\r
33 import java.awt.image.*;\r
34 import java.awt.print.*;\r
35 \r
36 import java.io.*;\r
37 \r
38 import javax.imageio.*;\r
39 \r
40 import javax.swing.*;\r
41 \r
42 \r
43 /**\r
44  * DOCUMENT ME!\r
45  *\r
46  * @author $author$\r
47  * @version $Revision$\r
48  */\r
49 public class AlignmentPanel extends GAlignmentPanel\r
50     implements AdjustmentListener, Printable\r
51 {\r
52     AlignViewport av;\r
53     OverviewPanel overviewPanel;\r
54     SeqPanel seqPanel;\r
55     IdPanel idPanel;\r
56     IdwidthAdjuster idwidthAdjuster;\r
57 \r
58     /** DOCUMENT ME!! */\r
59     public AlignFrame alignFrame;\r
60     ScalePanel scalePanel;\r
61     AnnotationPanel annotationPanel;\r
62     AnnotationLabels alabels;\r
63 \r
64     // this value is set false when selection area being dragged\r
65     boolean fastPaint = true;\r
66     int hextent = 0;\r
67     int vextent = 0;\r
68 \r
69     /**\r
70      * Creates a new AlignmentPanel object.\r
71      *\r
72      * @param af DOCUMENT ME!\r
73      * @param av DOCUMENT ME!\r
74      */\r
75     public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
76     {\r
77         alignFrame = af;\r
78         this.av = av;\r
79         seqPanel = new SeqPanel(av, this);\r
80         idPanel = new IdPanel(av, this);\r
81 \r
82         scalePanel = new ScalePanel(av, this);\r
83 \r
84         idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
85         idwidthAdjuster = new IdwidthAdjuster(this);\r
86         idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
87 \r
88         annotationPanel = new AnnotationPanel(this);\r
89         alabels = new AnnotationLabels(this);\r
90 \r
91         annotationSpaceFillerHolder.setPreferredSize(annotationPanel.getPreferredSize());\r
92         annotationScroller.setPreferredSize(annotationPanel.getPreferredSize());\r
93         annotationScroller.setViewportView(annotationPanel);\r
94         annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
95 \r
96         fontChanged();\r
97 \r
98         scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
99         seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
100 \r
101         setScrollValues(0, 0);\r
102 \r
103         hscroll.addAdjustmentListener(this);\r
104         vscroll.addAdjustmentListener(this);\r
105 \r
106         setFocusable(true);\r
107         addKeyListener(new KeyAdapter()\r
108             {\r
109                 public void keyPressed(KeyEvent evt)\r
110                 {\r
111                     switch (evt.getKeyCode())\r
112                     {\r
113                     case 27: // escape key\r
114                         av.setSelectionGroup(null);\r
115                         repaint();\r
116 \r
117                         break;\r
118 \r
119                     case KeyEvent.VK_DOWN:\r
120                         alignFrame.moveSelectedSequences(false);\r
121 \r
122                         break;\r
123 \r
124                     case KeyEvent.VK_UP:\r
125                         alignFrame.moveSelectedSequences(true);\r
126 \r
127                         break;\r
128                     }\r
129                 }\r
130             });\r
131     }\r
132 \r
133     /**\r
134      * DOCUMENT ME!\r
135      */\r
136     public void fontChanged()\r
137     {\r
138         // set idCanvas bufferedImage to null\r
139         // to prevent drawing old image\r
140         FontMetrics fm = getFontMetrics(av.getFont());\r
141 \r
142         scalePanelHolder.setPreferredSize(new Dimension(10,\r
143                 av.charHeight + fm.getDescent()));\r
144         idSpaceFillerPanel1.setPreferredSize(new Dimension(10,\r
145                 av.charHeight + fm.getDescent()));\r
146 \r
147         idPanel.idCanvas.gg = null;\r
148         annotationPanel.adjustPanelHeight();\r
149 \r
150         Dimension d = calculateIdWidth();\r
151         d.setSize(d.width + 4, d.height);\r
152         idPanel.idCanvas.setPreferredSize(d);\r
153         hscrollFillerPanel.setPreferredSize(d);\r
154         repaint();\r
155     }\r
156 \r
157     /**\r
158      * DOCUMENT ME!\r
159      *\r
160      * @return DOCUMENT ME!\r
161      */\r
162     public Dimension calculateIdWidth()\r
163     {\r
164         Graphics g = this.getGraphics();\r
165 \r
166         if (g == null)\r
167         {\r
168             javax.swing.JFrame f = new javax.swing.JFrame();\r
169             f.addNotify();\r
170             g = f.getGraphics();\r
171         }\r
172 \r
173         FontMetrics fm = g.getFontMetrics(av.font);\r
174         AlignmentI al = av.getAlignment();\r
175 \r
176         int i = 0;\r
177         int idWidth = 0;\r
178         String id;\r
179 \r
180         while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))\r
181         {\r
182             SequenceI s = al.getSequenceAt(i);\r
183 \r
184             if (av.getShowFullId())\r
185             {\r
186                 id = s.getDisplayId();\r
187             }\r
188             else\r
189             {\r
190                 id = s.getName();\r
191             }\r
192 \r
193             if (fm.stringWidth(id) > idWidth)\r
194             {\r
195                 idWidth = fm.stringWidth(id);\r
196             }\r
197 \r
198             i++;\r
199         }\r
200 \r
201         // Also check annotation label widths\r
202         i = 0;\r
203 \r
204         if (al.getAlignmentAnnotation() != null)\r
205         {\r
206             fm = g.getFontMetrics(alabels.getFont());\r
207 \r
208             while (i < al.getAlignmentAnnotation().length)\r
209             {\r
210                 String label = al.getAlignmentAnnotation()[i].label;\r
211 \r
212                 if (fm.stringWidth(label) > idWidth)\r
213                 {\r
214                     idWidth = fm.stringWidth(label);\r
215                 }\r
216 \r
217                 i++;\r
218             }\r
219         }\r
220 \r
221         return new Dimension(idWidth, 12);\r
222     }\r
223 \r
224     /**\r
225      * DOCUMENT ME!\r
226      *\r
227      * @param results DOCUMENT ME!\r
228      */\r
229     public void highlightSearchResults(int[] results)\r
230     {\r
231         seqPanel.seqCanvas.highlightSearchResults(results);\r
232 \r
233         // do we need to scroll the panel?\r
234         if (results != null)\r
235         {\r
236             SequenceI seq = av.alignment.getSequenceAt(results[0]);\r
237             int start = seq.findIndex(results[1]) - 1;\r
238             int end = seq.findIndex(results[2]) - 1;\r
239 \r
240             if ((av.getStartRes() > start) || (av.getEndRes() < end) ||\r
241                     ((av.getStartSeq() > results[0]) ||\r
242                     (av.getEndSeq() < results[0])))\r
243             {\r
244                 setScrollValues(start, results[0]);\r
245             }\r
246         }\r
247     }\r
248 \r
249     /**\r
250      * DOCUMENT ME!\r
251      *\r
252      * @return DOCUMENT ME!\r
253      */\r
254     public OverviewPanel getOverviewPanel()\r
255     {\r
256         return overviewPanel;\r
257     }\r
258 \r
259     /**\r
260      * DOCUMENT ME!\r
261      *\r
262      * @param op DOCUMENT ME!\r
263      */\r
264     public void setOverviewPanel(OverviewPanel op)\r
265     {\r
266         overviewPanel = op;\r
267     }\r
268 \r
269     /**\r
270      * DOCUMENT ME!\r
271      *\r
272      * @param b DOCUMENT ME!\r
273      */\r
274     public void setAnnotationVisible(boolean b)\r
275     {\r
276         annotationSpaceFillerHolder.setVisible(b);\r
277         annotationScroller.setVisible(b);\r
278     }\r
279 \r
280     /**\r
281      * DOCUMENT ME!\r
282      *\r
283      * @param wrap DOCUMENT ME!\r
284      */\r
285     public void setWrapAlignment(boolean wrap)\r
286     {\r
287         scalePanelHolder.setVisible(!wrap);\r
288         hscroll.setVisible(!wrap);\r
289         idwidthAdjuster.setVisible(!wrap);\r
290 \r
291         av.setShowAnnotation(!wrap);\r
292         annotationScroller.setVisible(!wrap);\r
293         annotationSpaceFillerHolder.setVisible(!wrap);\r
294         idSpaceFillerPanel1.setVisible(!wrap);\r
295 \r
296         repaint();\r
297     }\r
298 \r
299     /**\r
300      * DOCUMENT ME!\r
301      */\r
302     public void setColourScheme()\r
303     {\r
304         ColourSchemeI cs = av.getGlobalColourScheme();\r
305 \r
306         if (av.getConservationSelected())\r
307         {\r
308             Alignment al = (Alignment) av.getAlignment();\r
309             Conservation c = new Conservation("All",\r
310                     ResidueProperties.propHash, 3, al.getSequences(), 0,\r
311                     al.getWidth());\r
312 \r
313             c.calculate();\r
314             c.verdict(false, av.ConsPercGaps);\r
315 \r
316             ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
317 \r
318             av.setGlobalColourScheme(ccs);\r
319         }\r
320 \r
321         repaint();\r
322     }\r
323 \r
324     // return value is true if the scroll is valid\r
325     public boolean scrollUp(boolean up)\r
326     {\r
327         if (up)\r
328         {\r
329             if (vscroll.getValue() < 1)\r
330             {\r
331                 return false;\r
332             }\r
333 \r
334             fastPaint = false;\r
335             vscroll.setValue(vscroll.getValue() - 1);\r
336         }\r
337         else\r
338         {\r
339             if ((vextent + vscroll.getValue()) >= av.getAlignment().getHeight())\r
340             {\r
341                 return false;\r
342             }\r
343 \r
344             fastPaint = false;\r
345             vscroll.setValue(vscroll.getValue() + 1);\r
346         }\r
347 \r
348         fastPaint = true;\r
349 \r
350         return true;\r
351     }\r
352 \r
353     /**\r
354      * DOCUMENT ME!\r
355      *\r
356      * @param right DOCUMENT ME!\r
357      *\r
358      * @return DOCUMENT ME!\r
359      */\r
360     public boolean scrollRight(boolean right)\r
361     {\r
362         if (right)\r
363         {\r
364             if (hscroll.getValue() < 1)\r
365             {\r
366                 return false;\r
367             }\r
368 \r
369             fastPaint = false;\r
370             hscroll.setValue(hscroll.getValue() - 1);\r
371         }\r
372         else\r
373         {\r
374             if ((hextent + hscroll.getValue()) >= av.getAlignment().getWidth())\r
375             {\r
376                 return false;\r
377             }\r
378 \r
379             fastPaint = false;\r
380             hscroll.setValue(hscroll.getValue() + 1);\r
381         }\r
382 \r
383         fastPaint = true;\r
384 \r
385         return true;\r
386     }\r
387 \r
388     /**\r
389      * DOCUMENT ME!\r
390      *\r
391      * @param x DOCUMENT ME!\r
392      * @param y DOCUMENT ME!\r
393      */\r
394     public void setScrollValues(int x, int y)\r
395     {\r
396         av.setEndRes((x + (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) -\r
397             1);\r
398 \r
399         hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;\r
400         vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;\r
401 \r
402         if (hextent > av.alignment.getWidth())\r
403         {\r
404             hextent = av.alignment.getWidth();\r
405         }\r
406 \r
407         if (vextent > av.alignment.getHeight())\r
408         {\r
409             vextent = av.alignment.getHeight();\r
410         }\r
411 \r
412         if ((hextent + x) > av.getAlignment().getWidth())\r
413         {\r
414             x = av.getAlignment().getWidth() - hextent;\r
415         }\r
416 \r
417         if ((vextent + y) > av.getAlignment().getHeight())\r
418         {\r
419             y = av.getAlignment().getHeight() - vextent;\r
420         }\r
421 \r
422         if (y < 0)\r
423         {\r
424             y = 0;\r
425         }\r
426 \r
427         if (x < 0)\r
428         {\r
429             x = 0;\r
430         }\r
431 \r
432         hscroll.setValues(x, hextent, 0, av.getAlignment().getWidth());\r
433         vscroll.setValues(y, vextent, 0, av.getAlignment().getHeight());\r
434     }\r
435 \r
436     public void this_mouseWheelMoved(MouseWheelEvent e)\r
437     {\r
438       if(e.getWheelRotation()>0)\r
439         scrollUp(false);\r
440       else\r
441         scrollUp(true);\r
442     }\r
443 \r
444 \r
445     /**\r
446      * DOCUMENT ME!\r
447      *\r
448      * @param evt DOCUMENT ME!\r
449      */\r
450     public void adjustmentValueChanged(AdjustmentEvent evt)\r
451     {\r
452         int oldX = av.getStartRes();\r
453         int oldY = av.getStartSeq();\r
454 \r
455         if (evt.getSource() == hscroll)\r
456         {\r
457             int x = hscroll.getValue();\r
458             av.setStartRes(x);\r
459             av.setEndRes((x +\r
460                 (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);\r
461         }\r
462 \r
463         if (evt.getSource() == vscroll)\r
464         {\r
465             int offy = vscroll.getValue();\r
466 \r
467             if (av.getWrapAlignment())\r
468             {\r
469                 int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
470                 av.setStartRes(vscroll.getValue() * rowSize);\r
471                 av.setEndRes((vscroll.getValue() + 1) * rowSize);\r
472             }\r
473             else\r
474             {\r
475                 av.setStartSeq(offy);\r
476                 av.setEndSeq(offy +\r
477                     (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));\r
478             }\r
479         }\r
480 \r
481         if (overviewPanel != null)\r
482         {\r
483             overviewPanel.setBoxPosition();\r
484         }\r
485 \r
486         if (av.getWrapAlignment() || !fastPaint)\r
487         {\r
488             repaint();\r
489         }\r
490         else\r
491         {\r
492             idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
493             seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
494                 av.getStartSeq() - oldY);\r
495 \r
496             scalePanel.repaint();\r
497 \r
498             if (av.getShowAnnotation())\r
499             {\r
500                 annotationPanel.fastPaint(av.getStartRes() - oldX);\r
501             }\r
502         }\r
503     }\r
504 \r
505     /**\r
506      * DOCUMENT ME!\r
507      *\r
508      * @param g DOCUMENT ME!\r
509      */\r
510     public void paintComponent(Graphics g)\r
511     {\r
512         invalidate();\r
513 \r
514         Dimension d = idPanel.idCanvas.getPreferredSize();\r
515         idPanelHolder.setPreferredSize(d);\r
516         hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
517         validate();\r
518 \r
519         if (av.getWrapAlignment())\r
520         {\r
521             int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
522             vscroll.setMaximum(max);\r
523             vscroll.setUnitIncrement(1);\r
524             vscroll.setVisibleAmount(1);\r
525         }\r
526         else\r
527         {\r
528             setScrollValues(av.getStartRes(), av.getStartSeq());\r
529         }\r
530     }\r
531 \r
532     /**\r
533      * DOCUMENT ME!\r
534      *\r
535      * @param pg DOCUMENT ME!\r
536      * @param pf DOCUMENT ME!\r
537      * @param pi DOCUMENT ME!\r
538      *\r
539      * @return DOCUMENT ME!\r
540      *\r
541      * @throws PrinterException DOCUMENT ME!\r
542      */\r
543     public int print(Graphics pg, PageFormat pf, int pi)\r
544         throws PrinterException\r
545     {\r
546         pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());\r
547 \r
548         int pwidth = (int) pf.getImageableWidth();\r
549         int pheight = (int) pf.getImageableHeight();\r
550 \r
551         if (av.getWrapAlignment())\r
552         {\r
553             return printWrappedAlignment(pg, pwidth, pheight, pi);\r
554         }\r
555         else\r
556         {\r
557             return printUnwrapped(pg, pwidth, pheight, pi);\r
558         }\r
559     }\r
560 \r
561     /**\r
562      * DOCUMENT ME!\r
563      *\r
564      * @param pg DOCUMENT ME!\r
565      * @param pwidth DOCUMENT ME!\r
566      * @param pheight DOCUMENT ME!\r
567      * @param pi DOCUMENT ME!\r
568      *\r
569      * @return DOCUMENT ME!\r
570      *\r
571      * @throws PrinterException DOCUMENT ME!\r
572      */\r
573     public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)\r
574         throws PrinterException\r
575     {\r
576         int idWidth = calculateIdWidth().width + 4;\r
577         FontMetrics fm = getFontMetrics(av.getFont());\r
578         int scaleHeight = av.charHeight + fm.getDescent();\r
579 \r
580         pg.setColor(Color.white);\r
581         pg.fillRect(0, 0, pwidth, pheight);\r
582         pg.setFont(av.getFont());\r
583 \r
584         ////////////////////////////////////\r
585         /// How many sequences and residues can we fit on a printable page?\r
586         int totalRes = (pwidth - idWidth) / av.getCharWidth();\r
587 \r
588         int totalSeq = (int) ((pheight - scaleHeight) / av.getCharHeight()) -\r
589             1;\r
590 \r
591         int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;\r
592 \r
593         /////////////////////////////\r
594         /// Only print these sequences and residues on this page\r
595         int startRes;\r
596 \r
597         /////////////////////////////\r
598         /// Only print these sequences and residues on this page\r
599         int endRes;\r
600 \r
601         /////////////////////////////\r
602         /// Only print these sequences and residues on this page\r
603         int startSeq;\r
604 \r
605         /////////////////////////////\r
606         /// Only print these sequences and residues on this page\r
607         int endSeq;\r
608         startRes = (pi % pagesWide) * totalRes;\r
609         endRes = (startRes + totalRes) - 1;\r
610 \r
611         if (endRes > (av.getAlignment().getWidth() - 1))\r
612         {\r
613             endRes = av.getAlignment().getWidth() - 1;\r
614         }\r
615 \r
616         startSeq = (pi / pagesWide) * totalSeq;\r
617         endSeq = startSeq + totalSeq;\r
618 \r
619         if (endSeq > av.getAlignment().getHeight())\r
620         {\r
621             endSeq = av.getAlignment().getHeight();\r
622         }\r
623 \r
624         int pagesHigh = ((av.alignment.getHeight() / totalSeq) + 1) * pheight;\r
625 \r
626         if (av.showAnnotation)\r
627         {\r
628             pagesHigh += annotationPanel.getHeight();\r
629         }\r
630 \r
631         pagesHigh /= pheight;\r
632 \r
633         if (pi >= (pagesWide * pagesHigh))\r
634         {\r
635             return Printable.NO_SUCH_PAGE;\r
636         }\r
637 \r
638         //draw Scale\r
639         pg.translate(idWidth, 0);\r
640         scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth, scaleHeight);\r
641         pg.translate(-idWidth, scaleHeight);\r
642 \r
643         ////////////////\r
644         // Draw the ids\r
645         Color currentColor = null;\r
646         Color currentTextColor = null;\r
647 \r
648         for (int i = startSeq; i < endSeq; i++)\r
649         {\r
650             if ((av.getSelectionGroup() != null) &&\r
651                     av.getSelectionGroup().sequences.contains(\r
652                         av.getAlignment().getSequenceAt(i)))\r
653             {\r
654                 currentColor = Color.gray;\r
655                 currentTextColor = Color.black;\r
656             }\r
657             else\r
658             {\r
659                 currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
660                 currentTextColor = Color.black;\r
661             }\r
662 \r
663             pg.setColor(currentColor);\r
664             pg.fillRect(0, (i-startSeq) * av.charHeight, idWidth,\r
665                 av.getCharHeight());\r
666 \r
667             pg.setColor(currentTextColor);\r
668 \r
669             String string = av.getAlignment().getSequenceAt(i).getName();\r
670 \r
671             if (av.getShowFullId())\r
672             {\r
673                 string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
674             }\r
675 \r
676             pg.drawString(string, 0,\r
677                 (((i-startSeq) * av.charHeight) + av.getCharHeight()) -\r
678                 (av.getCharHeight() / 5));\r
679         }\r
680 \r
681         // draw main sequence panel\r
682         pg.translate(idWidth, 0);\r
683         seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq,\r
684             startRes, startSeq, 0);\r
685 \r
686         if (av.showAnnotation && (endSeq == av.alignment.getHeight()))\r
687         {\r
688             pg.translate(-idWidth, (endSeq - startSeq) * av.charHeight);\r
689             alabels.drawComponent((Graphics2D) pg);\r
690             pg.translate(idWidth, 0);\r
691             annotationPanel.drawComponent((Graphics2D) pg, startRes, endRes +\r
692                 1);\r
693         }\r
694 \r
695         return Printable.PAGE_EXISTS;\r
696     }\r
697 \r
698     /**\r
699      * DOCUMENT ME!\r
700      *\r
701      * @param pg DOCUMENT ME!\r
702      * @param pwidth DOCUMENT ME!\r
703      * @param pheight DOCUMENT ME!\r
704      * @param pi DOCUMENT ME!\r
705      *\r
706      * @return DOCUMENT ME!\r
707      *\r
708      * @throws PrinterException DOCUMENT ME!\r
709      */\r
710     public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,\r
711         int pi) throws PrinterException\r
712     {\r
713         int idWidth = calculateIdWidth().width + 4;\r
714 \r
715         int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -\r
716                 idWidth);\r
717         int totalHeight = totalHeight = (av.alignment.getHeight() + 2) * ((av.alignment.getWidth() / resWidth) +\r
718                 1) * av.charHeight;\r
719 \r
720         pg.setColor(Color.white);\r
721         pg.fillRect(0, 0, pwidth, pheight);\r
722         pg.setFont(av.getFont());\r
723 \r
724         ////////////////\r
725         // Draw the ids\r
726         pg.setColor(Color.black);\r
727 \r
728         pg.translate(0, -pi * pheight);\r
729 \r
730         pg.setClip(0, pi * pheight, pwidth, pheight);\r
731 \r
732         int ypos = 2 * av.charHeight;\r
733 \r
734         do\r
735         {\r
736             for (int i = 0; i < av.alignment.getHeight(); i++)\r
737             {\r
738                 SequenceI s = av.alignment.getSequenceAt(i);\r
739                 String string = s.getName();\r
740 \r
741                 if (av.getShowFullId())\r
742                 {\r
743                     string = s.getDisplayId();\r
744                 }\r
745 \r
746                 pg.drawString(string, 0,\r
747                     ((i * av.charHeight) + ypos + av.charHeight) -\r
748                     (av.charHeight / 5));\r
749             }\r
750 \r
751             ypos += ((av.alignment.getHeight() + 2) * av.charHeight);\r
752         }\r
753         while (ypos < totalHeight);\r
754 \r
755         pg.translate(idWidth, 0);\r
756 \r
757         seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight, 0);\r
758 \r
759         if ((pi * pheight) < totalHeight)\r
760         {\r
761             return Printable.PAGE_EXISTS;\r
762         }\r
763         else\r
764         {\r
765             return Printable.NO_SUCH_PAGE;\r
766         }\r
767     }\r
768 \r
769     /**\r
770      * DOCUMENT ME!\r
771      */\r
772     public void makeEPS(File epsFile)\r
773     {\r
774         if(epsFile == null)\r
775         {\r
776           jalview.io.JalviewFileChooser chooser = new jalview.io.\r
777               JalviewFileChooser(jalview.bin.Cache.getProperty(\r
778                   "LAST_DIRECTORY"), new String[]\r
779                                  {"eps"},\r
780                                  new String[]\r
781                                  {"Encapsulated Postscript"},\r
782                                  "Encapsulated Postscript");\r
783           chooser.setFileView(new jalview.io.JalviewFileView());\r
784           chooser.setDialogTitle("Create EPS file from alignment");\r
785           chooser.setToolTipText("Save");\r
786 \r
787           int value = chooser.showSaveDialog(this);\r
788 \r
789           if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
790           {\r
791             return;\r
792           }\r
793 \r
794           epsFile = chooser.getSelectedFile();\r
795 \r
796           jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
797                                         chooser.getSelectedFile().getParent());\r
798         }\r
799 \r
800         int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
801         int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
802 \r
803         if (av.getWrapAlignment())\r
804         {\r
805           height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
806               av.chunkHeight;\r
807           width = seqPanel.getWidth() + idPanel.getWidth();\r
808 \r
809         }\r
810 \r
811 \r
812         if (av.getShowAnnotation())\r
813         {\r
814             height += annotationPanel.getPreferredSize().height;\r
815         }\r
816 \r
817         try\r
818          {\r
819             FileOutputStream out = new FileOutputStream(epsFile);\r
820             EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width,\r
821                     height);\r
822 \r
823             if (av.getWrapAlignment())\r
824             {\r
825                 printWrappedAlignment(pg, width, height, 0);\r
826             }\r
827             else\r
828             {\r
829                 printUnwrapped(pg, width, height, 0);\r
830             }\r
831 \r
832             pg.flush();\r
833             pg.close();\r
834         }\r
835         catch (Exception ex)\r
836         {\r
837             ex.printStackTrace();\r
838         }\r
839     }\r
840 \r
841 \r
842     public void makePNGImageMap(File imgMapFile, String imageName)\r
843     {\r
844       ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS\r
845       //////////////////////////////////////////////\r
846       int idWidth = calculateIdWidth().width + 4;\r
847       FontMetrics fm = getFontMetrics(av.getFont());\r
848       int scaleHeight = av.charHeight + fm.getDescent();\r
849 \r
850         // Gen image map\r
851          //////////////////////////////////\r
852          if(imgMapFile!=null)\r
853          {\r
854            try\r
855            {\r
856              PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));\r
857              out.println(jalview.io.HTMLOutput.getImageMapHTML());\r
858              out.println("<img src=\"" + imageName +\r
859                        "\" border=\"0\" usemap=\"#Map\" >"\r
860                        +"<map name=\"Map\">");\r
861 \r
862              for (int s = 0; s < av.alignment.getHeight(); s++)\r
863              {\r
864                SequenceI seq = av.alignment.getSequenceAt(s);\r
865                SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
866                for (int i = 0; i < groups.length; i++)\r
867                {\r
868                  int sy = s * av.charHeight + scaleHeight;\r
869                  for (int res = groups[i].getStartRes();\r
870                       res < groups[i].getEndRes() + 1; res++)\r
871                  {\r
872                    int alIndex = seq.findPosition(res);\r
873                    Object obj = ResidueProperties.aa2Triplet.get(\r
874                        seq.getCharAt(res) + "");\r
875                    if (obj == null)\r
876                      continue;\r
877 \r
878                    String triplet = obj.toString();\r
879 \r
880                    out.println(\r
881                        "<area shape=\"rect\" coords=\""\r
882                        + (idWidth + res * av.charWidth) + ","\r
883                        + sy + ","\r
884                        + (idWidth + (res + 1) * av.charWidth) + ","\r
885                        + (av.charHeight + sy) + "\""\r
886                        + " onMouseOver=\"toolTip('"\r
887                        + alIndex + " " + triplet +\r
888                        "<br><em>" + groups[i].getName() +\r
889                        "</em>')\"; onMouseOut=\"toolTip()\"; "\r
890                        + " href=\"#\">");\r
891                  }\r
892                }\r
893              }\r
894 \r
895              out.println("</map></body></html>");\r
896              out.close();\r
897 \r
898            }\r
899            catch (Exception ex)\r
900            {\r
901              ex.printStackTrace();\r
902            }\r
903          }///////////END OF IMAGE MAP\r
904 \r
905     }\r
906 \r
907     /**\r
908      * DOCUMENT ME!\r
909      */\r
910     public void makePNG(File pngFile)\r
911     {\r
912       if(pngFile==null)\r
913       {\r
914         jalview.io.JalviewFileChooser chooser = new jalview.io.\r
915             JalviewFileChooser(jalview.bin.Cache.getProperty(\r
916                 "LAST_DIRECTORY"), new String[]\r
917                                {"png"},\r
918                                new String[]\r
919                                {"Portable network graphics"},\r
920                                "Portable network graphics");\r
921         chooser.setFileView(new jalview.io.JalviewFileView());\r
922         chooser.setDialogTitle("Create EPS file from alignment");\r
923         chooser.setToolTipText("Save");\r
924 \r
925         int value = chooser.showSaveDialog(this);\r
926 \r
927         if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
928         {\r
929           return;\r
930         }\r
931 \r
932         pngFile = chooser.getSelectedFile();\r
933 \r
934         jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
935                                       chooser.getSelectedFile().getParent());\r
936       }\r
937 \r
938 \r
939 \r
940       int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
941       int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
942 \r
943       if (av.getWrapAlignment())\r
944       {\r
945         height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
946             av.chunkHeight;\r
947         width = seqPanel.getWidth() + idPanel.getWidth();\r
948 \r
949       }\r
950 \r
951 \r
952         if (av.getShowAnnotation())\r
953         {\r
954             height += annotationPanel.getPreferredSize().height;\r
955         }\r
956 \r
957         try\r
958         {\r
959 \r
960             FileOutputStream out = new FileOutputStream(pngFile);\r
961 \r
962             BufferedImage bi = new BufferedImage(width, height,\r
963                     BufferedImage.TYPE_INT_RGB);\r
964             Graphics2D png = (Graphics2D) bi.getGraphics();\r
965 \r
966             png.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
967                 RenderingHints.VALUE_ANTIALIAS_ON);\r
968 \r
969             if (av.getWrapAlignment())\r
970             {\r
971                 printWrappedAlignment(png, width, height, 0);\r
972             }\r
973             else\r
974             {\r
975                 printUnwrapped(png, width, height, 0);\r
976             }\r
977 \r
978             ImageIO.write(bi, "png", out);\r
979             out.close();\r
980         }\r
981         catch(OutOfMemoryError err)\r
982         {\r
983           System.out.println("########################\n"\r
984                              +"OUT OF MEMORY "+pngFile+"\n"\r
985                              +"########################");\r
986         }\r
987         catch (Exception ex)\r
988         {\r
989             ex.printStackTrace();\r
990         }\r
991     }\r
992 }\r
993 \r
994 \r
995 /**\r
996  * DOCUMENT ME!\r
997  *\r
998  * @author $author$\r
999  * @version $Revision$\r
1000  */\r
1001 class Preview extends JFrame\r
1002 {\r
1003     /**\r
1004      * Creates a new Preview object.\r
1005      *\r
1006      * @param image DOCUMENT ME!\r
1007      */\r
1008     public Preview(Image image)\r
1009     {\r
1010         setResizable(true);\r
1011         setSize(image.getWidth(this), image.getHeight(this));\r
1012         setVisible(true);\r
1013         getContentPane().setLayout(new BorderLayout());\r
1014         getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
1015         validate();\r
1016         repaint();\r
1017     }\r
1018 }\r
1019 \r
1020 \r
1021 /**\r
1022  * DOCUMENT ME!\r
1023  *\r
1024  * @author $author$\r
1025  * @version $Revision$\r
1026  */\r
1027 class PreviewPanel extends JPanel\r
1028 {\r
1029     Image image;\r
1030 \r
1031     /**\r
1032      * Creates a new PreviewPanel object.\r
1033      *\r
1034      * @param image DOCUMENT ME!\r
1035      */\r
1036     public PreviewPanel(Image image)\r
1037     {\r
1038         this.image = image;\r
1039     }\r
1040 \r
1041     /**\r
1042      * DOCUMENT ME!\r
1043      *\r
1044      * @param g DOCUMENT ME!\r
1045      */\r
1046     public void paintComponent(Graphics g)\r
1047     {\r
1048         if (image != null)\r
1049         {\r
1050             g.drawImage(image, 0, 0, this);\r
1051         }\r
1052         else\r
1053         {\r
1054             System.out.println("DEBUG:image is null");\r
1055         }\r
1056     }\r
1057 }\r