/* * Copyright (c) 2000 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 2nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book (recommended), * visit http://www.davidflanagan.com/javaexamples2. */ package com.davidflanagan.examples.print; import java.awt.*; import java.awt.event.*; import java.awt.print.*; import java.awt.geom.*; import javax.swing.*; import java.util.*; /** * A "scribble" application that remembers the scribble and allows the user * to print it. It displays a Swing API and uses the Java 1.2 printing API. * It also uses Java2D features to draw and represent the scribble. **/ public class ScribblePrinter2 extends JComponent implements Printable { Stroke linestyle = new BasicStroke(3.0f); // Draw with wide lines GeneralPath scribble = new GeneralPath(); // Holds the scribble public ScribblePrinter2() { // Register event types we're interested in for scribbling enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); // Add a print button to he layout, and respond to it by printing JButton b = new JButton("Print"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { printScribble(); } }); this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); this.add(b); } /** Redraw (or print) the scribble based on stored lines */ public void paintComponent(Graphics g) { super.paintComponent(g); // Allow the superclass to draw itself Graphics2D g2 = (Graphics2D) g; g2.setStroke(linestyle); // Specify wide lines g2.draw(scribble); // Draw the scribble } /** * Print out the scribble. This is the method invoked by the Print button; * it is not part of the Printable interface **/ public void printScribble() { // Obtain a java.awt.print.PrinterJob (not java.awt.PrintJob) PrinterJob job = PrinterJob.getPrinterJob(); // Tell the PrinterJob to print us (since we implement Printable) // using the default page layout job.setPrintable(this, job.defaultPage()); // Display the print dialog that allows the user to set options. // The method returns false if the user cancelled the print request if (job.printDialog()) { // If not cancelled, start printing! This will call the print() // method defined by the Printable interface. try { job.print(); } catch (PrinterException e) { System.err.println(e); } } } /** * This is the method defined by the Printable interface. It prints the * scribble to the specified Graphics object, respecting the paper size * and margins specified by the PageFormat. If the specified page number * is not page 0, it returns a code saying that printing is complete. The * method must be prepared to be called multiple times per printing request **/ public int print(Graphics g, PageFormat format, int pagenum) { // We are only one page long; reject any other page numbers if (pagenum > 0) return Printable.NO_SUCH_PAGE; // The Java 1.2 printing API passes us a Graphics object, but we // can always cast it to a Graphics2D object Graphics2D g2 = (Graphics2D) g; // Translate to accomodate the requested top and left margins. g2.translate(format.getImageableX(), format.getImageableY()); // Figure out how big the drawing is, and how big the page // (excluding margins) is Dimension size = this.getSize(); // Scribble size double pageWidth = format.getImageableWidth(); // Page width double pageHeight = format.getImageableHeight(); // Page height // If the scribble is too wide or tall for the page, scale it down if (size.width > pageWidth) { double factor = pageWidth/size.width; // How much to scale g2.scale(factor, factor); // Adjust coordinate system pageWidth /= factor; // Adjust page size up pageHeight /= factor; } if (size.height > pageHeight) { // Do the same thing for height double factor = pageHeight/size.height; g2.scale(factor, factor); pageWidth /= factor; pageHeight /= factor; } // Now we know the scribble will fit on the page. Center it by // translating as necessary. g2.translate((pageWidth-size.width)/2,(pageHeight-size.height)/2); // Draw a line around the outside of the drawing area g2.drawRect(-1, -1, size.width+2, size.height+2); // Set a clipping region so the scribbles don't go out of bounds g2.setClip(0, 0, size.width, size.height); // Finally, print the component by calling the paintComponent() method. // Or, call paint() to paint the component, its background, border, and // children, including the Print JButton this.paintComponent(g); // Tell the PrinterJob that the page number was valid return Printable.PAGE_EXISTS; } /** Called when the user clicks to begin a scribble */ public void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_PRESSED) { scribble.moveTo(e.getX(), e.getY()); // Start a new line } else super.processMouseEvent(e); } /** Called when the the user drags the mouse: does the scribbling */ public void processMouseMotionEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_DRAGGED) { scribble.lineTo(e.getX(), e.getY()); // Add a line to the scribble repaint(); // Redraw the whole scribble. Clean but a little slow } else super.processMouseMotionEvent(e); } /** The main method. Create a ScribblePrinter2 object and away we go! */ public static void main(String[] args) { JFrame frame = new JFrame("ScribblePrinter2"); ScribblePrinter2 s = new ScribblePrinter2(); frame.getContentPane().add(s, BorderLayout.CENTER); frame.setSize(400, 400); frame.setVisible(true); } }