001 /* 002 * Copyright (C) 2008-2010 by Holger Arndt 003 * 004 * This file is part of the Universal Java Matrix Package (UJMP). 005 * See the NOTICE file distributed with this work for additional 006 * information regarding copyright ownership and licensing. 007 * 008 * UJMP is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation; either version 2 011 * of the License, or (at your option) any later version. 012 * 013 * UJMP is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public 019 * License along with UJMP; if not, write to the 020 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 021 * Boston, MA 02110-1301 USA 022 */ 023 024 package org.ujmp.gui.print; 025 026 import java.awt.BorderLayout; 027 import java.awt.Color; 028 import java.awt.Component; 029 import java.awt.Dimension; 030 import java.awt.Graphics; 031 import java.awt.Graphics2D; 032 import java.awt.GridBagConstraints; 033 import java.awt.GridBagLayout; 034 import java.awt.Image; 035 import java.awt.Insets; 036 import java.awt.event.ActionEvent; 037 import java.awt.event.ActionListener; 038 import java.awt.image.BufferedImage; 039 import java.awt.print.Book; 040 import java.awt.print.PageFormat; 041 import java.awt.print.Paper; 042 import java.awt.print.Printable; 043 import java.awt.print.PrinterException; 044 import java.awt.print.PrinterJob; 045 046 import javax.swing.BorderFactory; 047 import javax.swing.ButtonGroup; 048 import javax.swing.JButton; 049 import javax.swing.JLabel; 050 import javax.swing.JPanel; 051 import javax.swing.JRadioButton; 052 import javax.swing.JSpinner; 053 import javax.swing.RepaintManager; 054 import javax.swing.SpinnerNumberModel; 055 import javax.swing.event.ChangeEvent; 056 import javax.swing.event.ChangeListener; 057 058 /* 059 * taken from here: 060 * http://forum.java.sun.com/thread.jspa?threadID=601884&messageID=4215335 061 */ 062 063 public class PrintPreviewPanel extends JPanel implements ActionListener, ChangeListener { 064 private static final long serialVersionUID = -3281742799998775189L; 065 066 static final double INITIAL_SCALE_FACTOR = 1.0; 067 068 Component targetComponent; 069 070 PageFormat pageFormat = new PageFormat(); 071 072 double xScaleFactor = INITIAL_SCALE_FACTOR; 073 074 double yScaleFactor = INITIAL_SCALE_FACTOR; 075 076 BufferedImage bufferedImage; 077 078 JPanel settingsPanel = new JPanel(); 079 080 PreviewPanel previewPanel; 081 082 ButtonGroup orientationButtonGroup = new ButtonGroup(); 083 084 JRadioButton portraitButton; 085 086 JRadioButton landscapeButton; 087 088 JLabel xScaleLabel = new JLabel("X-Scale:", JLabel.LEFT); 089 090 JLabel yScaleLabel = new JLabel("Y-Scale:", JLabel.LEFT); 091 092 JButton print = new JButton("Print"); 093 094 JSpinner xsp, ysp; 095 096 SpinnerNumberModel snmx, snmy; 097 098 int pcw, pch; 099 100 double wh, hw; 101 102 public PrintPreviewPanel(Component pc) { 103 targetComponent = pc; 104 105 setLayout(new BorderLayout()); 106 107 if (targetComponent.getWidth() < 1) 108 targetComponent.setSize(600, targetComponent.getHeight()); 109 if (targetComponent.getHeight() < 1) 110 targetComponent.setSize(targetComponent.getWidth(), 400); 111 112 bufferedImage = new BufferedImage(pcw = targetComponent.getWidth(), pch = targetComponent.getHeight(), 113 BufferedImage.TYPE_INT_ARGB); 114 Graphics g = bufferedImage.createGraphics(); 115 targetComponent.paint(g); 116 g.dispose(); 117 wh = (double) pcw / (double) pch; 118 hw = (double) pch / (double) pcw; 119 120 pageFormat.setPaper(new PaperA4()); 121 pageFormat.setOrientation(PageFormat.PORTRAIT); 122 previewPanel = new PreviewPanel(); 123 124 snmx = new SpinnerNumberModel(1.0, 0.1, 10.0, 0.1); 125 snmy = new SpinnerNumberModel(1.0, 0.1, 10.0, 0.1); 126 xsp = new JSpinner(snmx); 127 ysp = new JSpinner(snmy); 128 129 xsp.addChangeListener(this); 130 ysp.addChangeListener(this); 131 132 portraitButton = new JRadioButton("Portrait"); 133 portraitButton.setActionCommand("1"); 134 portraitButton.setSelected(true); 135 portraitButton.addActionListener(this); 136 137 landscapeButton = new JRadioButton("Landscape"); 138 landscapeButton.setActionCommand("2"); 139 landscapeButton.addActionListener(this); 140 141 orientationButtonGroup.add(portraitButton); 142 orientationButtonGroup.add(landscapeButton); 143 144 print.addActionListener(this); 145 146 previewPanel.setBackground(Color.white); 147 settingsPanel.setBorder(BorderFactory.createTitledBorder("Settings")); 148 settingsPanel.setLayout(new GridBagLayout()); 149 150 GridBagConstraints c1 = new GridBagConstraints(); 151 152 c1.insets = new Insets(15, 45, 0, 5); 153 c1 = buildConstraints(c1, 0, 0, 2, 1, 0.0, 0.0); 154 settingsPanel.add(portraitButton, c1); 155 156 c1.insets = new Insets(2, 45, 0, 5); 157 c1 = buildConstraints(c1, 0, 1, 2, 1, 0.0, 0.0); 158 settingsPanel.add(landscapeButton, c1); 159 160 c1.insets = new Insets(25, 5, 0, 5); 161 c1 = buildConstraints(c1, 0, 2, 1, 1, 0.0, 0.0); 162 settingsPanel.add(xScaleLabel, c1); 163 164 c1.insets = new Insets(25, 5, 0, 35); 165 c1 = buildConstraints(c1, 1, 2, 1, 1, 0.0, 0.0); 166 settingsPanel.add(xsp, c1); 167 168 c1.insets = new Insets(5, 5, 0, 5); 169 c1 = buildConstraints(c1, 0, 3, 1, 1, 0.0, 0.0); 170 settingsPanel.add(yScaleLabel, c1); 171 172 c1.insets = new Insets(15, 5, 0, 35); 173 c1 = buildConstraints(c1, 1, 3, 1, 1, 0.0, 0.0); 174 settingsPanel.add(ysp, c1); 175 176 c1.insets = new Insets(5, 35, 25, 35); 177 c1 = buildConstraints(c1, 0, 7, 2, 1, 0.0, 0.0); 178 settingsPanel.add(print, c1); 179 180 add(settingsPanel, BorderLayout.WEST); 181 add(previewPanel, BorderLayout.CENTER); 182 } 183 184 GridBagConstraints buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, double wx, double wy) { 185 gbc.gridx = gx; 186 gbc.gridy = gy; 187 gbc.gridwidth = gw; 188 gbc.gridheight = gh; 189 gbc.weightx = wx; 190 gbc.weighty = wy; 191 gbc.fill = GridBagConstraints.BOTH; 192 return gbc; 193 } 194 195 public class PreviewPanel extends JPanel { 196 private static final long serialVersionUID = -868466190084572319L; 197 198 public PreviewPanel() { 199 setPreferredSize(new Dimension(640, 640)); 200 } 201 202 203 public void paintComponent(Graphics g) { 204 super.paintComponent(g); 205 206 Graphics2D g2d = (Graphics2D) g; 207 208 int xOffsetPaper = (int) pageFormat.getImageableX(); 209 int yOffsetPaper = (int) pageFormat.getImageableY(); 210 int widthImage = (int) pageFormat.getImageableWidth(); 211 int heightImage = (int) pageFormat.getImageableHeight(); 212 213 int widthScaledImage = (int) Math.rint(widthImage * xScaleFactor); 214 int heightScaledImage = (int) Math.rint((widthImage * hw) * yScaleFactor); 215 216 g2d.setColor(Color.black); 217 g2d.drawRect(0, 0, widthImage + 2 * xOffsetPaper, heightImage + 2 * yOffsetPaper); 218 g2d.setColor(Color.lightGray); 219 g2d.drawRect(xOffsetPaper, yOffsetPaper, widthImage, heightImage); 220 Image image = bufferedImage.getScaledInstance(widthScaledImage, heightScaledImage, Image.SCALE_DEFAULT); 221 g2d.drawImage(image, xOffsetPaper, yOffsetPaper, this); 222 } 223 } 224 225 public void actionPerformed(ActionEvent e) { 226 if (e.getSource() == portraitButton) { 227 updatePreview(); 228 } else if (e.getSource() == landscapeButton) { 229 updatePreview(); 230 } else if (e.getSource() == print) { 231 print(); 232 } 233 } 234 235 public void updatePreview() { 236 if (portraitButton.isSelected()) { 237 pageFormat.setOrientation(PageFormat.PORTRAIT); 238 } else if (landscapeButton.isSelected()) { 239 pageFormat.setOrientation(PageFormat.LANDSCAPE); 240 } 241 setScales(); 242 previewPanel.repaint(); 243 } 244 245 public void setScales() { 246 try { 247 xScaleFactor = ((Double) xsp.getValue()).doubleValue(); 248 yScaleFactor = ((Double) ysp.getValue()).doubleValue(); 249 } catch (NumberFormatException e) { 250 } 251 } 252 253 public void print() { 254 PrinterJob printerJob = PrinterJob.getPrinterJob(); 255 Book book = new Book(); 256 book.append(new PrintPage(), pageFormat); 257 printerJob.setPageable(book); 258 boolean doPrint = printerJob.printDialog(); 259 if (doPrint) { 260 try { 261 printerJob.print(); 262 } catch (PrinterException exception) { 263 System.err.println("Printing error: " + exception); 264 } 265 } 266 } 267 268 class PrintPage implements Printable { 269 270 public int print(Graphics g, PageFormat format, int pageIndex) { 271 Graphics2D g2d = (Graphics2D) g; 272 g2d.translate(format.getImageableX(), format.getImageableY()); 273 274 double dw = format.getImageableWidth(); 275 double dh = format.getImageableHeight(); 276 setScales(); 277 double xScale = dw / (targetComponent.getWidth() * xScaleFactor); 278 // double yScale = dh / (targetComponent.getHeight() * 279 // yScaleFactor); 280 281 g2d.scale(xScale, xScale); 282 targetComponent.paint(g2d); 283 return Printable.PAGE_EXISTS; 284 } 285 286 public void disableDoubleBuffering(Component c) { 287 RepaintManager currentManager = RepaintManager.currentManager(c); 288 currentManager.setDoubleBufferingEnabled(false); 289 } 290 291 public void enableDoubleBuffering(Component c) { 292 RepaintManager currentManager = RepaintManager.currentManager(c); 293 currentManager.setDoubleBufferingEnabled(true); 294 } 295 } 296 297 public void stateChanged(ChangeEvent e) { 298 updatePreview(); 299 } 300 } 301 302 class PaperA4 extends Paper { 303 304 private static final int CM = 28; 305 306 private static final double A4_WIDTH = 21.0 * CM; 307 308 private static final double A4_HEIGHT = 29.7 * CM; 309 310 public PaperA4() { 311 setSize(A4_WIDTH, A4_HEIGHT); 312 setImageableArea(2 * CM, 2 * CM, A4_WIDTH - 4 * CM, A4_HEIGHT - 4 * CM); 313 } 314 315 }