Use propertyListener for alignment edits
[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         av.setShowAnnotation(!wrap);\r
308         annotationScroller.setVisible(!wrap);\r
309         annotationSpaceFillerHolder.setVisible(!wrap);\r
310         idSpaceFillerPanel1.setVisible(!wrap);\r
311 \r
312         repaint();\r
313     }\r
314 \r
315 \r
316     // return value is true if the scroll is valid\r
317     public boolean scrollUp(boolean up)\r
318     {\r
319         if (up)\r
320         {\r
321             if (vscroll.getValue() < 1)\r
322             {\r
323                 return false;\r
324             }\r
325 \r
326             fastPaint = false;\r
327             vscroll.setValue(vscroll.getValue() - 1);\r
328         }\r
329         else\r
330         {\r
331             if ((vextent + vscroll.getValue()) >= av.getAlignment().getHeight())\r
332             {\r
333                 return false;\r
334             }\r
335 \r
336             fastPaint = false;\r
337             vscroll.setValue(vscroll.getValue() + 1);\r
338         }\r
339 \r
340         fastPaint = true;\r
341 \r
342         return true;\r
343     }\r
344 \r
345     /**\r
346      * DOCUMENT ME!\r
347      *\r
348      * @param right DOCUMENT ME!\r
349      *\r
350      * @return DOCUMENT ME!\r
351      */\r
352     public boolean scrollRight(boolean right)\r
353     {\r
354         if (right)\r
355         {\r
356             if (hscroll.getValue() < 1)\r
357             {\r
358                 return false;\r
359             }\r
360 \r
361             fastPaint = false;\r
362             hscroll.setValue(hscroll.getValue() - 1);\r
363         }\r
364         else\r
365         {\r
366             if ((hextent + hscroll.getValue()) >= av.getAlignment().getWidth())\r
367             {\r
368                 return false;\r
369             }\r
370 \r
371             fastPaint = false;\r
372             hscroll.setValue(hscroll.getValue() + 1);\r
373         }\r
374 \r
375         fastPaint = true;\r
376 \r
377         return true;\r
378     }\r
379 \r
380     /**\r
381      * DOCUMENT ME!\r
382      *\r
383      * @param x DOCUMENT ME!\r
384      * @param y DOCUMENT ME!\r
385      */\r
386     public void setScrollValues(int x, int y)\r
387     {\r
388         av.setEndRes((x + (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) -\r
389             1);\r
390 \r
391         hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;\r
392         vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;\r
393 \r
394         if (hextent > av.alignment.getWidth())\r
395         {\r
396             hextent = av.alignment.getWidth();\r
397         }\r
398 \r
399         if (vextent > av.alignment.getHeight())\r
400         {\r
401             vextent = av.alignment.getHeight();\r
402         }\r
403 \r
404         if ((hextent + x) > av.getAlignment().getWidth())\r
405         {\r
406             x = av.getAlignment().getWidth() - hextent;\r
407         }\r
408 \r
409         if ((vextent + y) > av.getAlignment().getHeight())\r
410         {\r
411             y = av.getAlignment().getHeight() - vextent;\r
412         }\r
413 \r
414         if (y < 0)\r
415         {\r
416             y = 0;\r
417         }\r
418 \r
419         if (x < 0)\r
420         {\r
421             x = 0;\r
422         }\r
423 \r
424         hscroll.setValues(x, hextent, 0, av.getAlignment().getWidth());\r
425         vscroll.setValues(y, vextent, 0, av.getAlignment().getHeight());\r
426     }\r
427 \r
428 \r
429     /**\r
430      * DOCUMENT ME!\r
431      *\r
432      * @param evt DOCUMENT ME!\r
433      */\r
434     public void adjustmentValueChanged(AdjustmentEvent evt)\r
435     {\r
436         int oldX = av.getStartRes();\r
437         int oldY = av.getStartSeq();\r
438 \r
439         if (evt.getSource() == hscroll)\r
440         {\r
441             int x = hscroll.getValue();\r
442             av.setStartRes(x);\r
443             av.setEndRes((x +\r
444                 (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);\r
445         }\r
446 \r
447         if (evt.getSource() == vscroll)\r
448         {\r
449             int offy = vscroll.getValue();\r
450 \r
451             if (av.getWrapAlignment())\r
452             {\r
453                 int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
454                 av.setStartRes(vscroll.getValue() * rowSize);\r
455                 av.setEndRes((vscroll.getValue() + 1) * rowSize);\r
456             }\r
457             else\r
458             {\r
459                 av.setStartSeq(offy);\r
460                 av.setEndSeq(offy +\r
461                     (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));\r
462             }\r
463         }\r
464 \r
465         if (overviewPanel != null)\r
466         {\r
467             overviewPanel.setBoxPosition();\r
468         }\r
469 \r
470         if (av.getWrapAlignment() || !fastPaint)\r
471         {\r
472             repaint();\r
473         }\r
474         else\r
475         {\r
476             idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
477             seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
478                 av.getStartSeq() - oldY);\r
479 \r
480             scalePanel.repaint();\r
481 \r
482             if (av.getShowAnnotation())\r
483             {\r
484                 annotationPanel.fastPaint(av.getStartRes() - oldX);\r
485             }\r
486         }\r
487     }\r
488 \r
489     /**\r
490      * DOCUMENT ME!\r
491      *\r
492      * @param g DOCUMENT ME!\r
493      */\r
494     public void paintComponent(Graphics g)\r
495     {\r
496         invalidate();\r
497 \r
498         Dimension d = idPanel.idCanvas.getPreferredSize();\r
499         idPanelHolder.setPreferredSize(d);\r
500         hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
501         validate();\r
502 \r
503         if (av.getWrapAlignment())\r
504         {\r
505             int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
506             vscroll.setMaximum(max);\r
507             vscroll.setUnitIncrement(1);\r
508             vscroll.setVisibleAmount(1);\r
509         }\r
510         else\r
511         {\r
512             setScrollValues(av.getStartRes(), av.getStartSeq());\r
513         }\r
514     }\r
515 \r
516     /**\r
517      * DOCUMENT ME!\r
518      *\r
519      * @param pg DOCUMENT ME!\r
520      * @param pf DOCUMENT ME!\r
521      * @param pi DOCUMENT ME!\r
522      *\r
523      * @return DOCUMENT ME!\r
524      *\r
525      * @throws PrinterException DOCUMENT ME!\r
526      */\r
527     public int print(Graphics pg, PageFormat pf, int pi)\r
528         throws PrinterException\r
529     {\r
530         pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());\r
531 \r
532         int pwidth = (int) pf.getImageableWidth();\r
533         int pheight = (int) pf.getImageableHeight();\r
534 \r
535         if (av.getWrapAlignment())\r
536         {\r
537             return printWrappedAlignment(pg, pwidth, pheight, pi);\r
538         }\r
539         else\r
540         {\r
541             return printUnwrapped(pg, pwidth, pheight, pi);\r
542         }\r
543     }\r
544 \r
545     /**\r
546      * DOCUMENT ME!\r
547      *\r
548      * @param pg DOCUMENT ME!\r
549      * @param pwidth DOCUMENT ME!\r
550      * @param pheight DOCUMENT ME!\r
551      * @param pi DOCUMENT ME!\r
552      *\r
553      * @return DOCUMENT ME!\r
554      *\r
555      * @throws PrinterException DOCUMENT ME!\r
556      */\r
557     public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)\r
558         throws PrinterException\r
559     {\r
560         int idWidth = calculateIdWidth().width + 4;\r
561         FontMetrics fm = getFontMetrics(av.getFont());\r
562         int scaleHeight = av.charHeight + fm.getDescent();\r
563 \r
564         pg.setColor(Color.white);\r
565         pg.fillRect(0, 0, pwidth, pheight);\r
566         pg.setFont(av.getFont());\r
567 \r
568         ////////////////////////////////////\r
569         /// How many sequences and residues can we fit on a printable page?\r
570         int totalRes = (pwidth - idWidth) / av.getCharWidth();\r
571 \r
572         int totalSeq = (int) ((pheight - scaleHeight) / av.getCharHeight()) -\r
573             1;\r
574 \r
575         int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;\r
576 \r
577         /////////////////////////////\r
578         /// Only print these sequences and residues on this page\r
579         int startRes;\r
580 \r
581         /////////////////////////////\r
582         /// Only print these sequences and residues on this page\r
583         int endRes;\r
584 \r
585         /////////////////////////////\r
586         /// Only print these sequences and residues on this page\r
587         int startSeq;\r
588 \r
589         /////////////////////////////\r
590         /// Only print these sequences and residues on this page\r
591         int endSeq;\r
592         startRes = (pi % pagesWide) * totalRes;\r
593         endRes = (startRes + totalRes) - 1;\r
594 \r
595         if (endRes > (av.getAlignment().getWidth() - 1))\r
596         {\r
597             endRes = av.getAlignment().getWidth() - 1;\r
598         }\r
599 \r
600         startSeq = (pi / pagesWide) * totalSeq;\r
601         endSeq = startSeq + totalSeq;\r
602 \r
603         if (endSeq > av.getAlignment().getHeight())\r
604         {\r
605             endSeq = av.getAlignment().getHeight();\r
606         }\r
607 \r
608         int pagesHigh = ((av.alignment.getHeight() / totalSeq) + 1) * pheight;\r
609 \r
610         if (av.showAnnotation)\r
611         {\r
612             pagesHigh += annotationPanel.getHeight();\r
613         }\r
614 \r
615         pagesHigh /= pheight;\r
616 \r
617         if (pi >= (pagesWide * pagesHigh))\r
618         {\r
619             return Printable.NO_SUCH_PAGE;\r
620         }\r
621 \r
622         //draw Scale\r
623         pg.translate(idWidth, 0);\r
624         scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth, scaleHeight);\r
625         pg.translate(-idWidth, scaleHeight);\r
626 \r
627         ////////////////\r
628         // Draw the ids\r
629         Color currentColor = null;\r
630         Color currentTextColor = null;\r
631 \r
632         for (int i = startSeq; i < endSeq; i++)\r
633         {\r
634             if ((av.getSelectionGroup() != null) &&\r
635                     av.getSelectionGroup().sequences.contains(\r
636                         av.getAlignment().getSequenceAt(i)))\r
637             {\r
638                 currentColor = Color.gray;\r
639                 currentTextColor = Color.black;\r
640             }\r
641             else\r
642             {\r
643                 currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
644                 currentTextColor = Color.black;\r
645             }\r
646 \r
647             pg.setColor(currentColor);\r
648             pg.fillRect(0, (i-startSeq) * av.charHeight, idWidth,\r
649                 av.getCharHeight());\r
650 \r
651             pg.setColor(currentTextColor);\r
652 \r
653             String string = av.getAlignment().getSequenceAt(i).getName();\r
654 \r
655             if (av.getShowFullId())\r
656             {\r
657                 string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
658             }\r
659 \r
660             pg.drawString(string, 0,\r
661                 (((i-startSeq) * av.charHeight) + av.getCharHeight()) -\r
662                 (av.getCharHeight() / 5));\r
663         }\r
664 \r
665         // draw main sequence panel\r
666         pg.translate(idWidth, 0);\r
667         seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq,\r
668             startRes, startSeq, 0);\r
669 \r
670         if (av.showAnnotation && (endSeq == av.alignment.getHeight()))\r
671         {\r
672             pg.translate(-idWidth, (endSeq - startSeq) * av.charHeight);\r
673             alabels.drawComponent((Graphics2D) pg);\r
674             pg.translate(idWidth, 0);\r
675             annotationPanel.drawComponent((Graphics2D) pg, startRes, endRes +\r
676                 1);\r
677         }\r
678 \r
679         return Printable.PAGE_EXISTS;\r
680     }\r
681 \r
682     /**\r
683      * DOCUMENT ME!\r
684      *\r
685      * @param pg DOCUMENT ME!\r
686      * @param pwidth DOCUMENT ME!\r
687      * @param pheight DOCUMENT ME!\r
688      * @param pi DOCUMENT ME!\r
689      *\r
690      * @return DOCUMENT ME!\r
691      *\r
692      * @throws PrinterException DOCUMENT ME!\r
693      */\r
694     public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,\r
695         int pi) throws PrinterException\r
696     {\r
697         int idWidth = calculateIdWidth().width + 4;\r
698 \r
699         int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -\r
700                 idWidth);\r
701         int totalHeight = totalHeight = (av.alignment.getHeight() + 2) * ((av.alignment.getWidth() / resWidth) +\r
702                 1) * av.charHeight;\r
703 \r
704         pg.setColor(Color.white);\r
705         pg.fillRect(0, 0, pwidth, pheight);\r
706         pg.setFont(av.getFont());\r
707 \r
708         ////////////////\r
709         // Draw the ids\r
710         pg.setColor(Color.black);\r
711 \r
712         pg.translate(0, -pi * pheight);\r
713 \r
714         pg.setClip(0, pi * pheight, pwidth, pheight);\r
715 \r
716         int ypos = 2 * av.charHeight;\r
717 \r
718         do\r
719         {\r
720             for (int i = 0; i < av.alignment.getHeight(); i++)\r
721             {\r
722                 SequenceI s = av.alignment.getSequenceAt(i);\r
723                 String string = s.getName();\r
724 \r
725                 if (av.getShowFullId())\r
726                 {\r
727                     string = s.getDisplayId();\r
728                 }\r
729 \r
730                 pg.drawString(string, 0,\r
731                     ((i * av.charHeight) + ypos + av.charHeight) -\r
732                     (av.charHeight / 5));\r
733             }\r
734 \r
735             ypos += ((av.alignment.getHeight() + 2) * av.charHeight);\r
736         }\r
737         while (ypos < totalHeight);\r
738 \r
739         pg.translate(idWidth, 0);\r
740 \r
741         seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight, 0);\r
742 \r
743         if ((pi * pheight) < totalHeight)\r
744         {\r
745             return Printable.PAGE_EXISTS;\r
746         }\r
747         else\r
748         {\r
749             return Printable.NO_SUCH_PAGE;\r
750         }\r
751     }\r
752 \r
753     /**\r
754      * DOCUMENT ME!\r
755      */\r
756     public void makeEPS(File epsFile)\r
757     {\r
758         if(epsFile == null)\r
759         {\r
760           jalview.io.JalviewFileChooser chooser = new jalview.io.\r
761               JalviewFileChooser(jalview.bin.Cache.getProperty(\r
762                   "LAST_DIRECTORY"), new String[]\r
763                                  {"eps"},\r
764                                  new String[]\r
765                                  {"Encapsulated Postscript"},\r
766                                  "Encapsulated Postscript");\r
767           chooser.setFileView(new jalview.io.JalviewFileView());\r
768           chooser.setDialogTitle("Create EPS file from alignment");\r
769           chooser.setToolTipText("Save");\r
770 \r
771           int value = chooser.showSaveDialog(this);\r
772 \r
773           if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
774           {\r
775             return;\r
776           }\r
777 \r
778           epsFile = chooser.getSelectedFile();\r
779 \r
780           jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
781                                         chooser.getSelectedFile().getParent());\r
782         }\r
783 \r
784         int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
785         int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
786 \r
787         if (av.getWrapAlignment())\r
788         {\r
789           height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
790               av.chunkHeight;\r
791           width = seqPanel.getWidth() + idPanel.getWidth();\r
792 \r
793         }\r
794 \r
795 \r
796         if (av.getShowAnnotation())\r
797         {\r
798             height += annotationPanel.getPreferredSize().height;\r
799         }\r
800 \r
801         try\r
802          {\r
803             FileOutputStream out = new FileOutputStream(epsFile);\r
804             EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width,\r
805                     height);\r
806 \r
807             if (av.getWrapAlignment())\r
808             {\r
809                 printWrappedAlignment(pg, width, height, 0);\r
810             }\r
811             else\r
812             {\r
813                 printUnwrapped(pg, width, height, 0);\r
814             }\r
815 \r
816             pg.flush();\r
817             pg.close();\r
818         }\r
819         catch (Exception ex)\r
820         {\r
821             ex.printStackTrace();\r
822         }\r
823     }\r
824 \r
825 \r
826     public void makePNGImageMap(File imgMapFile, String imageName)\r
827     {\r
828       ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS\r
829       //////////////////////////////////////////////\r
830       int idWidth = calculateIdWidth().width + 4;\r
831       FontMetrics fm = getFontMetrics(av.getFont());\r
832       int scaleHeight = av.charHeight + fm.getDescent();\r
833 \r
834         // Gen image map\r
835          //////////////////////////////////\r
836          if(imgMapFile!=null)\r
837          {\r
838            try\r
839            {\r
840              PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));\r
841              out.println(jalview.io.HTMLOutput.getImageMapHTML());\r
842              out.println("<img src=\"" + imageName +\r
843                        "\" border=\"0\" usemap=\"#Map\" >"\r
844                        +"<map name=\"Map\">");\r
845 \r
846              for (int s = 0; s < av.alignment.getHeight(); s++)\r
847              {\r
848                SequenceI seq = av.alignment.getSequenceAt(s);\r
849                SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
850                for (int i = 0; i < groups.length; i++)\r
851                {\r
852                  int sy = s * av.charHeight + scaleHeight;\r
853                  for (int res = groups[i].getStartRes();\r
854                       res < groups[i].getEndRes() + 1; res++)\r
855                  {\r
856                    int alIndex = seq.findPosition(res);\r
857                    Object obj = ResidueProperties.aa2Triplet.get(\r
858                        seq.getCharAt(res) + "");\r
859                    if (obj == null)\r
860                      continue;\r
861 \r
862                    String triplet = obj.toString();\r
863 \r
864                    out.println(\r
865                        "<area shape=\"rect\" coords=\""\r
866                        + (idWidth + res * av.charWidth) + ","\r
867                        + sy + ","\r
868                        + (idWidth + (res + 1) * av.charWidth) + ","\r
869                        + (av.charHeight + sy) + "\""\r
870                        + " onMouseOver=\"toolTip('"\r
871                        + alIndex + " " + triplet +\r
872                        "<br><em>" + groups[i].getName() +\r
873                        "</em>')\"; onMouseOut=\"toolTip()\"; "\r
874                        + " href=\"#\">");\r
875                  }\r
876                }\r
877              }\r
878 \r
879              out.println("</map></body></html>");\r
880              out.close();\r
881 \r
882            }\r
883            catch (Exception ex)\r
884            {\r
885              ex.printStackTrace();\r
886            }\r
887          }///////////END OF IMAGE MAP\r
888 \r
889     }\r
890 \r
891     /**\r
892      * DOCUMENT ME!\r
893      */\r
894     public void makePNG(File pngFile)\r
895     {\r
896       if(pngFile==null)\r
897       {\r
898         jalview.io.JalviewFileChooser chooser = new jalview.io.\r
899             JalviewFileChooser(jalview.bin.Cache.getProperty(\r
900                 "LAST_DIRECTORY"), new String[]\r
901                                {"png"},\r
902                                new String[]\r
903                                {"Portable network graphics"},\r
904                                "Portable network graphics");\r
905         chooser.setFileView(new jalview.io.JalviewFileView());\r
906         chooser.setDialogTitle("Create EPS file from alignment");\r
907         chooser.setToolTipText("Save");\r
908 \r
909         int value = chooser.showSaveDialog(this);\r
910 \r
911         if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
912         {\r
913           return;\r
914         }\r
915 \r
916         pngFile = chooser.getSelectedFile();\r
917 \r
918         jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
919                                       chooser.getSelectedFile().getParent());\r
920       }\r
921 \r
922 \r
923 \r
924       int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
925       int width = idPanel.getWidth() + (av.alignment.getWidth() * av.charWidth);\r
926 \r
927       if (av.getWrapAlignment())\r
928       {\r
929         height = ( (av.alignment.getWidth() / av.getChunkWidth()) + 1) *\r
930             av.chunkHeight;\r
931         width = seqPanel.getWidth() + idPanel.getWidth();\r
932 \r
933       }\r
934 \r
935 \r
936         if (av.getShowAnnotation())\r
937         {\r
938             height += annotationPanel.getPreferredSize().height;\r
939         }\r
940 \r
941         try\r
942         {\r
943 \r
944             FileOutputStream out = new FileOutputStream(pngFile);\r
945 \r
946             BufferedImage bi = new BufferedImage(width, height,\r
947                     BufferedImage.TYPE_INT_RGB);\r
948             Graphics2D png = (Graphics2D) bi.getGraphics();\r
949 \r
950             png.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
951                 RenderingHints.VALUE_ANTIALIAS_ON);\r
952 \r
953             if (av.getWrapAlignment())\r
954             {\r
955                 printWrappedAlignment(png, width, height, 0);\r
956             }\r
957             else\r
958             {\r
959                 printUnwrapped(png, width, height, 0);\r
960             }\r
961 \r
962             ImageIO.write(bi, "png", out);\r
963             out.close();\r
964         }\r
965         catch(OutOfMemoryError err)\r
966         {\r
967           System.out.println("########################\n"\r
968                              +"OUT OF MEMORY "+pngFile+"\n"\r
969                              +"########################");\r
970         }\r
971         catch (Exception ex)\r
972         {\r
973             ex.printStackTrace();\r
974         }\r
975     }\r
976 }\r
977 \r
978 \r
979 /**\r
980  * DOCUMENT ME!\r
981  *\r
982  * @author $author$\r
983  * @version $Revision$\r
984  */\r
985 class Preview extends JFrame\r
986 {\r
987     /**\r
988      * Creates a new Preview object.\r
989      *\r
990      * @param image DOCUMENT ME!\r
991      */\r
992     public Preview(Image image)\r
993     {\r
994         setResizable(true);\r
995         setSize(image.getWidth(this), image.getHeight(this));\r
996         setVisible(true);\r
997         getContentPane().setLayout(new BorderLayout());\r
998         getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
999         validate();\r
1000         repaint();\r
1001     }\r
1002 }\r
1003 \r
1004 \r
1005 /**\r
1006  * DOCUMENT ME!\r
1007  *\r
1008  * @author $author$\r
1009  * @version $Revision$\r
1010  */\r
1011 class PreviewPanel extends JPanel\r
1012 {\r
1013     Image image;\r
1014 \r
1015     /**\r
1016      * Creates a new PreviewPanel object.\r
1017      *\r
1018      * @param image DOCUMENT ME!\r
1019      */\r
1020     public PreviewPanel(Image image)\r
1021     {\r
1022         this.image = image;\r
1023     }\r
1024 \r
1025     /**\r
1026      * DOCUMENT ME!\r
1027      *\r
1028      * @param g DOCUMENT ME!\r
1029      */\r
1030     public void paintComponent(Graphics g)\r
1031     {\r
1032         if (image != null)\r
1033         {\r
1034             g.drawImage(image, 0, 0, this);\r
1035         }\r
1036         else\r
1037         {\r
1038             System.out.println("DEBUG:image is null");\r
1039         }\r
1040     }\r
1041 }\r