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