OutOfMemory try catch
[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.datamodel.*;\r
22 \r
23 import jalview.jbgui.*;\r
24 \r
25 import jalview.schemes.*;\r
26 \r
27 import org.jibble.epsgraphics.*;\r
28 \r
29 import java.awt.*;\r
30 import java.awt.event.*;\r
31 import java.awt.image.*;\r
32 import java.awt.print.*;\r
33 \r
34 import java.io.*;\r
35 \r
36 import javax.imageio.*;\r
37 \r
38 import javax.swing.*;\r
39 \r
40 \r
41 /**\r
42  * DOCUMENT ME!\r
43  *\r
44  * @author $author$\r
45  * @version $Revision$\r
46  */\r
47 public class AlignmentPanel extends GAlignmentPanel\r
48     implements AdjustmentListener, Printable\r
49 {\r
50     AlignViewport av;\r
51     OverviewPanel overviewPanel;\r
52     SeqPanel seqPanel;\r
53     IdPanel idPanel;\r
54     IdwidthAdjuster idwidthAdjuster;\r
55 \r
56     /** DOCUMENT ME!! */\r
57     public AlignFrame alignFrame;\r
58     ScalePanel scalePanel;\r
59     AnnotationPanel annotationPanel;\r
60     AnnotationLabels alabels;\r
61 \r
62     // this value is set false when selection area being dragged\r
63     boolean fastPaint = true;\r
64     int hextent = 0;\r
65     int vextent = 0;\r
66 \r
67     /**\r
68      * Creates a new AlignmentPanel object.\r
69      *\r
70      * @param af DOCUMENT ME!\r
71      * @param av DOCUMENT ME!\r
72      */\r
73     public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
74     {\r
75         alignFrame = af;\r
76         this.av = av;\r
77         seqPanel = new SeqPanel(av, this);\r
78         idPanel = new IdPanel(av, this);\r
79 \r
80         scalePanel = new ScalePanel(av, this);\r
81 \r
82         idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
83         idwidthAdjuster = new IdwidthAdjuster(this);\r
84         idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
85 \r
86         annotationPanel = new AnnotationPanel(this);\r
87         alabels = new AnnotationLabels(this);\r
88 \r
89         annotationSpaceFillerHolder.setPreferredSize(annotationPanel.getPreferredSize());\r
90         annotationScroller.setPreferredSize(annotationPanel.getPreferredSize());\r
91         annotationScroller.setViewportView(annotationPanel);\r
92         annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
93 \r
94         fontChanged();\r
95 \r
96         scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
97         seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
98 \r
99         setScrollValues(0, 0);\r
100 \r
101         hscroll.addAdjustmentListener(this);\r
102         vscroll.addAdjustmentListener(this);\r
103 \r
104         setFocusable(true);\r
105         addKeyListener(new KeyAdapter()\r
106             {\r
107                 public void keyPressed(KeyEvent evt)\r
108                 {\r
109                     switch (evt.getKeyCode())\r
110                     {\r
111                     case 27: // escape key\r
112                         av.setSelectionGroup(null);\r
113                         repaint();\r
114 \r
115                         break;\r
116 \r
117                     case KeyEvent.VK_DOWN:\r
118                         alignFrame.moveSelectedSequences(false);\r
119 \r
120                         break;\r
121 \r
122                     case KeyEvent.VK_UP:\r
123                         alignFrame.moveSelectedSequences(true);\r
124 \r
125                         break;\r
126 \r
127                     case KeyEvent.VK_BACK_SPACE:\r
128                     case KeyEvent.VK_DELETE:\r
129                       alignFrame.cut_actionPerformed(null);\r
130                       break;\r
131                     }\r
132 \r
133                 }\r
134             });\r
135     }\r
136 \r
137     /**\r
138      * DOCUMENT ME!\r
139      */\r
140     public void fontChanged()\r
141     {\r
142         // set idCanvas bufferedImage to null\r
143         // to prevent drawing old image\r
144         FontMetrics fm = getFontMetrics(av.getFont());\r
145 \r
146         scalePanelHolder.setPreferredSize(new Dimension(10,\r
147                 av.charHeight + fm.getDescent()));\r
148         idSpaceFillerPanel1.setPreferredSize(new Dimension(10,\r
149                 av.charHeight + fm.getDescent()));\r
150 \r
151         idPanel.idCanvas.gg = null;\r
152         seqPanel.seqCanvas.img = null;\r
153         annotationPanel.adjustPanelHeight();\r
154 \r
155         Dimension d = calculateIdWidth();\r
156         d.setSize(d.width + 4, d.height);\r
157         idPanel.idCanvas.setPreferredSize(d);\r
158         hscrollFillerPanel.setPreferredSize(d);\r
159 \r
160         if (av.getWrapAlignment())\r
161         {\r
162           int max = av.alignment.getWidth() /\r
163               seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
164           vscroll.setMaximum(max);\r
165           vscroll.setUnitIncrement(1);\r
166           vscroll.setVisibleAmount(1);\r
167         }\r
168         else\r
169         {\r
170           setScrollValues(av.getStartRes(), av.getStartSeq());\r
171         }\r
172 \r
173         if(overviewPanel!=null)\r
174           overviewPanel.setBoxPosition();\r
175 \r
176         repaint();\r
177     }\r
178 \r
179     /**\r
180      * DOCUMENT ME!\r
181      *\r
182      * @return DOCUMENT ME!\r
183      */\r
184     public Dimension calculateIdWidth()\r
185     {\r
186       Container c = new Container();\r
187 \r
188         FontMetrics fm = c.getFontMetrics(av.font);\r
189         AlignmentI al = av.getAlignment();\r
190 \r
191         int i = 0;\r
192         int idWidth = 0;\r
193         String id;\r
194 \r
195         while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))\r
196         {\r
197             SequenceI s = al.getSequenceAt(i);\r
198 \r
199             if (av.getShowFullId())\r
200             {\r
201                 id = s.getDisplayId();\r
202             }\r
203             else\r
204             {\r
205                 id = s.getName();\r
206             }\r
207 \r
208             if (fm.stringWidth(id) > idWidth)\r
209             {\r
210                 idWidth = fm.stringWidth(id);\r
211             }\r
212 \r
213             i++;\r
214         }\r
215 \r
216         // Also check annotation label widths\r
217         i = 0;\r
218 \r
219         if (al.getAlignmentAnnotation() != null)\r
220         {\r
221             fm = c.getFontMetrics(alabels.getFont());\r
222 \r
223             while (i < al.getAlignmentAnnotation().length)\r
224             {\r
225                 String label = al.getAlignmentAnnotation()[i].label;\r
226 \r
227                 if (fm.stringWidth(label) > idWidth)\r
228                 {\r
229                     idWidth = fm.stringWidth(label);\r
230                 }\r
231 \r
232                 i++;\r
233             }\r
234         }\r
235 \r
236         return new Dimension(idWidth, 12);\r
237     }\r
238 \r
239     /**\r
240      * DOCUMENT ME!\r
241      *\r
242      * @param results DOCUMENT ME!\r
243      */\r
244     public void highlightSearchResults(int[] results)\r
245     {\r
246         seqPanel.seqCanvas.highlightSearchResults(results);\r
247 \r
248         // do we need to scroll the panel?\r
249         if (results != null)\r
250         {\r
251             SequenceI seq = av.alignment.getSequenceAt(results[0]);\r
252             int start = seq.findIndex(results[1]) - 1;\r
253             int end = seq.findIndex(results[2]) - 1;\r
254 \r
255             if ((av.getStartRes() > start) || (av.getEndRes() < end) ||\r
256                     ((av.getStartSeq() > results[0]) ||\r
257                     (av.getEndSeq() < results[0])))\r
258             {\r
259                 setScrollValues(start, results[0]);\r
260             }\r
261         }\r
262     }\r
263 \r
264     /**\r
265      * DOCUMENT ME!\r
266      *\r
267      * @return DOCUMENT ME!\r
268      */\r
269     public OverviewPanel getOverviewPanel()\r
270     {\r
271         return overviewPanel;\r
272     }\r
273 \r
274     /**\r
275      * DOCUMENT ME!\r
276      *\r
277      * @param op DOCUMENT ME!\r
278      */\r
279     public void setOverviewPanel(OverviewPanel op)\r
280     {\r
281         overviewPanel = op;\r
282     }\r
283 \r
284     /**\r
285      * DOCUMENT ME!\r
286      *\r
287      * @param b DOCUMENT ME!\r
288      */\r
289     public void setAnnotationVisible(boolean b)\r
290     {\r
291         annotationSpaceFillerHolder.setVisible(b);\r
292         annotationScroller.setVisible(b);\r
293     }\r
294 \r
295     /**\r
296      * DOCUMENT ME!\r
297      *\r
298      * @param wrap DOCUMENT ME!\r
299      */\r
300     public void setWrapAlignment(boolean wrap)\r
301     {\r
302         av.startSeq = 0;\r
303         scalePanelHolder.setVisible(!wrap);\r
304         hscroll.setVisible(!wrap);\r
305         idwidthAdjuster.setVisible(!wrap);\r
306 \r
307        if(wrap)\r
308        {\r
309          annotationScroller.setVisible(false);\r
310          annotationSpaceFillerHolder.setVisible(false);\r
311        }\r
312        else if(av.showAnnotation)\r
313        {\r
314          annotationScroller.setVisible(true);\r
315          annotationSpaceFillerHolder.setVisible(true);\r
316        }\r
317 \r
318        idSpaceFillerPanel1.setVisible(!wrap);\r
319 \r
320         repaint();\r
321     }\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 \r
437     /**\r
438      * DOCUMENT ME!\r
439      *\r
440      * @param evt DOCUMENT ME!\r
441      */\r
442     public void adjustmentValueChanged(AdjustmentEvent evt)\r
443     {\r
444 \r
445         int oldX = av.getStartRes();\r
446         int oldY = av.getStartSeq();\r
447 \r
448         if (evt.getSource() == hscroll)\r
449         {\r
450             int x = hscroll.getValue();\r
451             av.setStartRes(x);\r
452             av.setEndRes((x +\r
453                 (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);\r
454         }\r
455 \r
456         if (evt.getSource() == vscroll)\r
457         {\r
458             int offy = vscroll.getValue();\r
459 \r
460             if (av.getWrapAlignment())\r
461             {\r
462                 int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
463                 av.setStartRes(vscroll.getValue() * rowSize);\r
464                 av.setEndRes((vscroll.getValue() + 1) * rowSize);\r
465             }\r
466             else\r
467             {\r
468                 av.setStartSeq(offy);\r
469                 av.setEndSeq(offy +\r
470                     (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));\r
471             }\r
472         }\r
473 \r
474         if (overviewPanel != null)\r
475         {\r
476             overviewPanel.setBoxPosition();\r
477         }\r
478 \r
479         int xShift = av.getStartRes() - oldX;\r
480         int yShift = av.getStartSeq() - oldY;\r
481 \r
482         if ( (xShift != 0 && yShift != 0) ||\r
483             (Math.abs(xShift) > av.getEndRes() - av.getStartRes()\r
484              || Math.abs(yShift) > av.getEndSeq() - av.getStartSeq())\r
485              || av.getWrapAlignment()\r
486              || !fastPaint)\r
487         {\r
488           // Either no shift at all, or shift greater than visible amount\r
489           repaint();\r
490         }\r
491         else\r
492         {\r
493             idPanel.idCanvas.fastPaint(yShift);\r
494             seqPanel.seqCanvas.fastPaint(xShift, yShift);\r
495 \r
496             scalePanel.repaint();\r
497 \r
498             if (av.getShowAnnotation())\r
499             {\r
500                 annotationPanel.fastPaint(xShift);\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       boolean accurateText = true;\r
775 \r
776       String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",\r
777           "Prompt each time");\r
778 \r
779       // If we need to prompt, and if the GUI is visible then\r
780       // Prompt for EPS rendering style\r
781       if (renderStyle.equalsIgnoreCase("Prompt each time")\r
782           && !\r
783           (System.getProperty("java.awt.headless") != null\r
784            && System.getProperty("java.awt.headless").equals("true")))\r
785       {\r
786         EPSOptions eps = new EPSOptions();\r
787         renderStyle = eps.getValue();\r
788 \r
789         if(eps.cancelled || renderStyle==null)\r
790           return;\r
791 \r
792         renderStyle = eps.getValue();\r
793       }\r
794 \r
795       if (renderStyle.equalsIgnoreCase("text"))\r
796       {\r
797         accurateText = false;\r
798       }\r
799 \r
800 \r
801         if(epsFile == null)\r
802         {\r
803           jalview.io.JalviewFileChooser chooser = new jalview.io.\r
804               JalviewFileChooser(jalview.bin.Cache.getProperty(\r
805                   "LAST_DIRECTORY"), new String[]\r
806                                  {"eps"},\r
807                                  new String[]\r
808                                  {"Encapsulated Postscript"},\r
809                                  "Encapsulated Postscript");\r
810           chooser.setFileView(new jalview.io.JalviewFileView());\r
811           chooser.setDialogTitle("Create EPS file from alignment");\r
812           chooser.setToolTipText("Save");\r
813 \r
814           int value = chooser.showSaveDialog(this);\r
815 \r
816           if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
817           {\r
818             return;\r
819           }\r
820 \r
821           epsFile = chooser.getSelectedFile();\r
822 \r
823           jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
824                                         chooser.getSelectedFile().getParent());\r
825         }\r
826 \r
827         int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
828         int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
829 \r
830         if (av.getWrapAlignment())\r
831         {\r
832           height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
833               av.chunkHeight;\r
834           width = seqPanel.getWidth() + idPanel.getWidth();\r
835 \r
836         }\r
837 \r
838 \r
839         if (av.getShowAnnotation())\r
840         {\r
841             height += annotationPanel.getPreferredSize().height;\r
842         }\r
843 \r
844         try\r
845          {\r
846            FileOutputStream out = new FileOutputStream(epsFile);\r
847            EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width,\r
848                                                 height);\r
849 \r
850            pg.setAccurateTextMode(accurateText);\r
851 \r
852            if (av.getWrapAlignment())\r
853            {\r
854                 printWrappedAlignment(pg, width, height, 0);\r
855             }\r
856             else\r
857             {\r
858                 printUnwrapped(pg, width, height, 0);\r
859             }\r
860 \r
861             pg.flush();\r
862             pg.close();\r
863           }\r
864           catch (OutOfMemoryError err)\r
865           {\r
866             System.out.println("########################\n"\r
867                                + "OUT OF MEMORY " + epsFile + "\n"\r
868                                + "########################");\r
869 \r
870             JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
871                                                   "Out of memory creating EPS file!!"\r
872                                                   +\r
873                                                   "\nSee help files for increasing Java Virtual Machine memory."\r
874                                                   , "Out of memory",\r
875                                                   JOptionPane.WARNING_MESSAGE);\r
876             System.out.println("Create EPS: " + err);\r
877             System.gc();\r
878           }\r
879         catch (Exception ex)\r
880         {\r
881             ex.printStackTrace();\r
882         }\r
883     }\r
884 \r
885 \r
886     public void makePNGImageMap(File imgMapFile, String imageName)\r
887     {\r
888       ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS\r
889       //////////////////////////////////////////////\r
890       int idWidth = calculateIdWidth().width + 4;\r
891       FontMetrics fm = getFontMetrics(av.getFont());\r
892       int scaleHeight = av.charHeight + fm.getDescent();\r
893 \r
894         // Gen image map\r
895          //////////////////////////////////\r
896          if(imgMapFile!=null)\r
897          {\r
898            try\r
899            {\r
900              PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));\r
901              out.println(jalview.io.HTMLOutput.getImageMapHTML());\r
902              out.println("<img src=\"" + imageName +\r
903                        "\" border=\"0\" usemap=\"#Map\" >"\r
904                        +"<map name=\"Map\">");\r
905 \r
906              for (int s = 0; s < av.alignment.getHeight(); s++)\r
907              {\r
908                SequenceI seq = av.alignment.getSequenceAt(s);\r
909                SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
910                for (int i = 0; i < groups.length; i++)\r
911                {\r
912                  int sy = s * av.charHeight + scaleHeight;\r
913                  for (int res = groups[i].getStartRes();\r
914                       res < groups[i].getEndRes() + 1; res++)\r
915                  {\r
916                    int alIndex = seq.findPosition(res);\r
917                    Object obj = ResidueProperties.aa2Triplet.get(\r
918                        seq.getCharAt(res) + "");\r
919                    if (obj == null)\r
920                      continue;\r
921 \r
922                    String triplet = obj.toString();\r
923 \r
924                    out.println(\r
925                        "<area shape=\"rect\" coords=\""\r
926                        + (idWidth + res * av.charWidth) + ","\r
927                        + sy + ","\r
928                        + (idWidth + (res + 1) * av.charWidth) + ","\r
929                        + (av.charHeight + sy) + "\""\r
930                        + " onMouseOver=\"toolTip('"\r
931                        + alIndex + " " + triplet +\r
932                        "<br><em>" + groups[i].getName() +\r
933                        "</em>')\"; onMouseOut=\"toolTip()\"; "\r
934                        + " href=\"#\">");\r
935                  }\r
936                }\r
937              }\r
938 \r
939              out.println("</map></body></html>");\r
940              out.close();\r
941 \r
942            }\r
943            catch (Exception ex)\r
944            {\r
945              ex.printStackTrace();\r
946            }\r
947          }///////////END OF IMAGE MAP\r
948 \r
949     }\r
950 \r
951     /**\r
952      * DOCUMENT ME!\r
953      */\r
954     public void makePNG(File pngFile)\r
955     {\r
956       if(pngFile==null)\r
957       {\r
958         jalview.io.JalviewFileChooser chooser = new jalview.io.\r
959             JalviewFileChooser(jalview.bin.Cache.getProperty(\r
960                 "LAST_DIRECTORY"), new String[]\r
961                                {"png"},\r
962                                new String[]\r
963                                {"Portable network graphics"},\r
964                                "Portable network graphics");\r
965         chooser.setFileView(new jalview.io.JalviewFileView());\r
966         chooser.setDialogTitle("Create EPS file from alignment");\r
967         chooser.setToolTipText("Save");\r
968 \r
969         int value = chooser.showSaveDialog(this);\r
970 \r
971         if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
972         {\r
973           return;\r
974         }\r
975 \r
976         pngFile = chooser.getSelectedFile();\r
977 \r
978         jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
979                                       chooser.getSelectedFile().getParent());\r
980       }\r
981 \r
982 \r
983 \r
984       int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
985       int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
986 \r
987       if (av.getWrapAlignment())\r
988       {\r
989         height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
990             av.chunkHeight;\r
991         width = seqPanel.getWidth() + idPanel.getWidth();\r
992 \r
993       }\r
994 \r
995 \r
996         if (av.getShowAnnotation())\r
997         {\r
998             height += annotationPanel.getPreferredSize().height;\r
999         }\r
1000 \r
1001         try\r
1002         {\r
1003 \r
1004             FileOutputStream out = new FileOutputStream(pngFile);\r
1005 \r
1006             BufferedImage bi = new BufferedImage(width, height,\r
1007                     BufferedImage.TYPE_INT_RGB);\r
1008             Graphics2D png = (Graphics2D) bi.getGraphics();\r
1009 \r
1010             png.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
1011                 RenderingHints.VALUE_ANTIALIAS_ON);\r
1012 \r
1013             if (av.getWrapAlignment())\r
1014             {\r
1015                 printWrappedAlignment(png, width, height, 0);\r
1016             }\r
1017             else\r
1018             {\r
1019                 printUnwrapped(png, width, height, 0);\r
1020             }\r
1021 \r
1022             ImageIO.write(bi, "png", out);\r
1023             out.close();\r
1024         }\r
1025         catch (OutOfMemoryError err)\r
1026         {\r
1027           System.out.println("########################\n"\r
1028                              + "OUT OF MEMORY " + pngFile + "\n"\r
1029                              + "########################");\r
1030 \r
1031           JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
1032                                                 "Out of memory creating PNG!!"\r
1033                                                 +\r
1034                                                 "\nSee help files for increasing Java Virtual Machine memory."\r
1035                                                 , "Out of memory",\r
1036                                                 JOptionPane.WARNING_MESSAGE);\r
1037           System.out.println("Create PNG: " + err);\r
1038           System.gc();\r
1039 \r
1040         }\r
1041         catch (Exception ex)\r
1042         {\r
1043             ex.printStackTrace();\r
1044         }\r
1045     }\r
1046 }\r
1047 \r
1048 \r
1049 /**\r
1050  * DOCUMENT ME!\r
1051  *\r
1052  * @author $author$\r
1053  * @version $Revision$\r
1054  */\r
1055 class Preview extends JFrame\r
1056 {\r
1057     /**\r
1058      * Creates a new Preview object.\r
1059      *\r
1060      * @param image DOCUMENT ME!\r
1061      */\r
1062     public Preview(Image image)\r
1063     {\r
1064         setResizable(true);\r
1065         setSize(image.getWidth(this), image.getHeight(this));\r
1066         setVisible(true);\r
1067         getContentPane().setLayout(new BorderLayout());\r
1068         getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
1069         validate();\r
1070         repaint();\r
1071     }\r
1072 }\r
1073 \r
1074 \r
1075 /**\r
1076  * DOCUMENT ME!\r
1077  *\r
1078  * @author $author$\r
1079  * @version $Revision$\r
1080  */\r
1081 class PreviewPanel extends JPanel\r
1082 {\r
1083     Image image;\r
1084 \r
1085     /**\r
1086      * Creates a new PreviewPanel object.\r
1087      *\r
1088      * @param image DOCUMENT ME!\r
1089      */\r
1090     public PreviewPanel(Image image)\r
1091     {\r
1092         this.image = image;\r
1093     }\r
1094 \r
1095     /**\r
1096      * DOCUMENT ME!\r
1097      *\r
1098      * @param g DOCUMENT ME!\r
1099      */\r
1100     public void paintComponent(Graphics g)\r
1101     {\r
1102         if (image != null)\r
1103         {\r
1104             g.drawImage(image, 0, 0, this);\r
1105         }\r
1106         else\r
1107         {\r
1108             System.out.println("DEBUG:image is null");\r
1109         }\r
1110     }\r
1111 }\r