/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.gui.print;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.RepaintManager;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/*
* taken from here:
* http://forum.java.sun.com/thread.jspa?threadID=601884&messageID=4215335
*/
public class PrintPreviewPanel extends JPanel implements ActionListener, ChangeListener {
private static final long serialVersionUID = -3281742799998775189L;
static final double INITIAL_SCALE_FACTOR = 1.0;
Component targetComponent;
PageFormat pageFormat = new PageFormat();
double xScaleFactor = INITIAL_SCALE_FACTOR;
double yScaleFactor = INITIAL_SCALE_FACTOR;
BufferedImage bufferedImage;
JPanel settingsPanel = new JPanel();
PreviewPanel previewPanel;
ButtonGroup orientationButtonGroup = new ButtonGroup();
JRadioButton portraitButton;
JRadioButton landscapeButton;
JLabel xScaleLabel = new JLabel("X-Scale:", JLabel.LEFT);
JLabel yScaleLabel = new JLabel("Y-Scale:", JLabel.LEFT);
JButton print = new JButton("Print");
JSpinner xsp, ysp;
SpinnerNumberModel snmx, snmy;
int pcw, pch;
double wh, hw;
public PrintPreviewPanel(Component pc) {
targetComponent = pc;
setLayout(new BorderLayout());
if (targetComponent.getWidth() < 1)
targetComponent.setSize(600, targetComponent.getHeight());
if (targetComponent.getHeight() < 1)
targetComponent.setSize(targetComponent.getWidth(), 400);
bufferedImage = new BufferedImage(pcw = targetComponent.getWidth(), pch = targetComponent.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.createGraphics();
targetComponent.paint(g);
g.dispose();
wh = (double) pcw / (double) pch;
hw = (double) pch / (double) pcw;
pageFormat.setPaper(new PaperA4());
pageFormat.setOrientation(PageFormat.PORTRAIT);
previewPanel = new PreviewPanel();
snmx = new SpinnerNumberModel(1.0, 0.1, 10.0, 0.1);
snmy = new SpinnerNumberModel(1.0, 0.1, 10.0, 0.1);
xsp = new JSpinner(snmx);
ysp = new JSpinner(snmy);
xsp.addChangeListener(this);
ysp.addChangeListener(this);
portraitButton = new JRadioButton("Portrait");
portraitButton.setActionCommand("1");
portraitButton.setSelected(true);
portraitButton.addActionListener(this);
landscapeButton = new JRadioButton("Landscape");
landscapeButton.setActionCommand("2");
landscapeButton.addActionListener(this);
orientationButtonGroup.add(portraitButton);
orientationButtonGroup.add(landscapeButton);
print.addActionListener(this);
previewPanel.setBackground(Color.white);
settingsPanel.setBorder(BorderFactory.createTitledBorder("Settings"));
settingsPanel.setLayout(new GridBagLayout());
GridBagConstraints c1 = new GridBagConstraints();
c1.insets = new Insets(15, 45, 0, 5);
c1 = buildConstraints(c1, 0, 0, 2, 1, 0.0, 0.0);
settingsPanel.add(portraitButton, c1);
c1.insets = new Insets(2, 45, 0, 5);
c1 = buildConstraints(c1, 0, 1, 2, 1, 0.0, 0.0);
settingsPanel.add(landscapeButton, c1);
c1.insets = new Insets(25, 5, 0, 5);
c1 = buildConstraints(c1, 0, 2, 1, 1, 0.0, 0.0);
settingsPanel.add(xScaleLabel, c1);
c1.insets = new Insets(25, 5, 0, 35);
c1 = buildConstraints(c1, 1, 2, 1, 1, 0.0, 0.0);
settingsPanel.add(xsp, c1);
c1.insets = new Insets(5, 5, 0, 5);
c1 = buildConstraints(c1, 0, 3, 1, 1, 0.0, 0.0);
settingsPanel.add(yScaleLabel, c1);
c1.insets = new Insets(15, 5, 0, 35);
c1 = buildConstraints(c1, 1, 3, 1, 1, 0.0, 0.0);
settingsPanel.add(ysp, c1);
c1.insets = new Insets(5, 35, 25, 35);
c1 = buildConstraints(c1, 0, 7, 2, 1, 0.0, 0.0);
settingsPanel.add(print, c1);
add(settingsPanel, BorderLayout.WEST);
add(previewPanel, BorderLayout.CENTER);
}
GridBagConstraints buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, double wx, double wy) {
gbc.gridx = gx;
gbc.gridy = gy;
gbc.gridwidth = gw;
gbc.gridheight = gh;
gbc.weightx = wx;
gbc.weighty = wy;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
public class PreviewPanel extends JPanel {
private static final long serialVersionUID = -868466190084572319L;
public PreviewPanel() {
setPreferredSize(new Dimension(640, 640));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int xOffsetPaper = (int) pageFormat.getImageableX();
int yOffsetPaper = (int) pageFormat.getImageableY();
int widthImage = (int) pageFormat.getImageableWidth();
int heightImage = (int) pageFormat.getImageableHeight();
int widthScaledImage = (int) Math.rint(widthImage * xScaleFactor);
int heightScaledImage = (int) Math.rint((widthImage * hw) * yScaleFactor);
g2d.setColor(Color.black);
g2d.drawRect(0, 0, widthImage + 2 * xOffsetPaper, heightImage + 2 * yOffsetPaper);
g2d.setColor(Color.lightGray);
g2d.drawRect(xOffsetPaper, yOffsetPaper, widthImage, heightImage);
Image image = bufferedImage.getScaledInstance(widthScaledImage, heightScaledImage, Image.SCALE_DEFAULT);
g2d.drawImage(image, xOffsetPaper, yOffsetPaper, this);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == portraitButton) {
updatePreview();
} else if (e.getSource() == landscapeButton) {
updatePreview();
} else if (e.getSource() == print) {
print();
}
}
public void updatePreview() {
if (portraitButton.isSelected()) {
pageFormat.setOrientation(PageFormat.PORTRAIT);
} else if (landscapeButton.isSelected()) {
pageFormat.setOrientation(PageFormat.LANDSCAPE);
}
setScales();
previewPanel.repaint();
}
public void setScales() {
try {
xScaleFactor = ((Double) xsp.getValue()).doubleValue();
yScaleFactor = ((Double) ysp.getValue()).doubleValue();
} catch (NumberFormatException e) {
}
}
public void print() {
PrinterJob printerJob = PrinterJob.getPrinterJob();
Book book = new Book();
book.append(new PrintPage(), pageFormat);
printerJob.setPageable(book);
boolean doPrint = printerJob.printDialog();
if (doPrint) {
try {
printerJob.print();
} catch (PrinterException exception) {
System.err.println("Printing error: " + exception);
}
}
}
class PrintPage implements Printable {
public int print(Graphics g, PageFormat format, int pageIndex) {
Graphics2D g2d = (Graphics2D) g;
g2d.translate(format.getImageableX(), format.getImageableY());
double dw = format.getImageableWidth();
double dh = format.getImageableHeight();
setScales();
double xScale = dw / (targetComponent.getWidth() * xScaleFactor);
// double yScale = dh / (targetComponent.getHeight() *
// yScaleFactor);
g2d.scale(xScale, xScale);
targetComponent.paint(g2d);
return Printable.PAGE_EXISTS;
}
public void disableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(false);
}
public void enableDoubleBuffering(Component c) {
RepaintManager currentManager = RepaintManager.currentManager(c);
currentManager.setDoubleBufferingEnabled(true);
}
}
public void stateChanged(ChangeEvent e) {
updatePreview();
}
}
class PaperA4 extends Paper {
private static final int CM = 28;
private static final double A4_WIDTH = 21.0 * CM;
private static final double A4_HEIGHT = 29.7 * CM;
public PaperA4() {
setSize(A4_WIDTH, A4_HEIGHT);
setImageableArea(2 * CM, 2 * CM, A4_WIDTH - 4 * CM, A4_HEIGHT - 4 * CM);
}
}