001: /*
002: * PrintPreviewer.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.executequery.print;
023:
024: import java.awt.BorderLayout;
025: import java.awt.Color;
026: import java.awt.Component;
027: import java.awt.Dimension;
028: import java.awt.Graphics;
029: import java.awt.GridBagConstraints;
030: import java.awt.GridBagLayout;
031: import java.awt.Image;
032: import java.awt.Insets;
033: import java.awt.event.ActionEvent;
034: import java.awt.event.ActionListener;
035: import java.awt.image.BufferedImage;
036: import java.awt.print.PageFormat;
037: import java.awt.print.Printable;
038:
039: import javax.swing.JComboBox;
040: import javax.swing.JDialog;
041: import javax.swing.JPanel;
042: import javax.swing.JScrollPane;
043: import javax.swing.SwingUtilities;
044: import javax.swing.border.MatteBorder;
045:
046: import org.executequery.GUIUtilities;
047: import org.executequery.SystemUtilities;
048: import org.executequery.ActiveComponent;
049: import org.underworldlabs.swing.RolloverButton;
050: import org.underworldlabs.swing.layouts.XYConstraints;
051: import org.underworldlabs.swing.layouts.XYLayout;
052:
053: /* ----------------------------------------------------------
054: * CVS NOTE: Changes to the CVS repository prior to the
055: * release of version 3.0.0beta1 has meant a
056: * resetting of CVS revision numbers.
057: * ----------------------------------------------------------
058: */
059:
060: /** <p>Print preview panel.
061: *
062: * @author Takis Diakoumis
063: * @version $Revision: 1.3 $
064: * @date $Date: 2006/05/14 06:56:52 $
065: */
066: public class PrintPreviewer extends JDialog implements ActionListener,
067: ActiveComponent {
068:
069: /** The title of this panel */
070: public static final String TITLE = "Print Preview";
071: /** The icon for this panel */
072: public static final String FRAME_ICON = "PrintPreview16.gif";
073:
074: /** The scale combo box */
075: private JComboBox scaleCombo;
076:
077: /** The page width */
078: private int m_wPage;
079:
080: /** The page height */
081: private int m_hPage;
082:
083: /** The page format for this preview */
084: private PageFormat format;
085:
086: /** The <code>Printable</code> object */
087: private Printable printable;
088:
089: /** The preview container */
090: private PreviewContainer previewContainer;
091:
092: /** The print function object */
093: private PrintFunction printFunction;
094:
095: /** <p>Constructs a new instance with the specified
096: * <code>Printable</code> object.
097: *
098: * @param the <code>Printable</code> object
099: */
100: public PrintPreviewer(PrintFunction printFunction) {
101: super (GUIUtilities.getParentFrame(), TITLE, true);
102:
103: this .printFunction = printFunction;
104: printable = printFunction.getPrintable();
105:
106: try {
107: jbInit();
108: } catch (Exception e) {
109: e.printStackTrace();
110: }
111:
112: }
113:
114: /** <p>Initializes the state of this instance. */
115: private void jbInit() throws Exception {
116: format = SystemUtilities.getPageFormat();
117:
118: if (format.getHeight() == 0 || format.getWidth() == 0) {
119: System.err.println("Unable to determine default page size");
120: return;
121: }
122:
123: JPanel base = new JPanel(new GridBagLayout());
124: base.setPreferredSize(new Dimension(380, 500));
125: previewContainer = new PreviewContainer();
126:
127: /*
128: SwingUtilities.invokeLater(new Runnable() {
129: public void run() {
130: generatePreviewImage();
131: }
132: });
133: */
134: JScrollPane scroller = new JScrollPane(previewContainer);
135:
136: RolloverButton printButton = new RolloverButton("Print", null,
137: 28, 55);
138: RolloverButton setupButton = new RolloverButton("Page Setup",
139: null, 28, 85);
140: RolloverButton closeButton = new RolloverButton("Close", null,
141: 28, 55);
142:
143: printButton.setMnemonic('P');
144: setupButton.setMnemonic('S');
145: closeButton.setMnemonic('C');
146:
147: String[] scales = { "10 %", "25 %", "50 %", "75 %", "100 %" };
148: scaleCombo = new JComboBox(scales);
149: scaleCombo.setActionCommand("scales");
150: scaleCombo.setPreferredSize(new Dimension(70, 28));
151: scaleCombo.setSelectedIndex(2);
152:
153: closeButton.addActionListener(this );
154: setupButton.addActionListener(this );
155: printButton.addActionListener(this );
156: scaleCombo.addActionListener(this );
157:
158: JPanel buttonPanel = new JPanel(new XYLayout());
159: XYConstraints xyc = new XYConstraints(0, 0, -1, -1);
160: buttonPanel.add(printButton, xyc);
161: xyc.setConstraints(60, 0, -1, -1);
162: buttonPanel.add(scaleCombo, xyc);
163: xyc.setConstraints(135, 0, -1, -1);
164: buttonPanel.add(setupButton, xyc);
165: xyc.setConstraints(225, 0, -1, -1);
166: buttonPanel.add(closeButton, xyc);
167:
168: GridBagConstraints gbc = new GridBagConstraints();
169: gbc.insets = new Insets(7, 7, 0, 7);
170: gbc.anchor = GridBagConstraints.NORTHWEST;
171: gbc.fill = GridBagConstraints.HORIZONTAL;
172: base.add(buttonPanel, gbc);
173: gbc.insets.bottom = 7;
174: gbc.gridx = 0;
175: gbc.gridy = 1;
176: gbc.fill = GridBagConstraints.BOTH;
177: gbc.weightx = 1.0;
178: gbc.weighty = 1.0;
179: gbc.gridwidth = GridBagConstraints.REMAINDER;
180: base.add(scroller, gbc);
181:
182: SwingUtilities.invokeLater(new Runnable() {
183: public void run() {
184: generatePreviewImage();
185: }
186: });
187:
188: getContentPane().setLayout(new BorderLayout());
189: getContentPane().add(base, BorderLayout.CENTER);
190:
191: display();
192: }
193:
194: /**
195: * Packs, positions and displays the dialog.
196: */
197: private void display() {
198: pack();
199: setLocation(GUIUtilities.getLocationForDialog(getSize()));
200: setVisible(true);
201: }
202:
203: public void dispose() {
204: cleanup();
205: GUIUtilities.scheduleGC();
206: super .dispose();
207: }
208:
209: /** <p>How to dispose of this panel. */
210: public void cleanup() {
211: format = null;
212: printable = null;
213: previewContainer = null;
214: printFunction = null;
215: }
216:
217: /** <p>Performs the button actions.
218: *
219: * @param the event object
220: */
221: public void actionPerformed(ActionEvent e) {
222: final String command = e.getActionCommand();
223:
224: SwingUtilities.invokeLater(new Runnable() {
225:
226: public void run() {
227: if (command.equals("Close")) {
228: dispose();
229: } else if (command.equals("Page Setup")) {
230: showPageSetup();
231: } else if (command.equals("Print")) {
232: doPrint();
233: } else if (command.equals("scales")) {
234: changeScale();
235: }
236: }
237:
238: });
239:
240: }
241:
242: private void changeScale() {
243: Thread runner = new Thread() {
244: public void run() {
245: String str = scaleCombo.getSelectedItem().toString();
246:
247: if (str.endsWith("%"))
248: str = str.substring(0, str.length() - 1);
249:
250: str = str.trim();
251: int scale = 0;
252:
253: try {
254: scale = Integer.parseInt(str);
255: } catch (NumberFormatException ex) {
256: }
257:
258: int w = (int) (m_wPage * scale / 100);
259: int h = (int) (m_hPage * scale / 100);
260:
261: Component[] comps = previewContainer.getComponents();
262: for (int k = 0; k < comps.length; k++) {
263:
264: if (!(comps[k] instanceof PagePreview))
265: continue;
266:
267: PagePreview pp = (PagePreview) comps[k];
268: pp.setScaledSize(w, h);
269: }
270:
271: previewContainer.doLayout();
272: previewContainer.repaint();
273: previewContainer.getParent().getParent().validate();
274: }
275: };
276:
277: runner.start();
278: }
279:
280: private void doPrint() {
281: PrintUtilities
282: .print(printable, printFunction.getPrintJobName());
283: }
284:
285: private void showPageSetup() {
286:
287: PageFormat newFormat = PrintUtilities.pageSetup();
288:
289: if (newFormat == null)
290: return;
291:
292: format = newFormat;
293:
294: SwingUtilities.invokeLater(new Runnable() {
295:
296: public void run() {
297:
298: if (printable instanceof TablePrinter) {
299: ((TablePrinter) printable).reset();
300: }
301:
302: previewContainer.invalidate();
303: previewContainer.removeAll();
304: generatePreviewImage();
305: previewContainer.revalidate();
306: repaint();
307: GUIUtilities.scheduleGC();
308: }
309:
310: });
311:
312: }
313:
314: private void generatePreviewImage() {
315:
316: int orientation = format.getOrientation();
317:
318: m_wPage = (int) (format.getWidth());
319: m_hPage = (int) (format.getHeight());
320:
321: int scale = 50;
322: int w = (int) (m_wPage * scale / 100);
323: int h = (int) (m_hPage * scale / 100);
324:
325: int pageIndex = 0;
326:
327: try {
328:
329: while (true) {
330: BufferedImage img = new BufferedImage(m_wPage, m_hPage,
331: BufferedImage.TYPE_INT_RGB);
332: Graphics g = img.getGraphics();
333: g.setColor(Color.white);
334: g.fillRect(0, 0, m_wPage, m_hPage);
335:
336: if (printable.print(g, format, pageIndex) != Printable.PAGE_EXISTS) {
337: break;
338: }
339:
340: PagePreview pp = new PagePreview(w, h, img);
341: previewContainer.add(pp);
342: pageIndex++;
343: }
344:
345: } catch (Exception e) {
346: e.printStackTrace();
347: System.err.println("Printing error: " + e.toString());
348: }
349: }
350:
351: class PreviewContainer extends JPanel {
352:
353: protected int H_GAP = 5;
354: protected int V_GAP = 5;
355:
356: public Dimension getPreferredSize() {
357: int n = getComponentCount();
358:
359: if (n == 0)
360: return new Dimension(H_GAP, V_GAP);
361:
362: Component comp = getComponent(0);
363: Dimension dc = comp.getPreferredSize();
364: int w = dc.width;
365: int h = dc.height;
366:
367: Dimension dp = getParent().getSize();
368: int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1);
369: int nRow = n / nCol;
370:
371: if (nRow * nCol < n)
372: nRow++;
373:
374: int ww = nCol * (w + H_GAP) + H_GAP;
375: int hh = nRow * (h + V_GAP) + V_GAP;
376: Insets ins = getInsets();
377:
378: return new Dimension(ww + ins.left + ins.right, hh
379: + ins.top + ins.bottom);
380: }
381:
382: public Dimension getMaximumSize() {
383: return getPreferredSize();
384: }
385:
386: public Dimension getMinimumSize() {
387: return getPreferredSize();
388: }
389:
390: public void doLayout() {
391: Insets ins = getInsets();
392: int x = ins.left + H_GAP;
393: int y = ins.top + V_GAP;
394:
395: int n = getComponentCount();
396:
397: if (n == 0)
398: return;
399:
400: Component comp = getComponent(0);
401: Dimension dc = comp.getPreferredSize();
402: int w = dc.width;
403: int h = dc.height;
404:
405: Dimension dp = getParent().getSize();
406: int nCol = Math.max((dp.width - H_GAP) / (w + H_GAP), 1);
407: int nRow = n / nCol;
408:
409: if (nRow * nCol < n)
410: nRow++;
411:
412: int index = 0;
413:
414: for (int k = 0; k < nRow; k++) {
415:
416: for (int m = 0; m < nCol; m++) {
417:
418: if (index >= n)
419: return;
420:
421: comp = getComponent(index++);
422: comp.setBounds(x, y, w, h);
423: x += w + H_GAP;
424:
425: }
426:
427: y += h + V_GAP;
428: x = ins.left + H_GAP;
429:
430: }
431:
432: }
433:
434: } // class PreviewContainer
435:
436: class PagePreview extends JPanel {
437:
438: protected int m_w;
439: protected int m_h;
440: protected Image m_source;
441: protected Image m_img;
442:
443: public PagePreview(int w, int h, Image source) {
444: m_w = w;
445: m_h = h;
446: m_source = source;
447: m_img = m_source.getScaledInstance(m_w, m_h,
448: Image.SCALE_SMOOTH);
449: m_img.flush();
450: setBackground(Color.white);
451: setBorder(new MatteBorder(1, 1, 2, 2, Color.black));
452: }
453:
454: public void setScaledSize(int w, int h) {
455: m_w = w;
456: m_h = h;
457: m_img = m_source.getScaledInstance(m_w, m_h,
458: Image.SCALE_SMOOTH);
459: repaint();
460: }
461:
462: public Dimension getPreferredSize() {
463: Insets ins = getInsets();
464: return new Dimension(m_w + ins.left + ins.right, m_h
465: + ins.top + ins.bottom);
466: }
467:
468: public Dimension getMaximumSize() {
469: return getPreferredSize();
470: }
471:
472: public Dimension getMinimumSize() {
473: return getPreferredSize();
474: }
475:
476: public void paint(Graphics g) {
477: g.setColor(getBackground());
478: g.fillRect(0, 0, getWidth(), getHeight());
479: g.drawImage(m_img, 0, 0, this );
480: paintBorder(g);
481: }
482:
483: } // class PagePreview
484:
485: }
|