Accelerator on menu takes care of actionkey
[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 && (av.getStartSeq()>results[0]\r
160                         || av.getEndSeq()<results[0]\r
161                         || av.getStartRes()>results[1]\r
162                         || av.getEndRes()<results[2]))\r
163        setScrollValues(results[1], results[0]);\r
164 \r
165 \r
166  }\r
167 \r
168 \r
169  public OverviewPanel getOverviewPanel()\r
170  {\r
171    return overviewPanel;\r
172  }\r
173 \r
174  public void setOverviewPanel(OverviewPanel op)\r
175  {\r
176    overviewPanel = op;\r
177  }\r
178 \r
179 \r
180   public void setAnnotationVisible(boolean b)\r
181   {\r
182     annotationSpaceFillerHolder.setVisible(b);\r
183     annotationScroller.setVisible(b);\r
184   }\r
185 \r
186 \r
187   public void setWrapAlignment(boolean wrap)\r
188   {\r
189     scalePanelHolder.setVisible(!wrap);\r
190     hscroll.setVisible(!wrap);\r
191     idwidthAdjuster.setVisible(!wrap);\r
192 \r
193     av.setShowAnnotation(!wrap);\r
194     annotationScroller.setVisible(!wrap);\r
195     annotationSpaceFillerHolder.setVisible(!wrap);\r
196     idSpaceFillerPanel1.setVisible(!wrap);\r
197 \r
198     repaint();\r
199 \r
200   }\r
201 \r
202 \r
203   public void setColourScheme()\r
204   {\r
205     ColourSchemeI cs = av.getGlobalColourScheme();\r
206 \r
207     if(av.getConservationSelected())\r
208     {\r
209 \r
210        Alignment al = (Alignment)av.getAlignment();\r
211        Conservation c = new Conservation("All",\r
212                             ResidueProperties.propHash, 3, al.getSequences(), 0,\r
213                             al.getWidth() );\r
214 \r
215        c.calculate();\r
216        c.verdict(false, av.ConsPercGaps);\r
217        ConservationColourScheme ccs = new ConservationColourScheme(c, cs);\r
218 \r
219        av.setGlobalColourScheme( ccs );\r
220 \r
221     }\r
222 \r
223     repaint();\r
224   }\r
225 \r
226 \r
227   int hextent = 0;\r
228   int vextent = 0;\r
229 \r
230   // return value is true if the scroll is valid\r
231   public boolean scrollUp(boolean up)\r
232   {\r
233     if(up)\r
234     {\r
235       if(vscroll.getValue()<1)\r
236         return false;\r
237       fastPaint  = false;\r
238       vscroll.setValue(vscroll.getValue() - 1);\r
239     }\r
240     else\r
241     {\r
242      if(vextent+vscroll.getValue() >= av.getAlignment().getHeight())\r
243        return false;\r
244       fastPaint  = false;\r
245       vscroll.setValue(vscroll.getValue() + 1);\r
246     }\r
247     fastPaint = true;\r
248     return true;\r
249   }\r
250 \r
251   public boolean scrollRight(boolean right)\r
252   {\r
253 \r
254     if (right)\r
255     {\r
256       if (hscroll.getValue() < 1)\r
257         return false;\r
258       fastPaint = false;\r
259       hscroll.setValue(hscroll.getValue() - 1);\r
260     }\r
261     else\r
262     {\r
263       if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())\r
264         return false;\r
265       fastPaint = false;\r
266       hscroll.setValue(hscroll.getValue() + 1);\r
267     }\r
268     fastPaint = true;\r
269     return true;\r
270   }\r
271 \r
272 \r
273   public void setScrollValues(int x, int y)\r
274   {\r
275     av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
276 \r
277     hextent = seqPanel.seqCanvas.getWidth()/av.charWidth;\r
278     vextent = seqPanel.seqCanvas.getHeight()/av.charHeight;\r
279 \r
280     if(hextent > av.alignment.getWidth())\r
281       hextent = av.alignment.getWidth();\r
282     if(vextent > av.alignment.getHeight())\r
283       vextent = av.alignment.getHeight();\r
284 \r
285     if(hextent+x  >  av.getAlignment().getWidth())\r
286       x =  av.getAlignment().getWidth()- hextent;\r
287 \r
288     if(vextent+y > av.getAlignment().getHeight())\r
289       y = av.getAlignment().getHeight() - vextent;\r
290 \r
291     if(y<0)\r
292       y = 0;\r
293 \r
294     if(x<0)\r
295       x=0;\r
296 \r
297     hscroll.setValues(x,hextent,0,av.getAlignment().getWidth());\r
298     vscroll.setValues(y,vextent,0,av.getAlignment().getHeight() );\r
299 \r
300 \r
301 \r
302   }\r
303 \r
304 \r
305   public void adjustmentValueChanged(AdjustmentEvent evt)\r
306   {\r
307     int oldX = av.getStartRes();\r
308     int oldY = av.getStartSeq();\r
309 \r
310     if (evt.getSource() == hscroll)\r
311     {\r
312       int x = hscroll.getValue();\r
313       av.setStartRes(x);\r
314       av.setEndRes(x + seqPanel.seqCanvas.getWidth()/av.getCharWidth()-1);\r
315     }\r
316 \r
317     if (evt.getSource() == vscroll)\r
318     {\r
319       int offy = vscroll.getValue();\r
320       if (av.getWrapAlignment())\r
321       {\r
322         int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
323         av.setStartRes( vscroll.getValue() * rowSize );\r
324         av.setEndRes( (vscroll.getValue()+1) * rowSize );\r
325       }\r
326       else\r
327       {\r
328         av.setStartSeq(offy);\r
329         av.setEndSeq(offy + seqPanel.seqCanvas.getHeight() / av.getCharHeight());\r
330       }\r
331     }\r
332 \r
333     if(overviewPanel!=null)\r
334       overviewPanel.setBoxPosition();\r
335 \r
336     if(av.getWrapAlignment() || !fastPaint)\r
337       repaint();\r
338     else\r
339     {\r
340       idPanel.idCanvas.fastPaint(av.getStartSeq() - oldY);\r
341       seqPanel.seqCanvas.fastPaint(av.getStartRes() - oldX,\r
342                                    av.getStartSeq() - oldY);\r
343 \r
344       scalePanel.repaint();\r
345       if (av.getShowAnnotation())\r
346         annotationPanel.fastPaint(av.getStartRes() - oldX);\r
347     }\r
348 \r
349   }\r
350 \r
351 \r
352   public void paintComponent(Graphics g)\r
353   {\r
354     invalidate();\r
355     Dimension d = idPanel.idCanvas.getPreferredSize();\r
356     idPanelHolder.setPreferredSize(d);\r
357     hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));\r
358     validate();\r
359 \r
360     if (av.getWrapAlignment())\r
361     {\r
362       int max = av.alignment.getWidth() / seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
363       vscroll.setMaximum(max);\r
364       vscroll.setUnitIncrement(1);\r
365       vscroll.setVisibleAmount(1);\r
366     }\r
367     else\r
368     {\r
369       setScrollValues(av.getStartRes(), av.getStartSeq());\r
370     }\r
371 \r
372 \r
373 \r
374   }\r
375 \r
376   public int print(Graphics pg, PageFormat pf, int pi) throws PrinterException\r
377   {\r
378     pg.translate((int)pf.getImageableX(), (int)pf.getImageableY());\r
379 \r
380     int pwidth = (int) pf.getImageableWidth();\r
381     int pheight = (int) pf.getImageableHeight();\r
382 \r
383     if (av.getWrapAlignment())\r
384       return printWrappedAlignment(pg, pwidth,pheight, pi);\r
385     else\r
386       return printUnwrapped(pg,pwidth, pheight,pi);\r
387   }\r
388 \r
389   public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
390   {\r
391 \r
392       int idWidth = calculateIdWidth().width + 4;\r
393       FontMetrics fm = getFontMetrics(av.getFont());\r
394       int scaleHeight = av.charHeight + fm.getDescent();\r
395 \r
396       pg.setColor(Color.white);\r
397       pg.fillRect(0, 0, pwidth, pheight);\r
398       pg.setFont(av.getFont());\r
399 \r
400       ////////////////////////////////////\r
401       /// How many sequences and residues can we fit on a printable page?\r
402       int totalRes = (pwidth - idWidth) / av.getCharWidth();\r
403 \r
404       int totalSeq = (int) ( (pheight - scaleHeight) / av.getCharHeight()) - 1;\r
405 \r
406       int pagesWide = av.getAlignment().getWidth() / totalRes + 1;\r
407 \r
408       /////////////////////////////\r
409       /// Only print these sequences and residues on this page\r
410       int startRes, endRes, startSeq, endSeq;\r
411       startRes = (pi % pagesWide) * totalRes;\r
412       endRes = startRes + totalRes - 1;\r
413       if (endRes > av.getAlignment().getWidth()-1)\r
414         endRes = av.getAlignment().getWidth()-1;\r
415 \r
416       startSeq = (pi / pagesWide) * totalSeq;\r
417       endSeq = startSeq + totalSeq;\r
418       if (endSeq > av.getAlignment().getHeight())\r
419         endSeq = av.getAlignment().getHeight();\r
420 \r
421       int pagesHigh = ( (av.alignment.getHeight() / totalSeq) + 1) * pheight;\r
422 \r
423       if (av.showAnnotation)\r
424         pagesHigh += annotationPanel.getHeight();\r
425 \r
426       pagesHigh /= pheight;\r
427 \r
428       if (pi >= pagesWide * pagesHigh)\r
429         return Printable.NO_SUCH_PAGE;\r
430 \r
431         //draw Scale\r
432       pg.translate(idWidth, 0);\r
433       scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth, scaleHeight);\r
434       pg.translate( -idWidth, scaleHeight);\r
435       ////////////////\r
436       // Draw the ids\r
437       Color currentColor = null;\r
438       Color currentTextColor = null;\r
439       for (int i = startSeq; i < endSeq; i++)\r
440       {\r
441         if (av.getSelectionGroup() != null &&\r
442             av.getSelectionGroup().sequences.\r
443             contains(av.getAlignment().getSequenceAt(i)))\r
444         {\r
445           currentColor = Color.gray;\r
446           currentTextColor = Color.black;\r
447         }\r
448         else\r
449         {\r
450           currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
451           currentTextColor = Color.black;\r
452         }\r
453 \r
454         pg.setColor(currentColor);\r
455         pg.fillRect(0,\r
456                     jalview.analysis.AlignmentUtil.getPixelHeight(startSeq, i,\r
457             av.getCharHeight()),\r
458                     idWidth,\r
459                     av.getCharHeight());\r
460 \r
461         pg.setColor(currentTextColor);\r
462 \r
463         String string = av.getAlignment().getSequenceAt(i).getName();\r
464         if (av.getShowFullId())\r
465           string = av.getAlignment().getSequenceAt(i).getDisplayId();\r
466 \r
467         pg.drawString(string, 0, jalview.analysis.AlignmentUtil.getPixelHeight\r
468                       (startSeq, i, av.getCharHeight()) + av.getCharHeight() -\r
469                       (av.getCharHeight() / 5));\r
470       }\r
471 \r
472       // draw main sequence panel\r
473       pg.translate(idWidth, 0);\r
474       seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq,\r
475                                    startRes, startSeq, 0);\r
476 \r
477 \r
478       if (av.showAnnotation && endSeq == av.alignment.getHeight())\r
479       {\r
480         pg.translate( -idWidth, (endSeq - startSeq) * av.charHeight);\r
481         alabels.drawComponent( (Graphics2D) pg);\r
482         pg.translate(idWidth, 0);\r
483         annotationPanel.drawComponent( (Graphics2D) pg, startRes, endRes+1);\r
484       }\r
485 \r
486       return Printable.PAGE_EXISTS;\r
487 \r
488   }\r
489 \r
490 \r
491   public int printWrappedAlignment(Graphics pg, int pwidth, int pheight, int pi) throws PrinterException\r
492   {\r
493       int idWidth = calculateIdWidth().width + 4;\r
494 \r
495       int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth - idWidth);\r
496       int totalHeight = totalHeight = (av.alignment.getHeight() + 2) *\r
497           ( (av.alignment.getWidth()\r
498              / resWidth) + 1) * av.charHeight;\r
499 \r
500 \r
501       pg.setColor(Color.white);\r
502       pg.fillRect(0, 0, pwidth, pheight);\r
503       pg.setFont(av.getFont());\r
504 \r
505       ////////////////\r
506       // Draw the ids\r
507       pg.setColor(Color.black);\r
508 \r
509       pg.translate(0, -pi * pheight);\r
510 \r
511       pg.setClip(0,pi*pheight,pwidth, pheight);\r
512 \r
513       int ypos = 2 * av.charHeight;\r
514       do\r
515       {\r
516         for (int i = 0; i < av.alignment.getHeight(); i++)\r
517         {\r
518           SequenceI s = av.alignment.getSequenceAt(i);\r
519           String string = s.getName();\r
520           if (av.getShowFullId())\r
521             string = s.getDisplayId();\r
522 \r
523           pg.drawString(string, 0,\r
524                         AlignmentUtil.getPixelHeight(0, i, av.charHeight) +\r
525                         ypos +\r
526                         av.charHeight - (av.charHeight / 5));\r
527 \r
528         }\r
529 \r
530         ypos += (av.alignment.getHeight() + 2) * av.charHeight;\r
531 \r
532       }\r
533       while (ypos < totalHeight);\r
534 \r
535       pg.translate(idWidth, 0);\r
536 \r
537       seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight, 0);\r
538 \r
539       if (pi * pheight < totalHeight)\r
540         return Printable.PAGE_EXISTS;\r
541       else\r
542         return Printable.NO_SUCH_PAGE;\r
543 \r
544 \r
545 \r
546   }\r
547 \r
548 \r
549   public void makeEPS()\r
550   {\r
551     int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
552     int width = seqPanel.getWidth() + idPanel.getWidth();\r
553 \r
554     if (!av.getWrapAlignment())\r
555     {\r
556       height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
557       width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
558     }\r
559     if(av.getShowAnnotation())\r
560    {\r
561      height += annotationPanel.getPreferredSize().height;\r
562    }\r
563 \r
564     try\r
565     {\r
566       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
567           "LAST_DIRECTORY"), new String[]{"eps"}, "Encapsulated Postscript");\r
568       chooser.setFileView(new jalview.io.JalviewFileView());\r
569       chooser.setDialogTitle("Create EPS file from alignment");\r
570       chooser.setToolTipText("Save");\r
571 \r
572       int value = chooser.showSaveDialog(this);\r
573       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
574         return;\r
575 \r
576       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
577       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
578       EpsGraphics2D pg = new EpsGraphics2D("Example", out, 0, 0, width, height);\r
579 \r
580         if (av.getWrapAlignment())\r
581           printWrappedAlignment(pg, width, height, 0);\r
582         else\r
583           printUnwrapped(pg, width, height, 0);\r
584 \r
585 \r
586         pg.flush();\r
587         pg.close();\r
588     }\r
589     catch (Exception ex)\r
590     {\r
591       ex.printStackTrace();\r
592     }\r
593   }\r
594 \r
595   public void makePNG()\r
596   {\r
597       int height = (av.alignment.getWidth() / av.getChunkWidth() +1) * av.chunkHeight;\r
598       int width = seqPanel.getWidth() + idPanel.getWidth();\r
599 \r
600       if (!av.getWrapAlignment())\r
601       {\r
602         height = (av.alignment.getHeight()+1) * av.charHeight + 30;\r
603         width = idPanel.getWidth() + av.alignment.getWidth() * av.charWidth;\r
604       }\r
605 \r
606       if(av.getShowAnnotation())\r
607       {\r
608         height += annotationPanel.getPreferredSize().height;\r
609       }\r
610 \r
611 \r
612 \r
613     try\r
614     {\r
615       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(jalview.bin.Cache.getProperty(\r
616           "LAST_DIRECTORY"), new String[]{"png"}, "Portable network graphics");\r
617       chooser.setFileView(new jalview.io.JalviewFileView());\r
618       chooser.setDialogTitle("Create EPS file from alignment");\r
619       chooser.setToolTipText("Save");\r
620 \r
621       int value = chooser.showSaveDialog(this);\r
622       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
623         return;\r
624 \r
625       jalview.bin.Cache.setProperty("LAST_DIRECTORY",chooser.getSelectedFile().getPath());\r
626       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
627 \r
628       BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\r
629       Graphics2D png = (Graphics2D)bi.getGraphics();\r
630 \r
631       png.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);\r
632 \r
633         if (av.getWrapAlignment())\r
634           printWrappedAlignment(png, width, height, 0);\r
635         else\r
636           printUnwrapped(png, width, height, 0);\r
637 \r
638         ImageIO.write(bi, "png", out);\r
639         out.close();\r
640     }\r
641     catch (Exception ex)\r
642     {\r
643       ex.printStackTrace();\r
644     }\r
645   }\r
646 \r
647 }\r
648 \r
649 class Preview extends JFrame\r
650 {\r
651 \r
652   public Preview(Image image)\r
653   {\r
654     setResizable(true);\r
655     setSize(image.getWidth(this), image.getHeight(this));\r
656     setVisible(true);\r
657     getContentPane().setLayout(new BorderLayout());\r
658     getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
659     validate();\r
660     repaint();\r
661   }\r
662 }\r
663 \r
664 class PreviewPanel extends JPanel\r
665 {\r
666   Image image;\r
667   public PreviewPanel(Image image)\r
668   {\r
669     this.image = image;\r
670   }\r
671   public void paintComponent(Graphics g)\r
672   {\r
673     if(image!=null)\r
674       g.drawImage(image,0,0,this);\r
675     else\r
676       System.out.println("image is null");\r
677   }\r
678 }\r
679 \r
680 \r
681 \r
682 \r