1 /* PrintVCFview
2  *
3  * Copyright(C) 2010  Genome Research Limited
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or(at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  */
20 
21 package uk.ac.sanger.artemis.components.variant;
22 
23 import java.awt.*;
24 import java.awt.image.BufferedImage;
25 import java.awt.image.RenderedImage;
26 import java.awt.print.PageFormat;
27 import java.awt.print.Printable;
28 import java.awt.print.PrinterException;
29 import java.awt.print.PrinterJob;
30 import java.awt.event.*;
31 import javax.swing.*;
32 import java.io.*;
33 
34 import uk.ac.sanger.artemis.editor.ScrollPanel;
35 
36 /**
37 * Use to print images from VCFview
38 */
39 public class PrintVCFview extends ScrollPanel implements Printable
40 {
41   private static final long serialVersionUID = 1L;
42   private VCFview vcfView;
43 
PrintVCFview(VCFview vcfView)44   public PrintVCFview(VCFview vcfView)
45   {
46     super();
47     setBackground(Color.white);
48     this.vcfView = vcfView;
49   }
50 
51   /**
52   *
53   * Override paintComponent to draw entry
54   *
55   */
paintComponent(Graphics g)56   public void paintComponent(Graphics g)
57   {
58 // let UI delegate paint first (incl. background filling)
59     super.paintComponent(g);
60     vcfView.paintComponent(g);
61   }
62 
63 
64   /**
65   *
66   * Set the size of the image
67   *
68   */
setImageSize()69   private void setImageSize()
70   {
71     setPreferredSize(vcfView.getPreferredSize());
72   }
73 
74   /**
75   *
76   * Display a print preview page
77   *
78   */
printPreview()79   protected void printPreview()
80   {
81     final JFrame f = new JFrame("Print Preview");
82     JPanel jpane   = (JPanel)f.getContentPane();
83 
84     JScrollPane scrollPane = new JScrollPane(this);
85 
86     jpane.setLayout(new BorderLayout());
87     jpane.add(scrollPane,BorderLayout.CENTER);
88 
89     final Dimension dScreen = f.getToolkit().getScreenSize();
90     Dimension d = new Dimension((int)(3*dScreen.getWidth()/4),
91                                 (int)(dScreen.getHeight()/2));
92     f.setSize(d);
93     setImageSize();
94 
95     JMenuBar menuBar = new JMenuBar();
96     JMenu filemenu = new JMenu("File");
97     menuBar.add(filemenu);
98 
99 // print png/jpeg
100     JMenuItem printImage = new JMenuItem("Save As Image Files (png/jpeg)...");
101     printImage.addActionListener(new ActionListener()
102     {
103       public void actionPerformed(ActionEvent e)
104       {
105         print();
106       }
107     });
108     filemenu.add(printImage);
109 
110 //  print PostScript
111     JMenuItem printPS = new JMenuItem("Print...");
112     printPS.addActionListener(new ActionListener()
113     {
114       public void actionPerformed(ActionEvent e)
115       {
116         doPrintActions();
117       }
118     });
119     filemenu.add(printPS);
120 
121 // close
122     filemenu.add(new JSeparator());
123     JMenuItem menuClose = new JMenuItem("Close");
124     menuClose.setAccelerator(KeyStroke.getKeyStroke(
125               KeyEvent.VK_E, ActionEvent.CTRL_MASK));
126 
127     filemenu.add(menuClose);
128     menuClose.addActionListener(new ActionListener()
129     {
130       public void actionPerformed(ActionEvent e)
131       {
132         f.dispose();
133       }
134     });
135 
136     f.setJMenuBar(menuBar);
137     f.setVisible(true);
138   }
139 
140   /**
141   *
142   * Print to a jpeg or png file
143   *
144   */
print()145   public void print()
146   {
147     // file chooser
148     String cwd = System.getProperty("user.dir");
149     JFileChooser fc = new JFileChooser(cwd);
150     File fselect = new File(cwd+
151                             System.getProperty("file.separator")+
152                             "vcfView.png");
153     fc.setSelectedFile(fselect);
154 
155     // file name prefix
156     Box YBox = Box.createVerticalBox();
157     JLabel labFormat = new JLabel("Select Format:");
158     Font font = labFormat.getFont();
159     labFormat.setFont(font.deriveFont(Font.BOLD));
160     YBox.add(labFormat);
161 
162     Box bacross = Box.createHorizontalBox();
163     JComboBox formatSelect =
164        new JComboBox(javax.imageio.ImageIO.getWriterFormatNames());
165     formatSelect.setSelectedItem("png");
166 
167     Dimension d = formatSelect.getPreferredSize();
168     formatSelect.setMaximumSize(d);
169     bacross.add(Box.createHorizontalGlue());
170     bacross.add(formatSelect);
171     YBox.add(bacross);
172 
173 
174     // file prefix & format options
175     fc.setAccessory(YBox);
176     int n = fc.showSaveDialog(null);
177     if(n == JFileChooser.CANCEL_OPTION)
178       return;
179 
180     // remove file extension
181     String fsave = fc.getSelectedFile().getAbsolutePath().toLowerCase();
182     if(fsave.endsWith(".png") ||
183        fsave.endsWith(".jpg") ||
184        fsave.endsWith(".jpeg") )
185     {
186       int ind = fsave.lastIndexOf(".");
187       fsave = fc.getSelectedFile().getAbsolutePath();
188       fsave = fsave.substring(0,ind);
189     }
190     else
191       fsave = fc.getSelectedFile().getAbsolutePath();
192 
193     // image type
194     String ftype = (String)formatSelect.getSelectedItem();
195     try
196     {
197       RenderedImage rendImage = createImage();
198       writeImageToFile(rendImage, new File(fsave+"."+ftype),
199                        ftype);
200     }
201     catch(NoClassDefFoundError ex)
202     {
203       JOptionPane.showMessageDialog(this,
204             "This option requires Java 1.8 or higher.");
205     }
206   }
207 
doPrintActions()208   protected void doPrintActions()
209   {
210     final PrinterJob pj=PrinterJob.getPrinterJob();
211     pj.setPrintable(PrintVCFview.this);
212     pj.printDialog();
213     try
214     {
215       pj.print();
216     }
217     catch (Exception PrintException) {}
218   }
219 
220   /**
221   *  Returns a generated image
222   *  @param pageIndex   page number
223   *  @return            image
224   */
createImage()225   private RenderedImage createImage()
226   {
227     setImageSize();
228     // Create a buffered image in which to draw
229     BufferedImage bufferedImage = new BufferedImage(
230                                   vcfView.getWidth(), vcfView.getHeight(),
231                                   BufferedImage.TYPE_INT_RGB);
232     // Create a graphics contents on the buffered image
233     Graphics2D g2d = bufferedImage.createGraphics();
234     paintComponent(g2d);
235 
236     return bufferedImage;
237   }
238 
239 
240   /**
241   * Write out the image
242   * @param image        image
243   * @param file         file to write image to
244   * @param type         type of image
245   */
writeImageToFile(RenderedImage image, File file, String type)246   private void writeImageToFile(RenderedImage image,
247                                File file, String type)
248   {
249     try
250     {
251       javax.imageio.ImageIO.write(image,type,file);
252     }
253     catch ( IOException e )
254     {
255       System.out.println("Java 1.8+ is required");
256       e.printStackTrace();
257     }
258   }
259 
260   /**
261   *
262   * The method @print@ must be implemented for @Printable@ interface.
263   * Parameters are supplied by system.
264   *
265   */
print(Graphics g, PageFormat pf, int pageIndex)266   public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException
267   {
268     setImageSize();
269     Graphics2D g2 = (Graphics2D) g;
270 
271 //  RepaintManager.currentManager(this).setDoubleBufferingEnabled(false);
272     Dimension d = this.getSize();    //get size of document
273     double panelWidth  = d.width;    //width in pixels
274     double panelHeight = d.height;   //height in pixels
275 
276     if(panelWidth == 0)
277     {
278       d = this.getPreferredSize();
279       panelWidth  = d.width;
280       panelHeight = d.height;
281     }
282     double pageHeight = pf.getImageableHeight();   //height of printer page
283     double pageWidth  = pf.getImageableWidth();    //width of printer page
284     double scale = pageWidth/panelWidth;
285     int totalNumPages = (int)Math.ceil(scale * panelHeight / pageHeight);
286     // Make sure not print empty pages
287     if(pageIndex >= totalNumPages)
288      return Printable.NO_SUCH_PAGE;
289 
290     // Shift Graphic to line up with beginning of print-imageable region
291     g2.translate(pf.getImageableX(), pf.getImageableY());
292     // Shift Graphic to line up with beginning of next page to print
293     g2.translate(0f, -pageIndex*pageHeight);
294     // Scale the page so the width fits...
295     g2.scale(scale, scale);
296     paintComponent(g2);
297     return Printable.PAGE_EXISTS;
298   }
299 }
300