Printing in Java 2

   *
          o PrintExample.java Demonstrates printing a Graphics2D object.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.print.*;

/** An example of a printable window in Java 1.2. The key point
 *  here is that any component is printable in Java 1.2.
 *  However, you have to be careful to turn off double buffering
 *  globally (not just for the top-level window).
 *  See the PrintUtilities class for the printComponent method
 *  that lets you print an arbitrary component with a single
 *  function call.
 *
 */

public class PrintExample extends JFrame
                           implements ActionListener {
  public static void main(String[] args) {
    new PrintExample();
  }

  public PrintExample() {
    super("Printing Swing Components in JDK 1.2");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    JButton printButton = new JButton("Print");
    printButton.addActionListener(this);
    JPanel buttonPanel = new JPanel();
    buttonPanel.setBackground(Color.white);
    buttonPanel.add(printButton);
    content.add(buttonPanel, BorderLayout.SOUTH);
    DrawingPanel drawingPanel = new DrawingPanel();
    content.add(drawingPanel, BorderLayout.CENTER);
    pack();
    setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    PrintUtilities.printComponent(this);
  }
}

 Uses the following classes:
                + PrintUtilities.java Simple utility class to support printing graphical windows in JDK 1.2.

import java.awt.*;
import javax.swing.*;
import java.awt.print.*;

/** A simple utility class that lets you very simply print
 *  an arbitrary component in JDK 1.2. Just pass the 
 *  component to PrintUtilities.printComponent. The 
 *  component you want to print doesn't need a print method 
 *  and doesn't have to implement any interface or do 
 *  anything special at all.
 *  


 *  If you are going to be printing many times, it is marginally
 *  more efficient to first do the following:
 *  

 *    PrintUtilities printHelper = 
 *      new PrintUtilities(theComponent);
 *  


 *  then later do printHelper.print(). But this is a very tiny
 *  difference, so in most cases just do the simpler
 *  PrintUtilities.printComponent(componentToBePrinted).
 *
 
 */

public class PrintUtilities implements Printable {
  protected Component componentToBePrinted;

  public static void printComponent(Component c) {
    new PrintUtilities(c).print();
  }
  
  public PrintUtilities(Component componentToBePrinted) {
    this.componentToBePrinted = componentToBePrinted;
  }
  
  public void print() {
    PrinterJob printJob = PrinterJob.getPrinterJob();
    printJob.setPrintable(this);
    if (printJob.printDialog())
      try {
        printJob.print();
      } catch(PrinterException pe) {
        System.out.println("Error printing: " + pe);
      }
  }

  // General print routine for JDK 1.2. Use PrintUtilities2
  // for printing in JDK 1.3.
  public int print(Graphics g, PageFormat pageFormat, 
                   int pageIndex) {
    if (pageIndex > 0) {
      return(NO_SUCH_PAGE);
    } else {
      Graphics2D g2d = (Graphics2D)g;
      g2d.translate(pageFormat.getImageableX(), 
                    pageFormat.getImageableY());
      disableDoubleBuffering(componentToBePrinted);
      componentToBePrinted.paint(g2d);
      enableDoubleBuffering(componentToBePrinted);
      return(PAGE_EXISTS);
    }
  }

  /** The speed and quality of printing suffers dramatically if
   *  any of the containers have double buffering turned on,
   *  so this turns it off globally.  This step is only 
   *  required in JDK 1.2.
   */
   
  public static void disableDoubleBuffering(Component c) {
    RepaintManager currentManager = 
                      RepaintManager.currentManager(c);
    currentManager.setDoubleBufferingEnabled(false);
  }

  /** Reenables double buffering globally. This step is only 
   *  required in JDK 1.2.
   */
  
  public static void enableDoubleBuffering(Component c) {
    RepaintManager currentManager = 
                      RepaintManager.currentManager(c);
    currentManager.setDoubleBufferingEnabled(true);
  }
}
//
                + DrawingPanel.java A basic JPanel containing a Java 2D drawing.

import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;

