Java打印和打印预览机制实例代码

复制代码 代码如下:

import java.awt.basicstroke;

import java.awt.borderlayout;

import java.awt.color;

import java.awt.component;

import java.awt.dimension;

import java.awt.font;

import java.awt.fontmetrics;

import java.awt.graphics;

import java.awt.graphics2d;

import java.awt.gridlayout;

import java.awt.event.actionevent;

import java.awt.event.actionlistener;

import java.awt.event.mouseadapter;

import java.awt.event.mouseevent;

import java.awt.print.pageformat;

import java.awt.print.printable;

import java.awt.print.printerexception;

import java.awt.print.printerjob;

import javax.swing.jbutton;
import javax.swing.jdialog;
import javax.swing.jframe;
import javax.swing.jpanel;
import javax.swing.jscrollpane;
import javax.swing.jtextarea;
import javax.swing.swingutilities;
import javax.swing.windowconstants;
import javax.swing.text.badlocationexception;
import javax.swing.text.document;

/**
 * 使用了原始的分页方式去渲染jtextarea,提供了打印预览机制。
 * <p>
 * 事实上,我们还可以通过其他方式打印jtextarea:
 * <ol>
 * <li>{@code component.print(graphics g);} or
 * {@code component.printall(graphics g);}</li>
 * <li>{@code component.paint(graphics g);} or
 * {@code component.paintall(graphics g);} whose rending may be slightly
 * different to the previous method (for example, <code>jframe</code>)</li>
 * <li>{@code jtable.print();} or {@code jtextcomponent.print();} provide
 * especially powerful and convenient printing mechanism</li>
 * </ol>
 *
 * @author gaowen
 */
