本教程适用于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页面,将其添加到打印列表,并一次在后台线程上打印所有选定的页面。 |