consistent percentage gaps filter for conservation calculation.
[jalview.git] / src / jalview / gui / AlignmentPanel.java
1 package jalview.gui;\r
2 \r
3 import jalview.jbgui.GAlignmentPanel;\r
4 import jalview.schemes.*;\r
5 import jalview.analysis.*;\r
6 import jalview.datamodel.*;\r
7 import java.awt.*;\r
8 import java.awt.event.*;\r
9 import java.awt.print.*;\r
10 import java.io.*;\r
11 import java.awt.image.*;\r
12 import org.jibble.epsgraphics.*;\r
13 import javax.imageio.*;\r
14 \r
15 \r
16 \r
17 public class AlignmentPanel extends GAlignmentPanel implements AdjustmentListener, Printable\r
18 {\r
19 \r
20   AlignViewport     av;\r
21   OverviewPanel overviewPanel;\r
22   SeqPanel   seqPanel;\r
23   IdPanel    idPanel;\r
24   IdwidthAdjuster idwidthAdjuster;\r
25   public AlignFrame alignFrame;\r
26   ScalePanel scalePanel;\r
27   AnnotationPanel annotationPanel;\r
28   AnnotationLabels alabels;\r
29 \r
30   // this value is set false when selection area being dragged\r
31   boolean fastPaint = true;\r
32 \r
33   public AlignmentPanel(AlignFrame af, final AlignViewport av)\r
34   {\r
35     alignFrame = af;\r
36     this.av         = av;\r
37     seqPanel        = new SeqPanel  (av, this);\r
38     idPanel         = new IdPanel   (av, this);\r
39 \r
40     scalePanel = new ScalePanel(av, this);\r
41 \r
42     idPanelHolder.add(idPanel, BorderLayout.CENTER);\r
43     idwidthAdjuster = new IdwidthAdjuster(this);\r
44     idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);\r
45 \r
46     annotationPanel = new AnnotationPanel(this);\r
47     alabels = new AnnotationLabels(this);\r
48 \r
49     annotationSpaceFillerHolder.setPreferredSize(annotationPanel.getPreferredSize());\r
50     annotationScroller.setPreferredSize(annotationPanel.getPreferredSize());\r
51     annotationScroller.setViewportView(annotationPanel);\r
52     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
53 \r
54     Dimension d = calculateIdWidth();\r
55     d.setSize( d.width+4, d.height);\r
56     idPanel.idCanvas.setPreferredSize( d );\r
57     hscrollFillerPanel.setPreferredSize( d );\r
58 \r
59     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
60     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
61 \r
62     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
63      {\r
64        public void run()\r
65        {\r
66          invalidate();\r
67          setScrollValues(0,0);\r
68          Dimension d = calculateIdWidth();\r
69          d.setSize( d.width+4, d.height);\r
70          idPanel.idCanvas.setPreferredSize( d );\r
71          RefreshPanels();\r
72        }\r
73     });\r
74 \r
75 \r
76     hscroll.addAdjustmentListener(this);\r
77     vscroll.addAdjustmentListener(this);\r
78 \r
79     addComponentListener(new ComponentAdapter()\r
80    {\r
81      public void componentResized(ComponentEvent evt)\r
82      {\r
83           RefreshPanels();\r
84      }\r
85    });\r
86 \r
87    setFocusable(true);\r
88    addKeyListener(new KeyAdapter()\r
89    {\r
90      public void keyPressed(KeyEvent evt)\r
91      {\r
92        switch(evt.getKeyCode())\r
93        {\r
94          case  27: // escape key\r
95            av.setSelectionGroup(null);\r
96            RefreshPanels();\r
97            break;\r
98          case KeyEvent.VK_X:\r
99            if(evt.isControlDown())\r
100            alignFrame.cut_actionPerformed(null);\r
101            break;\r
102          case KeyEvent.VK_C:\r
103          if(evt.isControlDown())\r
104            alignFrame.copy_actionPerformed(null);\r
105            break;\r
106          case KeyEvent.VK_V:\r
107           if(evt.isControlDown())\r
108            alignFrame.paste(true);\r
109            break;\r
110          case KeyEvent.VK_A:\r
111          if(evt.isControlDown())\r
112            alignFrame.selectAllSequenceMenuItem_actionPerformed(null);\r
113            break;\r
114         case KeyEvent.VK_DOWN:\r
115           alignFrame.moveSelectedSequences(false);\r
116           break;\r
117         case KeyEvent.VK_UP:\r
118           alignFrame.moveSelectedSequences(true);\r
119           break;\r
120         case KeyEvent.VK_F:\r
121          if(evt.isControlDown())\r
122           alignFrame.findMenuItem_actionPerformed(null);\r
123           break;\r
124        }\r
125      }\r
126    });\r
127   }\r
128 \r
129   Dimension calculateIdWidth()\r
130   {\r
131     Graphics g = this.getGraphics();\r
132     if(g==null)\r
133     {\r
134       javax.swing.JFrame f = new javax.swing.JFrame();\r
135       f.addNotify();\r
136       g = f.getGraphics();\r
137     }\r
138 \r
139     FontMetrics fm = g.getFontMetrics(av.font);\r
140     AlignmentI al = av.getAlignment();\r
141 \r
142        int i   = 0;\r
143        int idWidth = 0;\r
144        String id;\r
145        while (i < al.getHeight() && al.getSequenceAt(i) != null)\r
146        {\r
147          SequenceI s   = al.getSequenceAt(i);\r
148          if(av.getShowFullId())\r
149            id   = s.getDisplayId();\r
150          else\r
151            id = s.getName();\r
152 \r
153          if (fm.stringWidth(id) > idWidth)\r
154            idWidth = fm.stringWidth(id);\r
155          i++;\r
156        }\r
157 \r
158        // Also check annotation label widths\r
159        i=0;\r
160        if(al.getAlignmentAnnotation()!=null)\r
161        {\r
162          fm = g.getFontMetrics(alabels.getFont());\r
163          while (i < al.getAlignmentAnnotation().length)\r
164          {\r
165            String label = al.getAlignmentAnnotation()[i].label;\r
166            if (fm.stringWidth(label) > idWidth)\r
167              idWidth = fm.stringWidth(label);\r
168            i++;\r
169          }\r
170        }\r
171 \r
172        return new Dimension(idWidth, 12);\r
173   }\r
174 \r
175 \r
176  public void highlightSearchResults(int [] results)\r
177  {\r
178    seqPanel.seqCanvas.highlightSearchResults( results );\r
179 \r
180    // do we need to scroll the panel?\r
181    if(results!=null && (av.getStartSeq()>results[0]\r
182                         || av.getEndSeq()<results[0]\r
183                         || av.getStartRes()>results[1]\r
184                         || av.getEndRes()<results[2]))\r
185        setScrollValues(results[1], results[0]);\r
186 \r
187 \r
188  }\r
189 \r
190 \r
191  public OverviewPanel getOverviewPanel()\r
192  {\r
193    return overviewPanel;\r
194  }\r
195 \r
196  public void setOverviewPanel(OverviewPanel op)\r
197  {\r
198    overviewPanel = op;\r
199  }\r
200 \r
201 \r
202   public void setAnnotationVisible(boolean b)\r
203   {\r
204     annotationSpaceFillerHolder.setVisible(b);\r
205     annotationScroller.setVisible(b);\r
206     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
207      {\r
208        public void run()\r
209        {\r
210          RefreshPanels();\r
211        }\r
212     });\r
213 \r
214   }\r
215 \r
216 \r
217   public void setWrapAlignment(boolean wrap)\r
218   {\r
219     scalePanelHolder.setVisible(!wrap);\r
220     hscroll.setVisible(!wrap);\r
221     idwidthAdjuster.setVisible(!wrap);\r
222 \r
223     av.setShowAnnotation(!wrap);\r
224     annotationScroller.setVisible(!wrap);\r
225     annotationSpaceFillerHolder.setVisible(!wrap);\r
226     idSpaceFillerPanel1.setVisible(!wrap);\r
227     javax.swing.SwingUtilities.invokeLater(new Runnable()\r
228      {\r
229        public void run()\r
230        {\r
231          RefreshPanels();\r
232        }\r
233     });\r
234 \r
235   }\r
236 \r
237 \r
238   public void setColourScheme()\r
239   {\r
240     ColourSchemeI cs = av.getGlobalColourScheme();\r
241 \r
242     if(av.getConservationSelected())\r
243     {\r
244 \r
245        Alignment al = (Alignment)av.getAlignment();\r
246        Conservation c = new Conservation("All",\r
247                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
248                             al.getWidth() );\r
249 \r
250        c.calculate();\r
251        c.verdict(false, av.ConsPercGaps);\r
252        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
253 \r
254        av.setGlobalColourScheme( ccs );\r
255 \r
256     }\r
257 \r
258     RefreshPanels();\r
259   }\r
260 \r
261 \r
262   public void RefreshPanels()\r
263   {\r
264 \r
265     Dimension d = idPanel.idCanvas.getPreferredSize();\r
266     idPanelHolder.setPreferredSize(d);\r
267     hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
268 \r
269     if (av.getWrapAlignment())\r
270     {\r
271       int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
272       vscroll.setValues(0, 1, 0, max);\r
273     }\r
274     else\r
275     {\r
276       if (overviewPanel != null)\r
277         overviewPanel.updateOverviewImage();\r
278       setScrollValues(av.getStartRes(), av.getStartSeq());\r
279     }\r
280 \r
281     validate();\r
282     repaint();\r
283   }\r
284 \r
285 \r
286   int hextent = 0;\r
287   int vextent = 0;\r
288 \r
289   // return value is true if the scroll is valid\r
290   public boolean scrollUp(boolean up)\r
291   {\r
292     if(up)\r
293     {\r
294       if(vscroll.getValue()<1)\r
295         return false;\r
296       fastPaint  = false;\r
297       vscroll.setValue(vscroll.getValue() - 1);\r
298     }\r
299     else\r
300     {\r
301      if(vextent+vscroll.getValue() >= av.getAlignment().getHeight())\r
302        return false;\r
303       fastPaint  = false;\r
304       vscroll.setValue(vscroll.getValue() + 1);\r
305     }\r
306     fastPaint = true;\r
307     return true;\r
308   }\r
309 \r
310   public boolean scrollRight(boolean right)\r
311   {\r
312 \r
313     if (right)\r
314     {\r
315       if (hscroll.getValue() < 1)\r
316         return false;\r
317       fastPaint = false;\r
318       hscroll.setValue(hscroll.getValue() - 1);\r
319     }\r
320     else\r
321     {\r
322       if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())\r
323         return false;\r
324       fastPaint = false;\r
325       hscroll.setValue(hscroll.getValue() + 1);\r
326     }\r
327     fastPaint = true;\r
328     return true;\r
329   }\r
330 \r
331 \r
332   public void setScrollValues(int x, int y)\r
333   {\r
334     hextent = seqPanel.seqCanvas.getWidth()/av.charWidth;\r
335     vextent = seqPanel.seqCanvas.getHeight()/av.charHeight;\r
336 \r
337     if(hextent > av.alignment.getWidth())\r
338       hextent = av.alignment.getWidth();\r
339     if(vextent > av.alignment.getHeight())\r
340       vextent = av.alignment.getHeight();\r
341 \r
342     if(hextent+x  >  av.getAlignment().getWidth())\r
343       x =  av.getAlignment().getWidth()- hextent;\r
344 \r
345     if(vextent+y > av.getAlignment().getHeight())\r
346       y = av.getAlignment().getHeight() - vextent;\r
347 \r
348     if(y<0)\r
349       y = 0;\r
350 \r
351     if(x<0)\r
352       x=0;\r
353 \r
354     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
355     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
356 \r
357   }\r
358 \r
359 \r
360   public void adjustmentValueChanged(AdjustmentEvent evt)\r
361   {\r
362     int oldX = av.getStartRes();\r
363     int oldY = av.getStartSeq();\r
364 \r
365     if (evt.getSource() == hscroll)\r
366     {\r
367       int x = hscroll.getValue();\r
368       av.setStartRes(x);\r
369       av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
370     }\r
371 \r
372     if (evt.getSource() == vscroll)\r
373     {\r
374       int offy = vscroll.getValue();\r
375       if (av.getWrapAlignment())\r
376       {\r
377         int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
378         av.setStartRes( vscroll.getValue() * rowSize );\r
379         av.setEndRes( (vscroll.getValue()+1) * rowSize );\r
380       }\r
381       else\r
382       {\r
383         av.setStartSeq(offy);\r
384         av.setEndSeq(offy + seqPanel.seqCanvas.getHeight() / av.getCharHeight());\r
385       }\r
386     }\r
387 \r
388 \r
389     if(overviewPanel!=null)\r
390       overviewPanel.setBoxPosition();\r
391 \r
392     if(av.getWrapAlignment() || !fastPaint)\r
393       repaint();\r
394     else\r
395     {\r
396       seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
397                                    av.getStartSeq() - oldY);\r
398       idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
399       scalePanel.repaint();\r
400       if (av.getShowAnnotation())\r
401         annotationPanel.fastPaint(av.getStartRes() - oldX);\r
402     }\r
403 \r
404   }\r
405 \r
406   public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
407   {\r
408     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
409 \r
410     int pwidth = (int) pf.getImageableWidth();\r
411     int pheight = (int) pf.getImageableHeight();\r
412 \r
413     if (av.getWrapAlignment())\r
414       return printWrappedAlignment(pg, pwidth,pheight, pi);\r
415     else\r
416       return printUnwrapped(pg,pwidth, pheight,pi);\r
417   }\r
418 \r
419   public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
420   {\r
421 \r
422     int idWidth = calculateIdWidth().width + 4;\r
423 \r
424 \r
425     pg.setColor(Color.white);\r
426     pg.fillRect(0,0,pwidth, pheight);\r
427     pg.setFont( av.getFont() );\r
428 \r
429     ////////////////////////////////////\r
430     /// How many sequences and residues can we fit on a printable page?\r
431     int totalRes = (pwidth - idWidth)/av.getCharWidth();\r
432     int totalSeq = (int)((pheight - 30)/av.getCharHeight())-1;\r
433     int pagesWide = av.getAlignment().getWidth() / totalRes +1;\r
434     int pagesHigh = av.getAlignment().getHeight() / totalSeq +1;\r
435 \r
436     if (pi >= pagesWide*pagesHigh)\r
437      return Printable.NO_SUCH_PAGE;\r
438 \r
439     /////////////////////////////\r
440     /// Only print these sequences and residues on this page\r
441     int startRes, endRes, startSeq, endSeq;\r
442     startRes = (pi % pagesWide) * totalRes;\r
443     endRes = startRes + totalRes-1;\r
444     if(endRes>av.getAlignment().getWidth())\r
445       endRes = av.getAlignment().getWidth();\r
446 \r
447      startSeq = (pi / pagesWide) * totalSeq;\r
448      endSeq = startSeq + totalSeq;\r
449      if(endSeq > av.getAlignment().getHeight())\r
450        endSeq = av.getAlignment().getHeight();\r
451 \r
452 \r
453     ////////////////\r
454     //draw Scale\r
455     pg.translate(idWidth,0);\r
456     scalePanel.drawScale(pg, startRes, endRes, pwidth-idWidth);\r
457 \r
458     pg.translate(-idWidth, 30);\r
459     ////////////////\r
460     // Draw the ids\r
461     Color currentColor=null;\r
462     Color currentTextColor=null;\r
463     for(int i=startSeq; i<endSeq; i++)\r
464     {\r
465       if (av.getSelectionGroup()!=null && av.getSelectionGroup().sequences.contains(av.getAlignment().getSequenceAt(i)))\r
466       {\r
467         currentColor = Color.gray;\r
468         currentTextColor = Color.black;\r
469       }\r
470       else\r
471       {\r
472         currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
473         currentTextColor = Color.black;\r
474       }\r
475 \r
476       pg.setColor(currentColor);\r
477       pg.fillRect(0,  jalview.analysis.AlignmentUtil.getPixelHeight(startSeq, i, av.getCharHeight()),\r
478                               idWidth,\r
479                               av.getCharHeight());\r
480 \r
481       pg.setColor(currentTextColor);\r
482 \r
483       String string = av.getAlignment().getSequenceAt(i).getName();\r
484       if(av.getShowFullId())\r
485         string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
486 \r
487       pg.drawString(string, 0,  jalview.analysis.AlignmentUtil.getPixelHeight\r
488                     (startSeq, i, av.getCharHeight()) + av.getCharHeight() - (av.getCharHeight() / 5));\r
489     }\r
490 \r
491     // draw main sequence panel\r
492     pg.translate(idWidth,0);\r
493     seqPanel.seqCanvas.drawPanel(pg,startRes,endRes,startSeq,endSeq,startRes,startSeq,0);\r
494 \r
495 \r
496     if(av.getShowAnnotation())\r
497       {\r
498         pg.translate(-idWidth,(endSeq-startSeq)*av.charHeight);\r
499         alabels.drawComponent((Graphics2D)pg);\r
500         pg.translate(idWidth,0);\r
501         annotationPanel.drawComponent((Graphics2D) pg, startRes, endRes+1);\r
502       }\r
503 \r
504     return Printable.PAGE_EXISTS;\r
505   }\r
506 \r
507 \r
508   public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
509   {\r
510 \r
511     int idWidth = calculateIdWidth().width+4;\r
512 \r
513     if( seqPanel.seqCanvas.getWidth() < pwidth-idWidth)\r
514       pwidth = seqPanel.seqCanvas.getWidth() + idWidth;\r
515 \r
516 \r
517     pg.setColor(Color.white);\r
518     pg.fillRect(0,0,pwidth, pheight);\r
519     pg.setFont( av.getFont() );\r
520 \r
521     ////////////////////////////////////\r
522     /// How many sequences and residues can we fit on a printable page?\r
523     AlignmentI da = av.alignment;\r
524     int endy   = da.getHeight();\r
525     int chunkHeight =  (da.getHeight() + 2)*av.charHeight;\r
526     int chunkWidth  =   (pwidth-idWidth)/av.charWidth;\r
527 \r
528     int noChunksOnPage = pheight / chunkHeight;\r
529     int totalChunks = da.getWidth() / chunkWidth;\r
530 \r
531     if ( pi*noChunksOnPage > totalChunks )\r
532      return Printable.NO_SUCH_PAGE;\r
533 \r
534     ////////////////\r
535     // Draw the ids\r
536     pg.setClip(0,0,pwidth, noChunksOnPage*chunkHeight);\r
537 \r
538     pg.setColor(Color.black);\r
539 \r
540     int rowSize =  av.getEndRes() - av.getStartRes();\r
541     // Draw the rest of the panels\r
542 \r
543     for(int ypos=2*av.charHeight, row=av.getEndRes(); row<av.alignment.getWidth();\r
544         ypos += av.chunkHeight, row+=rowSize )\r
545     {\r
546       for (int i = 0; i < endy; i++)\r
547       {\r
548         SequenceI s = da.getSequenceAt(i);\r
549         String string = s.getName();\r
550         if (av.getShowFullId())\r
551           string = s.getDisplayId();\r
552 \r
553         pg.drawString(string, 0,\r
554                       AlignmentUtil.getPixelHeight(0, i, av.charHeight) + ypos +\r
555                       av.charHeight - (av.charHeight / 5));\r
556       }\r
557     }\r
558 \r
559     // draw main sequence panel\r
560     pg.translate(idWidth,0);\r
561     seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth-idWidth, pheight, pi*noChunksOnPage*chunkWidth);\r
562 \r
563 \r
564     return Printable.PAGE_EXISTS;\r
565 \r
566   }\r
567 \r
568 \r
569   public void makeEPS()\r
570   {\r
571     int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
572     int width = seqPanel.getWidth() + idPanel.getWidth();\r
573 \r
574     if (!av.getWrapAlignment())\r
575     {\r
576       height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
577       width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
578     }\r
579     if(av.getShowAnnotation())\r
580    {\r
581      height += annotationPanel.getPreferredSize().height;\r
582    }\r
583 \r
584     try\r
585     {\r
586       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
587           "LAST_DIRECTORY"), new String[]{"eps"}, "Encapsulated Postscript");\r
588       chooser.setFileView(new jalview.io.JalviewFileView());\r
589       chooser.setDialogTitle("Create EPS file from alignment");\r
590       chooser.setToolTipText("Save");\r
591 \r
592       int value = chooser.showSaveDialog(this);\r
593       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
594         return;\r
595 \r
596       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
597       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
598       EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width, height);\r
599 \r
600         if (av.getWrapAlignment())\r
601           printWrappedAlignment(pg, width, height, 0);\r
602         else\r
603           printUnwrapped(pg, width, height, 0);\r
604 \r
605 \r
606         pg.flush();\r
607         pg.close();\r
608     }\r
609     catch (Exception ex)\r
610     {\r
611       ex.printStackTrace();\r
612     }\r
613   }\r
614 \r
615   public void makePNG()\r
616   {\r
617       int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
618       int width = seqPanel.getWidth() + idPanel.getWidth();\r
619 \r
620       if (!av.getWrapAlignment())\r
621       {\r
622         height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
623         width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
624       }\r
625 \r
626       if(av.getShowAnnotation())\r
627       {\r
628         height += annotationPanel.getPreferredSize().height;\r
629       }\r
630 \r
631 \r
632 System.out.println(width +" "+height);\r
633 \r
634     try\r
635     {\r
636       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
637           "LAST_DIRECTORY"), new String[]{"png"}, "Portable network graphics");\r
638       chooser.setFileView(new jalview.io.JalviewFileView());\r
639       chooser.setDialogTitle("Create EPS file from alignment");\r
640       chooser.setToolTipText("Save");\r
641 \r
642       int value = chooser.showSaveDialog(this);\r
643       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
644         return;\r
645 \r
646       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
647       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
648 \r
649       BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\r
650       Graphics png = bi.getGraphics();\r
651 \r
652 \r
653         if (av.getWrapAlignment())\r
654           printWrappedAlignment(png, width, height, 0);\r
655         else\r
656           printUnwrapped(png, width, height, 0);\r
657 \r
658         ImageIO.write(bi, "png", out);\r
659         out.close();\r
660     }\r
661     catch (Exception ex)\r
662     {\r
663       ex.printStackTrace();\r
664     }\r
665   }\r
666 \r
667 }\r
668 \r
669 \r
670 \r
671 \r