public class printuicomponent extends jpanel implements actionlistener,
  printable {
 private static final long serialversionuid = 4797002827940419724l;
 private static jframe frame;
 private jtextarea textareatoprint;
 private printerjob job;
 private int[] pagebreaks;// array of page break line positions
 private string[] textlines;
 private header header;

 public printuicomponent() {
  super(new borderlayout());
  textareatoprint = new jtextarea(50, 20);
  for (int i = 1; i <= 50; i++) {
   textareatoprint.append(“line ” + i + “\n”);
  }
  jscrollpane scrollpane = new jscrollpane(textareatoprint);
  scrollpane.setpreferredsize(new dimension(250, 200));
  add(scrollpane, borderlayout.center);
  jbutton printbutton = new jbutton(“print this textarea”);
  printbutton.setname(“printbutton”);
  printbutton.addactionlistener(this);
  jbutton printpreviewbutton = new jbutton(“print preview”);
  printpreviewbutton.setname(“printpreviewbutton”);
  printpreviewbutton.addactionlistener(this);
  jpanel buttongroup = new jpanel(new gridlayout(2, 1));
  buttongroup.add(printbutton);
  buttongroup.add(printpreviewbutton);
  add(buttongroup, borderlayout.south);

  /* initialize printerjob */
  initprinterjob();
 }

 public static void main(string[] args) {
  swingutilities.invokelater(new runnable() {
   @override
   public void run() {
    createandshowgui();
   }
  });
 }

 private static void createandshowgui() {
  frame = new jframe(“print ui example”);
  frame.setcontentpane(new printuicomponent());
  frame.pack();
  frame.setlocationrelativeto(null);
  frame.setdefaultcloseoperation(windowconstants.exit_on_close);
  frame.setvisible(true);
 }

 private void inittextlines() {
  document doc = textareatoprint.getdocument();
  try {
   string text = doc.gettext(0, doc.getlength());
   textlines = text.split(“\n”);
  } catch (badlocationexception e) {
   e.printstacktrace();
  }
 }

 private void initprinterjob() {
  job = printerjob.getprinterjob();
  job.setjobname(“print textarea”);// 出现在系统打印任务列表
  job.setprintable(this);
 }

 @override
 public int print(graphics graphics, pageformat pageformat, int pageindex)
   throws printerexception {
  /*
   * it is safe to use a copy of this graphics as this will not involve
   * changes to it.
   */
  graphics2d g2 = (graphics2d) graphics.create();

  /* calculate “pagebreaks” */
  font font = new font(“serif”, font.plain, 12);
  fontmetrics metrics = g2.getfontmetrics(font);
  int lineheight = metrics.getheight();
  if (pagebreaks == null) {
   inittextlines();
   int linesperpage = (int) (pageformat.getimageableheight() / lineheight);
   int numbreaks = (textlines.length – 1) / linesperpage;
   pagebreaks = new int[numbreaks];
   for (int b = 0; b < numbreaks; b++) {
    pagebreaks[b] = (b + 1) * linesperpage;
   }
  }

  /* condition to exit printing */
  if (pageindex > pagebreaks.length) {
   return no_such_page;
  }

  /* (0,0) is outside the imageable area, translate to avoid clipping */
  g2.translate(pageformat.getimageablex(), pageformat.getimageabley());

  /* draw each line that is on this page */
  int y = 0;
  int start = (pageindex == 0) ? 0 : pagebreaks[pageindex – 1];
  int end = (pageindex == pagebreaks.length) ? textlines.length
    : pagebreaks[pageindex];
  for (int line = start; line < end; line++) {
   y += lineheight;
   g2.drawstring(textlines[line], 0, y);
  }

  /* dispose of the graphics copy */
  g2.dispose();

  /* tell the caller that this page is part of the printed document */
  return page_exists;
 }

 @override
 public void actionperformed(actionevent e) {
  object actioneventsource = e.getsource();
  if (actioneventsource instanceof jbutton) {
   jbutton button = (jbutton) actioneventsource;
   if (button.getname().equals(“printbutton”)) {
    pagebreaks = null;// reset pagination
    boolean ok = job.printdialog();
    if (ok) {
     try {
      job.print();
     } catch (printerexception ex) {
      /* the job did not successfully complete */
      ex.printstacktrace();
     }
    }
   } else if (button.getname().equals(“printpreviewbutton”)) {
    pagebreaks = null;// reset pagination
    createandshowpreviewdialog();
   }
  }
 }

 private void createandshowpreviewdialog() {
  jdialog previewdialog = new jdialog(frame, “print preview dialog”, true);
  jpanel contentpane = new jpanel(new borderlayout());
  previewarea previewarea = new previewarea();
  previewarea.addmouselistener(new previewareamouseadapter(previewarea));
  jscrollpane scrollpane = new jscrollpane(previewarea);
  contentpane.add(scrollpane, borderlayout.center);
  header = new header(previewarea);
  contentpane.add(header, borderlayout.north);
  previewdialog.setcontentpane(contentpane);
  previewdialog.setsize(600, 600);
  previewdialog
    .setdefaultcloseoperation(windowconstants.dispose_on_close);
  previewdialog.setvisible(true);
 }

 private class header extends component {
  private static final long serialversionuid = -1741188309769027249l;
  private previewarea previewarea;
  private boolean paintable;

  private header(previewarea previewarea) {
   this.previewarea = previewarea;
  }

  private void setpaintable(boolean paintable) {
   this.paintable = paintable;
  }

  @override
  public void paint(graphics g) {
   if (paintable) {
    g.setcolor(color.gray);
    g.drawstring(
      string.valueof(previewarea.getpageindex() + 1)
        + “/”
        + string.valueof(pagebreaks.length + 1)
        + ” pages (click left mouse button to preview next page; right to previous)”,
      10, 15);
   }
  }

  @override
  public dimension getpreferredsize() {
   return new dimension(super.getpreferredsize().width, 20);
  }
 }

 private class previewarea extends component {
  private static final long serialversionuid = -6384174997251439843l;
  private pageformat pageformat;
  private int pageindex;
  private int w;
  private int h;
  private final int marginx = 10;
  private final int marginy = 20;

  private previewarea() {
   pageformat = job.pagedialog(job.defaultpage());
   pageindex = 0;
   w = (int) pageformat.getwidth();
   h = (int) pageformat.getheight();
  }

  private int getpageindex() {
   return pageindex;
  }

  private void setpageindex(int pageindex) {
   this.pageindex = pageindex;
  }

  @override
  public dimension getpreferredsize() {
   return new dimension(w + 2 * marginx, h + 2 * marginy);
  }

  @override
  public void paint(graphics g) {
   graphics2d g2 = (graphics2d) g.create();
   g2.translate(marginx, marginy);
   g2.drawrect(0, 0, w, h);
   int ix = (int) (pageformat.getimageablex() – 1);
   int iy = (int) (pageformat.getimageabley() – 1);
   int iw = (int) (pageformat.getimageablewidth() + 1);
   int ih = (int) (pageformat.getimageableheight() + 1);
   g2.setstroke(new basicstroke(1f, basicstroke.cap_round,
     basicstroke.join_round, 10f, new float[] { 5, 5 }, 0f));
   g2.drawrect(ix, iy, iw, ih);
   try {
    printuicomponent.this.print(g2, pageformat, pageindex);
   } catch (printerexception e) {
    e.printstacktrace();
   }
   g2.dispose();
   header.setpaintable(true);
   header.repaint();
  }
 }

 private class previewareamouseadapter extends mouseadapter {
  private previewarea previewarea;

  private previewareamouseadapter(previewarea previewarea) {
   this.previewarea = previewarea;
  }

  @override
  public void mouseclicked(mouseevent e) {
   int currentindex = previewarea.getpageindex();
   if (e.getbutton() == mouseevent.button1) {
    /* next page */
    if (currentindex < pagebreaks.length) {
     previewarea.setpageindex(currentindex + 1);
     previewarea.repaint();
    }
   } else if (e.getbutton() == mouseevent.button3) {
    /* previous page */
    if (currentindex > 0) {
     previewarea.setpageindex(currentindex – 1);
     previewarea.repaint();
    }
   }
  }
 }
}

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