本教程适用于JDK 8。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改了解Java SE 9及其后续版本中更新的语言特性的摘要。
请参阅JDK发布说明了解有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息。
JTextComponent类提供了文本文档打印的支持。 JTextComponent API包括了允许您实现基本和高级打印任务的方法。支持的格式包括HTML、RTF和纯文本。对于简单的打印任务,比如打印文本文档,可以直接使用print方法。 print方法有几种形式,具有不同的参数集。该方法准备您的文本文档,获取相应的Printable对象,并将其发送到打印机。
如果默认的Printable对象的实现不符合您的需求,您可以通过覆盖getPrintable方法来自定义打印布局,以包装默认的Printable对象,甚至完全替换它。
打印文本组件的最简单方法是调用没有参数的print方法。请参阅下面的代码示例。
try {
boolean complete = textComponent.print();
if (complete) {
/*显示成功消息*/
...
} else {
/*显示打印被取消的消息*/
...
}
} catch (PrinterException pe) {
/*打印失败,向用户报告*/
...
}
当您调用没有参数的print方法时,将显示打印对话框,然后以交互方式打印您的文本组件,不包括页眉和页脚。下面的代码示例显示了具有完整参数集的print方法签名。
boolean complete = textComponent.print(MessageFormat headerFormat,
MessageFormat footerFormat,
boolean showPrintDialog,
PrintService service
PrintRequestAttributeSet attributes,
boolean interactive);
当您使用所有参数调用print方法时,您可以显式选择打印特性,例如页眉和页脚文本、打印属性、目标打印服务,以及是否显示打印对话框,以及是否交互式或非交互式打印。要决定哪些参数最适合您的需求,请参阅下面的可用特性的描述。
JTextComponent打印API提供了以下功能:
在交互模式下,打印过程中会显示一个带有中止选项的进度对话框。以下是一个进度对话框的示例。
该对话框允许用户跟踪打印进度。当在事件调度线程上调用print方法时,进度对话框是模态的;否则是非模态的。在打印过程中,文档必须保持不变,否则打印行为是未定义的。print方法确保文档不会被更改,并在打印过程中禁用组件。
如果您在非交互模式下在事件调度线程上调用print方法,那么所有事件,包括重绘,都将被阻塞。因此,只建议在具有非可见GUI的应用程序上在EDT上进行非交互式打印。
您可以显示一个标准的打印对话框,用户可以在该对话框中执行以下操作:
您可能注意到打印对话框中没有指定打印输出中的总页数。这是因为文本打印实现使用了Printable API,并且在打印时无法知道总页数。
页眉和页脚是由MessageFormat参数提供的。这些参数允许对页眉和页脚进行本地化。请阅读MessageFormat类的文档,因为特殊字符(如单引号)需要避免使用。页眉和页脚都居中显示。您可以使用{0}插入页码。
MessageFormat footer = new MessageFormat("页码 - {0}");
由于在输出时无法事先知道输出的总页数,因此无法指定类似“第1页/共5页”的编号格式。
让我们来看一个名为TextAreaPrintingDemo的示例。该示例的主要特点是根据用户的选择,在事件分派线程或后台线程上打印文本文档。该示例显示一个文本区,允许选择几个打印功能,并根据所选选项打印文本区的内容。完整的程序代码可以在TextAreaPrintingDemo.java中找到。该示例的GUI使用NetBeans IDE GUI构建器构建。下面是TextAreaPrintingDemo应用程序的截图。
每当一个通过Web启动的应用程序尝试打印时,Java Web Start都会打开一个安全对话框,询问用户是否允许打印,除非该权限已在系统设置中授予。要继续打印,用户必须接受该请求。
为“打印”按钮注册了一个动作监听器。当用户点击“打印”按钮时,actionPerformed方法调用print方法,启动一个打印任务。打印任务是一个SwingWorker对象。下面的代码示例显示了PrintingTask类的实现。
private class PrintingTask extends SwingWorker<Object, Object> {
private final MessageFormat headerFormat;
private final MessageFormat footerFormat;
private final boolean interactive;
private volatile boolean complete = false;
private volatile String message;
public PrintingTask(MessageFormat header, MessageFormat footer,
boolean interactive) {
this.headerFormat = header;
this.footerFormat = footer;
this.interactive = interactive;
}
@Override
protected Object doInBackground() {
try {
complete = text.print(headerFormat, footerFormat,
true, null, null, interactive);
message = "打印" + (complete ? "完成" : "已取消");
} catch (PrinterException ex) {
message = "抱歉,发生打印机错误";
} catch (SecurityException ex) {
message = "抱歉,由于安全原因无法访问打印机";
}
return null;
}
@Override
protected void done() {
message(!complete, message);
}
}
下面的代码示例显示了print方法如何从GUI组件中获取所选选项集,然后创建PrintingTask类的实例并执行打印。
private void print(java.awt.event.ActionEvent evt) {
MessageFormat header = createFormat(headerField);
MessageFormat footer = createFormat(footerField);
boolean interactive = interactiveCheck.isSelected();
boolean background = backgroundCheck.isSelected();
PrintingTask task = new PrintingTask(header, footer, interactive);
if (background) {
task.execute();
} else {
task.run()
}
}
粗体显示的代码演示了如何根据background参数的值调用PrintingTask的方法。每当用户选择在后台线程上打印时,将调用execute方法,该方法将打印任务安排在后台线程上执行。否则,run方法将在EDT上执行打印任务。
由于打印大型文档是一个耗时的任务,建议在后台线程上执行打印。
TextBatchPrintingDemo示例演示了如何在后台线程上打印非可见的HTML文本文档。启动此演示时,会显示一个包含URL列表的页面。您可以访问一个HTML页面,将显示的页面添加到打印列表中,并在选择所需的所有页面后一次性在后台线程上打印它们。此程序的全部代码可以在TextBatchPrintingDemo.java中找到。这是TextBatchPrintingDemo应用程序的图片。
您可以在printSelectedPages方法中找到打印代码。调用此方法时,首先获取选择的打印页面数量。下面的代码示例显示了printSelectedPages方法如何为每个页面创建一个Runnable对象,然后在单独的线程上打印当前页面。
for (int i = 0; i < n; i++) {
final PageItem item = (PageItem) pages.getElementAt(i);
// 此方法从EDT中调用。打印是一项耗时的任务,因此应该在EDT之外,在单独的线程中进行。
Runnable printTask = new Runnable() {
public void run() {
try {
item.print(
// 两个“false”参数表示“无打印对话框”和“非交互式”(即批处理模式打印)。
null, null, false, printService, null, false);
} catch (PrinterException pe) {
JOptionPane.showMessageDialog(null,
"打印" + item.getPage() + "时出错\n" + pe,
"打印错误", JOptionPane.WARNING_MESSAGE);
}
}
};
new Thread(printTask).start();
本节列出了JTextComponent类中定义的允许您打印文本文档的方法。
| 方法 | 目的 |
|---|---|
| boolean print() boolean print(MessageFormat, MessageFormat) boolean print(MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean, PrintService) |
当无参数调用时,显示打印对话框,并以交互方式打印此文本组件,无页眉或页脚文本。如果用户继续打印,则返回true,如果用户取消打印,则返回false。当使用两个 MessageFormat参数调用时,显示打印对话框,并以指定的页眉和页脚文本交互打印此文本组件。当使用完整的参数集调用时,根据指定的参数打印此文本组件。两个 MessageFormat参数指定页眉和页脚文本。第一个布尔参数定义是否显示打印对话框。另一个布尔参数指定是否交互式打印。通过另外两个参数,您可以指定打印属性和打印服务。每当省略 PrintService参数时,将使用默认打印机。 |
| Printable getPrintable(MessageFormat, MessageFormat) | 返回一个用于打印文本组件的Printable对象。重写此方法以获取自定义的Printable对象。您可以将一个Printable对象包装在另一个对象中,以获得复杂的报告和文档。 |
此表列出了使用文本打印的示例,并指向这些示例所在的位置。
| 示例 | 描述位置 | 备注 |
|---|---|---|
TextAreaPrintingDemo |
此页面 | 演示了文本打印的基础知识,并提供了丰富的GUI。允许用户指定页眉或页脚文本,打开或关闭打印对话框,选择交互式或非交互式打印,然后根据所选选项进行打印。 |
TextBatchPrintingDemo |
此页面 | 此演示显示了一个带有URL列表的文本组件,允许用户查看HTML页面,将其添加到打印列表,并一次在后台线程上打印所有选定的页面。 |