/*** * Copyright (c) 2008, Endless Loop Software, Inc. * * This file is part of EgoNet. * * EgoNet is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * EgoNet 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.egonet.util; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; 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.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.border.MatteBorder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PrintPreview extends JFrame { final private static Logger logger = LoggerFactory.getLogger(PrintPreview.class); protected int m_wPage; protected int m_hPage; protected int m_orientation; protected Printable m_target; protected JComboBox<String> m_cbScale; protected PreviewContainer m_preview; public PrintPreview(Printable target, PageFormat pFormat) { this(target, pFormat, "Print Preview", PageFormat.PORTRAIT); } public PrintPreview(Printable target, PageFormat pFormat, String title, int orientation) { super(title); setSize(600, 400); getContentPane().setLayout(new BorderLayout()); final PageFormat pageFormat = pFormat; m_target = target; m_orientation = orientation; JToolBar tb = new JToolBar(); JButton bt = new JButton("Print", new ImageIcon(PrintPreview.class.getResource("print.gif"))); ActionListener lst = new ActionListener() { public void actionPerformed(ActionEvent e) { final PrinterJob prnJob = PrinterJob.getPrinterJob(); PageFormat pf = pageFormat; pf.setOrientation(m_orientation); prnJob.setPrintable(m_target, pf); if (!prnJob.printDialog()) return; Thread runner = new Thread() { public void run() { try { prnJob.print(); } catch (PrinterException ex) { System.err.println("Printing error: " + ex.toString()); throw new RuntimeException(ex); } } }; runner.start(); dispose(); } }; bt.addActionListener(lst); bt.setAlignmentY(0.5f); bt.setMargin(new Insets(4, 6, 4, 6)); tb.add(bt); bt = new JButton("Close"); lst = new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }; bt.addActionListener(lst); bt.setAlignmentY(0.5f); bt.setMargin(new Insets(2, 6, 2, 6)); tb.add(bt); String[] scales = { "10 %", "25 %", "50 %", "100 %" }; m_cbScale = new JComboBox<String>(scales); lst = new ActionListener() { public void actionPerformed(ActionEvent e) { Thread runner = new Thread() { public void run() { String str = m_cbScale.getSelectedItem().toString(); if (str.endsWith("%")) str = str.substring(0, str.length() - 1); str = str.trim(); int scale = 0; try { scale = Integer.parseInt(str); } catch (NumberFormatException ex) { return; } int w = (int) (m_wPage * scale / 100); int h = (int) (m_hPage * scale / 100); Component[] comps = m_preview.getComponents(); for (int k = 0; k < comps.length; k++) { if (!(comps[k] instanceof PagePreview)) continue; PagePreview pp = (PagePreview) comps[k]; pp.setScaledSize(w, h); } m_preview.doLayout(); m_preview.getParent().getParent().validate(); } }; runner.start(); } }; m_cbScale.addActionListener(lst); m_cbScale.setMaximumSize(m_cbScale.getPreferredSize()); m_cbScale.setEditable(true); tb.addSeparator(); tb.add(m_cbScale); getContentPane().add(tb, BorderLayout.NORTH); m_preview = new PreviewContainer(); pageFormat.setOrientation(m_orientation); if (pageFormat.getHeight() == 0 || pageFormat.getWidth() == 0) { System.err.println("Unable to determine default page size"); return; } m_wPage = (int) (pageFormat.getWidth()); m_hPage = (int) (pageFormat.getHeight()); int scale = 10; int w = (int) (m_wPage * scale / 100); int h = (int) (m_hPage * scale / 100); int pageIndex = 0; try { while (true) { BufferedImage img = new BufferedImage(m_wPage, m_hPage, BufferedImage.TYPE_BYTE_GRAY); Graphics g = img.getGraphics(); g.setColor(Color.white); g.fillRect(0, 0, m_wPage, m_hPage); if (target.print(g, pageFormat, pageIndex) != Printable.PAGE_EXISTS) break; PagePreview pp = new PagePreview(w, h, img); m_preview.add(pp); pageIndex++; } } catch (PrinterException ex) { logger.error(ex.toString()); System.err.println("Printing error: " + ex.toString()); } JScrollPane ps = new JScrollPane(m_preview); getContentPane().add(ps, BorderLayout.CENTER); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setVisible(true); } class PreviewContainer extends JPanel { protected int H_GAP = 16; protected int V_GAP = 10; public Dimension getPreferredSize() { int n = getComponentCount(); if (n == 0) return new Dimension(H_GAP, V_GAP); Component comp = getComponent(0); Dimension dc = comp.getPreferredSize(); int w = dc.width; int h = dc.height; Dimension dp = getParent().getSize(); int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1); int nRow = n / nCol; if (nRow * nCol < n) nRow++; int ww = nCol * (w + H_GAP) + H_GAP; int hh = nRow * (h + V_GAP) + V_GAP; Insets ins = getInsets(); return new Dimension(ww + ins.left + ins.right, hh + ins.top + ins.bottom); } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getMinimumSize() { return getPreferredSize(); } public void doLayout() { Insets ins = getInsets(); int x = ins.left + H_GAP; int y = ins.top + V_GAP; int n = getComponentCount(); if (n == 0) return; Component comp = getComponent(0); Dimension dc = comp.getPreferredSize(); int w = dc.width; int h = dc.height; Dimension dp = getParent().getSize(); int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1); int nRow = n / nCol; if (nRow * nCol < n) nRow++; int index = 0; for (int k = 0; k < nRow; k++) { for (int m = 0; m < nCol; m++) { if (index >= n) return; comp = getComponent(index++); comp.setBounds(x, y, w, h); x += w + H_GAP; } y += h + V_GAP; x = ins.left + H_GAP; } } } class PagePreview extends JPanel { protected int m_w; protected int m_h; protected Image m_source; protected Image m_img; public PagePreview(int w, int h, Image source) { m_w = w; m_h = h; m_source = source; m_img = m_source.getScaledInstance(m_w, m_h, Image.SCALE_SMOOTH); m_img.flush(); setBackground(Color.white); setBorder(new MatteBorder(1, 1, 2, 2, Color.black)); } public void setScaledSize(int w, int h) { m_w = w; m_h = h; m_img = m_source.getScaledInstance(m_w, m_h, Image.SCALE_SMOOTH); repaint(); } public Dimension getPreferredSize() { Insets ins = getInsets(); return new Dimension(m_w + ins.left + ins.right, m_h + ins.top + ins.bottom); } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getMinimumSize() { return getPreferredSize(); } public void paint(Graphics g) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); g.drawImage(m_img, 0, 0, this); paintBorder(g); } } }