1 /* 2 * Copyright (C) 2008 Genome Research Limited 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 * @author: Tim Carver 19 */ 20 21 package uk.ac.sanger.artemis.circular; 22 23 import java.awt.BorderLayout; 24 import java.awt.Color; 25 import java.awt.Dimension; 26 import java.awt.Font; 27 import java.awt.Graphics; 28 import java.awt.Graphics2D; 29 import java.awt.print.PageFormat; 30 import java.awt.print.Paper; 31 import java.awt.print.PrinterJob; 32 import java.awt.event.ActionEvent; 33 import java.awt.event.ActionListener; 34 import java.awt.event.KeyEvent; 35 import java.awt.image.BufferedImage; 36 import java.awt.image.RenderedImage; 37 import java.io.File; 38 import java.io.FileNotFoundException; 39 import java.io.FileOutputStream; 40 import java.io.IOException; 41 import java.io.OutputStreamWriter; 42 import java.io.UnsupportedEncodingException; 43 import java.io.Writer; 44 45 import javax.swing.BorderFactory; 46 import javax.swing.Box; 47 import javax.swing.JComboBox; 48 import javax.swing.JFileChooser; 49 import javax.swing.JFrame; 50 import javax.swing.JLabel; 51 import javax.swing.JMenu; 52 import javax.swing.JMenuBar; 53 import javax.swing.JMenuItem; 54 import javax.swing.JOptionPane; 55 import javax.swing.JPanel; 56 import javax.swing.JScrollPane; 57 import javax.swing.JSeparator; 58 import javax.swing.JTextField; 59 import javax.swing.KeyStroke; 60 import javax.swing.border.Border; 61 62 import org.apache.batik.dom.GenericDOMImplementation; 63 import org.apache.batik.svggen.SVGGeneratorContext; 64 import org.apache.batik.svggen.SVGGraphics2D; 65 import org.apache.batik.svggen.SVGGraphics2DIOException; 66 import org.w3c.dom.DOMImplementation; 67 import org.w3c.dom.Document; 68 69 import uk.ac.sanger.artemis.Options; 70 import uk.ac.sanger.artemis.components.PrintArtemis; 71 import uk.ac.sanger.artemis.components.StickyFileChooser; 72 73 74 75 76 /** 77 * 78 * Print png/jpeg image and print preview. 79 * The imageio package is used here to create jpeg and png images of the 80 * DNA diagram. 81 * 82 */ 83 public class PrintDNAImage extends ScrollPanel 84 { 85 private static final long serialVersionUID = 1L; 86 87 /** page format */ 88 private PageFormat format = null; 89 90 /** alignment sequence panel */ 91 private DNADraw dna; 92 /** status field for print preview */ 93 private JTextField statusField = new JTextField(""); 94 /** type (jpeg/png) */ 95 private String type; 96 97 /** 98 * 99 * @param dna dna panel 100 * 101 */ PrintDNAImage(DNADraw dna)102 public PrintDNAImage(DNADraw dna) 103 { 104 super(); 105 this.dna = dna; 106 107 setBackground(Color.white); 108 } 109 110 111 /** 112 * 113 * Override this method to draw the sequences 114 * @return Graphics g 115 * 116 */ paintComponent(Graphics g)117 public void paintComponent(Graphics g) 118 { 119 // let UI delegate paint first (incl. background filling) 120 super.paintComponent(g); 121 Graphics2D g2d = (Graphics2D) g.create(); 122 dna.drawAll(g2d,true); 123 } 124 125 /** 126 * 127 * Get a default page format 128 * @return page format 129 * 130 */ getFormatDialog()131 protected PageFormat getFormatDialog() 132 { 133 PrinterJob printerJob = PrinterJob.getPrinterJob(); 134 format = new PageFormat(); 135 format = printerJob.pageDialog(format); 136 return format; 137 } 138 139 140 /** 141 * 142 * Returns a generated image 143 * @param pageIndex page number 144 * @return image 145 * 146 */ createDNAImage(int pageIndex)147 private RenderedImage createDNAImage(int pageIndex) 148 { 149 int width = (int)format.getWidth(); 150 int height = (int)format.getHeight(); 151 // Create a buffered image in which to draw 152 BufferedImage bufferedImage = new BufferedImage( 153 width,height, 154 BufferedImage.TYPE_INT_RGB); 155 156 // Create a graphics contents on the buffered image 157 Graphics2D g2d = bufferedImage.createGraphics(); 158 g2d.setColor(Color.white); 159 g2d.fillRect(0,0,width,height); 160 // Draw graphics 161 dna.drawAll(g2d,true); 162 163 return bufferedImage; 164 } 165 166 167 /** 168 * 169 * Display a print preview page 170 * 171 */ printPreview()172 protected void printPreview() 173 { 174 Border loweredbevel = BorderFactory.createLoweredBevelBorder(); 175 Border raisedbevel = BorderFactory.createRaisedBevelBorder(); 176 Border compound = BorderFactory.createCompoundBorder(raisedbevel,loweredbevel); 177 statusField.setBorder(compound); 178 statusField.setEditable(false); 179 180 if(format == null) 181 format = getFormatDialog(); 182 183 statusField.setText("DNA map"); 184 final JFrame f = new JFrame("Print Preview"); 185 JPanel jpane = (JPanel)f.getContentPane(); 186 JScrollPane scrollPane = new JScrollPane(this); 187 jpane.setLayout(new BorderLayout()); 188 jpane.add(scrollPane,BorderLayout.CENTER); 189 jpane.add(statusField,BorderLayout.SOUTH); 190 191 Dimension d = new Dimension((int)format.getWidth(), 192 (int)format.getHeight()); 193 setPreferredSize(d); 194 f.setSize(d); 195 196 JMenuBar menuBar = new JMenuBar(); 197 JMenu filemenu = new JMenu("File"); 198 menuBar.add(filemenu); 199 200 // print postscript 201 JMenu printMenu = new JMenu("Print"); 202 filemenu.add(printMenu); 203 204 JMenuItem print = new JMenuItem("Print Postscript..."); 205 print.addActionListener(new ActionListener() 206 { 207 public void actionPerformed(ActionEvent e) 208 { 209 dna.doPrintActions(); 210 } 211 }); 212 printMenu.add(print); 213 214 // print png/jpeg 215 JMenuItem printImage = new JMenuItem("Print png/jpeg Image..."); 216 printImage.addActionListener(new ActionListener() 217 { 218 public void actionPerformed(ActionEvent e) 219 { 220 printAsSinglePage(); 221 } 222 }); 223 printMenu.add(printImage); 224 225 // close 226 filemenu.add(new JSeparator()); 227 JMenuItem menuClose = new JMenuItem("Close"); 228 menuClose.setAccelerator(KeyStroke.getKeyStroke( 229 KeyEvent.VK_E, ActionEvent.CTRL_MASK)); 230 231 filemenu.add(menuClose); 232 menuClose.addActionListener(new ActionListener() 233 { 234 public void actionPerformed(ActionEvent e) 235 { 236 f.dispose(); 237 } 238 }); 239 240 f.setJMenuBar(menuBar); 241 f.setVisible(true); 242 } 243 244 /** 245 * Provide some options for the image created 246 */ showOptions()247 private File showOptions() 248 { 249 final StickyFileChooser fc = new StickyFileChooser(); 250 File fselect = new File(fc.getCurrentDirectory()+ 251 System.getProperty("file.separator")+ 252 "dnaplotter.png"); 253 fc.setSelectedFile(fselect); 254 255 // file name prefix 256 Box bdown = Box.createVerticalBox(); 257 bdown.add(Box.createVerticalGlue()); 258 259 JLabel labFormat = new JLabel("Select Format:"); 260 Font font = labFormat.getFont(); 261 labFormat.setFont(font.deriveFont(Font.BOLD)); 262 263 bdown.add(labFormat); 264 265 Box bacross = Box.createHorizontalBox(); 266 final JComboBox formatSelect = new JComboBox(PrintArtemis.getImageFormats()); 267 formatSelect.setSelectedItem("png"); 268 formatSelect.addActionListener(new ActionListener() 269 { 270 public void actionPerformed(ActionEvent arg0) 271 { 272 String selected; 273 if(fc.getSelectedFile() != null) 274 { 275 selected = fc.getSelectedFile().getAbsolutePath(); 276 String fmts[] = PrintArtemis.getImageFormats(); 277 for(int i=0; i<fmts.length; i++) 278 selected = selected.replaceAll("."+fmts[i]+"$", ""); 279 } 280 else 281 selected = "dnaplotter"; 282 283 fc.setSelectedFile(new File(selected+"."+ 284 formatSelect.getSelectedItem())); 285 } 286 }); 287 288 Dimension d = formatSelect.getPreferredSize(); 289 formatSelect.setMaximumSize(d); 290 bacross.add(Box.createHorizontalGlue()); 291 bacross.add(formatSelect); 292 bdown.add(bacross); 293 294 // file prefix & format options 295 fc.setAccessory(bdown); 296 int n = fc.showSaveDialog(null); 297 if(n == JFileChooser.CANCEL_OPTION) 298 return null; 299 300 type = (String)formatSelect.getSelectedItem(); 301 return fc.getSelectedFile(); 302 } 303 304 305 /** 306 * 307 * Write out the image 308 * @param image image 309 * @param file file to write image to 310 * @param type type of image 311 * 312 */ writeImageToFile(RenderedImage image, File file, String type)313 private void writeImageToFile(RenderedImage image, 314 File file, String type) 315 { 316 try 317 { 318 javax.imageio.ImageIO.write(image,type,file); 319 } 320 catch (IOException e) 321 { 322 System.out.println("Java 1.8+ is required"); 323 } 324 } 325 326 /** 327 * Print to one jpeg or png file 328 */ printAsSinglePage()329 public void printAsSinglePage() 330 { 331 //PrinterJob printerJob = PrinterJob.getPrinterJob(); 332 format = new PageFormat(); 333 334 File file = showOptions(); 335 if(file == null) 336 return; 337 338 Dimension d = dna.getSize(); 339 double imageWidth = d.getWidth(); 340 double imageHeight = d.getHeight(); 341 342 if(type.equals("svg")) 343 { 344 createSVG(file, d); 345 return; 346 } 347 348 Paper paper = format.getPaper(); 349 paper.setSize(imageWidth,imageHeight); 350 paper.setImageableArea(0,0, 351 imageWidth,imageHeight+imageHeight); 352 format.setPaper(paper); 353 354 try 355 { 356 RenderedImage rendImage = createDNAImage(0); 357 writeImageToFile(rendImage,file,type); 358 } 359 catch(NoClassDefFoundError ex) 360 { 361 JOptionPane.showMessageDialog(this, 362 "This option requires Java 1.8 or higher."); 363 } 364 } 365 createSVG(final File fout, Dimension d)366 private void createSVG(final File fout, Dimension d) 367 { 368 final DOMImplementation domImpl = 369 GenericDOMImplementation.getDOMImplementation(); 370 final Document doc = domImpl.createDocument( 371 "http://www.w3.org/2000/svg", "svg", null); 372 373 SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(doc); 374 ctx.setComment("Generated by DNAPlotter with Batik SVG Generator"); 375 final SVGGraphics2D svgG = new SVGGraphics2D(ctx, true); 376 svgG.setFont(Options.getOptions().getFont()); 377 svgG.setSVGCanvasSize(d); 378 paintComponent(svgG); 379 380 try 381 { 382 final Writer out = new OutputStreamWriter( 383 new FileOutputStream(fout), "UTF-8"); 384 svgG.stream(out, true); 385 } 386 catch (UnsupportedEncodingException e) 387 { 388 e.printStackTrace(); 389 } 390 catch (SVGGraphics2DIOException e) 391 { 392 e.printStackTrace(); 393 } 394 catch (FileNotFoundException e) 395 { 396 e.printStackTrace(); 397 } 398 399 return; 400 } 401 402 } 403 404 405