这些 Java 教程是针对 JDK 8 编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅 Java 语言更改,了解 Java SE 9 及其后续版本中更新的语言特性的摘要。
请参阅 JDK 发布说明,了解有关所有 JDK 发布的新功能、增强功能以及已删除或弃用选项的信息。
JTable
类提供对表格的打印支持。 JTable
打印API包括了允许您实现基本和高级打印任务的方法。 对于常见的打印任务,当您只需要打印一个表格时,直接使用print
方法即可。 print
方法有多种形式,具有不同的参数集。 该方法准备您的表格,获取相应的Printable
对象,并将其发送到打印机。
如果Printable
对象的默认实现不符合您的需求,您可以通过重写getPrintable
方法来自定义打印布局,以包装默认的Printable
对象或完全替换它。
打印表格的最简单方法是调用没有参数的print
方法。 请参阅下面的代码示例。
try { boolean complete = table.print(); if (complete) { /* 显示成功消息 */ ... } else { /* 显示打印被取消的消息 */ ... } } catch (PrinterException pe) { /* 打印失败,向用户报告 */ ... }
当您调用没有参数的print
方法时,将显示打印对话框,然后以FIT_WIDTH
模式交互式打印您的表格,不包括页眉和页脚。 以下代码示例显示了带有完整参数集的print
方法签名。
boolean complete = table.print(JTable.PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat, boolean showPrintDialog, PrintRequestAttributeSet attr, boolean interactive, PrintService service);
当您使用所有参数调用print
方法时,您可以明确选择打印功能,例如打印模式、页眉和页脚文本、打印属性、目标打印服务,以及是否显示打印对话框,以及是否交互式打印。 要确定哪些参数最适合您的需求,请参阅下面可用功能的描述。
JTable
打印API提供以下功能:
在交互模式下,将显示一个带有中止选项的进度对话框,用于打印的持续时间。 下面是一个进度对话框的示例。
该对话框允许用户跟踪打印进度。进度对话框是模态的,这意味着在显示对话框时,用户无法与表格进行交互。在打印期间,重要的是您的表格保持不变,否则打印行为将是未定义的。然而,交互式打印不会阻止其他开发者的代码修改表格。例如,还有另一个线程使用SwingUtilities.invokeLater
方法发布更新。因此,为确保正确的打印行为,您应确保在打印期间您自己的代码不会修改表格。
或者,您可以以非交互方式打印表格。在这种模式下,打印立即在事件调度线程上开始,并完全阻塞任何待处理的事件。一方面,这种模式可以确保在打印完成之前,表格不会发生任何更改。另一方面,这种模式完全剥夺了用户与GUI的任何交互。这就是为什么只有在从非可见GUI的应用程序打印时才推荐使用非交互打印。
您可以显示一个标准的打印对话框,允许用户执行以下操作:
您可能会注意到打印对话框中没有指定打印输出的总页数。这是因为表格打印实现使用了Printable
API,打印时无法预先知道总页数。
页眉和页脚由MessageFormat
参数提供。这些参数允许对页眉和页脚进行本地化。请阅读MessageFormat
类的文档,因为一些字符(例如单引号)是特殊字符,需要避免使用。页眉和页脚都居中。您可以使用{0}插入页码。
MessageFormat footer = new MessageFormat("Page - {0}");
由于在打印时不知道输出的总页数,因此无法指定像“第1页/共5页”这样的编号格式。
打印模式负责缩放输出并将其分布在页面上。您可以以以下任一模式打印表格:
PrintMode.NORMAL
(正常模式)PrintMode.FIT_WIDTH
(适应宽度模式)在NORMAL
模式下,表格以其当前大小打印。如果列无法适应一页,它们将根据表格的ComponentOrientation
分布在其他页面上。在FIT_WIDTH
模式下,如果需要,表格的大小会缩小以适应每页的所有列。请注意,宽度和高度都会按比例缩放,以提供相同比例的输出。在这两种模式下,行会依次跨多个页面展开,每页尽可能多的行。
使用JTable
打印API,您无需关心布局和分页。您只需要为print
方法指定适当的参数,例如打印模式和页脚文本格式(如果您想在页脚插入页码)。如前所示,您可以在页脚字符串中包含"{0}"
来指定页码。在打印输出中,{0}将被当前页码替换。
让我们来看一个名为TablePrintDemo1
的示例。该程序的完整代码可以在TablePrintDemo1.java
中找到。这个演示的丰富GUI是由NetBeans IDE GUI构建器自动构建的。这是TablePrintDemo1
应用程序的截图。
每当一个通过Web启动的应用程序尝试进行打印时,Java Web Start会弹出一个安全对话框,询问用户是否允许打印。要继续打印,用户必须接受请求。
请注意,当你清除“交互式”复选框时,会出现一个警告消息,提醒用户打印非交互式的劣势。你可以在PrintGradesTable
方法中找到打印代码。当调用此方法时,首先从GUI组件中获取选定选项的集合,然后调用print
方法,如下所示。
boolean complete = gradesTable.print(mode, header, footer, showPrintDialog, null, interactive, null);
print
方法返回的值被用来显示成功消息或用户取消打印的消息。
另一个重要的功能是表格打印API使用表格渲染器。通过使用表格的渲染器,API提供了一个打印输出,其外观与屏幕上的表格相同。看一下屏幕上表格的最后一列。它包含了每个学生的通过或不通过状态的自定义图像。现在看一下打印结果。你会发现,勾号和叉号看起来是一样的。
下面是TablePrintDemo1在FIT_WIDTH
模式下的打印结果的图片。
TablePrintDemo2
示例是基于上一个示例的,并且具有相同的界面。唯一的区别在于打印输出结果。如果你仔细观察TablePrintDemo1的打印结果,你可能会注意到勾号和X号模糊不清。TablePrintDemo2
示例展示了如何自定义表格以使图像在表格打印中更加清晰可辨。在此示例中,重写的getTableCellRendererComponent
方法判断表格是否正在打印,并返回更清晰的黑白图像。如果表格没有在打印,它返回在屏幕上可见的彩色图像。
点击“启动”按钮使用Java™ Web Start(下载JDK 7或更高版本)运行TablePrintDemo2。或者,要自己编译和运行示例,请参考示例索引。
JComponent
类中定义的isPaintingForPrint
方法允许我们根据打印和屏幕显示的差异来自定义打印内容。下面是自定义单元格渲染器的代码,取自TablePrintDemo2.java
。这段代码根据isPaintingForPrint
方法的返回值选择使用哪些图像。
/** * 一个自定义单元格渲染器,继承自TablePrintDemo1的渲染器,用于在打印时使用更清晰的黑白图标。 */ protected static class BWPassedColumnRenderer extends PassedColumnRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); /* 如果当前正在打印,则使用黑白图标 */ if (table.isPaintingForPrint()) { boolean status = (Boolean)value; setIcon(status ? passedIconBW : failedIconBW); } /* 否则,使用父类(彩色)图标 */ return this; } }
这是TablePrintDemo2打印结果的图片,使用FIT_WIDTH模式。
TablePrintDemo3示例基于前两个演示。此示例展示了如何通过包装默认的Printable来提供自定义的Printable实现。此演示具有类似的界面,但标题和页脚的复选框被禁用,因为自定义的可打印对象将提供自己的标题和页脚。
点击“启动”按钮使用Java™ Web Start 运行TablePrintDemo3(下载JDK 7或更高版本)。或者,要自己编译和运行示例,请参考示例索引。
此示例将表格打印在剪贴板的图像内。这是TablePrintDemo3示例的打印结果的图片,使用FIT_WIDTH模式。
此程序的完整代码可以在TablePrintDemo3.java
中找到。在此演示中,使用了一个名为FancyPrintingJTable
的JTable
类的自定义子类。这个FancyPrintingJTable
类重写了getPrintable
方法,返回一个自定义的可打印对象,该对象包装了默认的可打印对象,并带有自己的装饰、标题和页脚。下面是getPrintable
方法的实现。
public Printable getPrintable(PrintMode printMode, MessageFormat headerFormat, MessageFormat footerFormat) { MessageFormat pageNumber = new MessageFormat("- {0} -"); /* 获取默认的可打印对象 */ Printable delegate = super.getPrintable(printMode, null, pageNumber); /* 返回一个包装默认可打印对象的精美可打印对象 */ return new FancyPrintable(delegate); }
FancyPrintable
类负责将默认的可打印对象包装成另一个可打印对象,并设置剪贴板图像。当实例化这个类的一个实例时,它会加载组装剪贴板图像所需的图像,计算剪贴板图像所需的区域,计算表格的缩小区域,将表格打印到较小的区域,并组装和打印剪贴板图像。
请注意,组装剪贴板图像的代码对于页面大小的灵活性。代码考虑了实际页面的尺寸,并组合辅助图像,根据需要拉伸其中一些图像,以使最终的剪贴板图像适合实际页面大小。下图显示了辅助图像并指示这些图像如何组成最终的输出。
本节列出了JTable
类中定义的允许您打印表格的方法。
方法 | 目的 |
---|---|
boolean print() boolean print(printMode) boolean print(printMode, MessageFormat, MessageFormat) boolean print(printMode, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean) boolean print(printMode, MessageFormat, MessageFormat, boolean, PrintRequestAttributeSet, boolean, PrintService) |
当不带参数调用时,显示一个打印对话框,然后以FIT_WIDTH 模式打印此表格,不包含页眉和页脚文本。如果用户继续打印,则返回true ,如果用户取消打印,则返回false 。当使用完整的参数列表调用时,根据指定的参数打印此表格。第一个参数指定打印模式。两个 MessageFormat 参数指定页眉和页脚文本。第一个布尔参数定义是否显示打印对话框。另一个布尔参数指定是否进行交互式打印。使用另外两个参数,您可以指定打印属性和打印服务。每当省略一个 PrintService 参数时,将使用默认打印机。 |
Printable getPrintable(PrintMode, MessageFormat, MessageFormat) | 返回用于打印表格的Printable 对象。重写此方法以获取自定义的Printable 对象。您可以将一个Printable 对象包装在另一个中以获得各种布局。 |
这个表格列出了使用表格打印的示例,并指向了这些示例所描述的位置。
示例 | 描述位置 | 注释 |
---|---|---|
TablePrintDemo |
如何使用表格 | 演示了表格打印的基本功能,例如显示打印对话框,然后以FIT_WIDTH 模式进行交互式打印,并将页码作为页眉。 |
TablePrintDemo1 |
本页面 | 演示了表格打印的基础知识,并提供了一个丰富的GUI。允许用户指定页眉或页脚文本,选择打印模式,打开或关闭打印对话框,以及选择交互式或非交互式打印。 |
TablePrintDemo2 |
本页面 | 基于TablePrintDemo1,此示例具有相同的界面。此演示演示了如何自定义表格,使打印结果与屏幕上显示的表格不同。 |
TablePrintDemo3 |
本页面 | 此演示显示了高级表格打印功能,例如将默认表格可打印对象包装到另一个可打印对象中,以获得不同的布局。 |