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