/** A window with a custom paintComponent method. 
 *  Illustrates that you can make a general-purpose method
 *  that can print any component, regardless of whether
 *  that component performs custom drawing.
 *  See the PrintUtilities class for the printComponent method
 *  that lets you print an arbitrary component with a single
 *  function call.
 *
  */

public class DrawingPanel extends JPanel {
  private int fontSize = 90;
  private String message = "Java 2D";
  private int messageWidth;
  
  public DrawingPanel() {
    setBackground(Color.white);
    Font font = new Font("Serif", Font.PLAIN, fontSize);
    setFont(font);
    FontMetrics metrics = getFontMetrics(font);
    messageWidth = metrics.stringWidth(message);
    int width = messageWidth*5/3;
    int height = fontSize*3;
    setPreferredSize(new Dimension(width, height));
  }

  /** Draws a black string with a tall angled "shadow"
   *  of the string behind it.
   */

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    int x = messageWidth/10;
    int y = fontSize*5/2;
    g2d.translate(x, y);
    g2d.setPaint(Color.lightGray);
    AffineTransform origTransform = g2d.getTransform();
    g2d.shear(-0.95, 0);
    g2d.scale(1, 3);
    g2d.drawString(message, 0, 0);
    g2d.setTransform(origTransform);
    g2d.setPaint(Color.black);
    g2d.drawString(message, 0, 0);
  }
}

          o PrintUtilities2.java Simple utility class to support printing graphical windows in JDK 1.3 and later. Inherits from PrintUtilities.java.

import java.awt.*;
import javax.swing.*;
import java.awt.print.*;

/** A simple utility class for printing an arbitrary
 *  component in JDK 1.3. The class relies on the 
 *  fact that in JDK 1.3 the JComponent class overrides
 *  print (in Container) to automatically set a flag
 *  that disables double buffering before the component
 *  is painted. If the printing flag is set, paint calls 
 *  printComponent, printBorder, and printChildren.
 *
 *  To print a component, just pass the component to 
 *  PrintUtilities2.printComponent(componentToBePrinted). 
 *
  */

public class PrintUtilities2 extends PrintUtilities {

  public static void printComponent(Component c) {
    new PrintUtilities2(c).print();
  }
  
  public PrintUtilities2(Component componentToBePrinted) {
    super(componentToBePrinted);
  }
  
  // General print routine for JDK 1.3. Use PrintUtilities1
  // for printing in JDK 1.2.
  public int print(Graphics g, PageFormat pageFormat, 
                   int pageIndex) {
    if (pageIndex > 0) {
      return(NO_SUCH_PAGE);
    } else {
      Graphics2D g2d = (Graphics2D)g;
      g2d.translate(pageFormat.getImageableX(), 
                    pageFormat.getImageableY());
      componentToBePrinted.print(g2d);
      return(PAGE_EXISTS);
    }
  }
}

    * FileTransfer.java Demonstrates the proper technique for updating Swing components in a multithreaded program.

/** 

// Final version of FileTransfer. Modification of the 
// label is thread safe.

public class FileTransfer extends Thread {
  private String filename;
  private JLabel label;

  public FileTransfer(String filename, JLabel label) {
    this.filename = filename;
    this.label = label;
  }

  public void run() {
  
    try {
      // Place the runnable object to update the label
      // on the event queue. The invokeAndWait method
      // will block until the label is updated.
      SwingUtilities.invokeAndWait(
        new Runnable() {
          public void run() {
            label.setText("Transferring " + filename);
          }
        });
    } catch(InvocationTargetException ite) {
    } catch(InterruptedException ie) { }
       
    // Transfer file to server. Lengthy process.
    doTransfer(...);

    // Perform the final update to the label from
    // within the runnable object. Use invokeLater;
    // blocking is not necessary.
    SwingUtilities.invokeLater(
       new Runnable() {
         public void run() {
           label.setText("Transfer completed");
         }
       });
  }
}
    * WindowUtilities.java Utility class that simplifies creating a window and setting the look and feel.
    * ExitListener.java A WindowListener with support to close the window.

Permanent link to this article: http://bangla.sitestree.com/printing-in-java-2/

Leave a Reply