在Java中轻松打印文档
当前位置:以往代写 > JAVA 教程 >在Java中轻松打印文档
2019-06-14

在Java中轻松打印文档

在Java中轻松打印文档

副标题#e#

有关在Java中实现文档打印的典范说法描写了一个巨大的进程,它要求对字 体举办测定、对文本举办理会并将功效绘制到一个Graphics工具中。这个进程似 乎执行起来相当坚苦,而且它和用于文档视频显示的高级编程要领纷歧致。假如 你想要耗费大量的精神来完成这个进程,那么你就不会首先想到要在Java中编程 。

你必然不想本身完成测定、理会和绘制进程,而是但愿通过简朴地将文档发 送到一个能为你处理惩罚所有工作的工具中来完成这个任务。本文就将先容这样一个 工具――DocumentRenderer,它将一个文档作为要领中的一个参数并处理惩罚指定任 务来完成打印。好比,用这个类来显示一个HTML文档需要两个步调:结构一个 DocumentRenderer类的实例并将HTML文档作为参数发送到print(HTMLDocument) 要领中。DocumentRenderer类用于处理惩罚打印该文档所必须的开销,包罗显示一个 打印对话框以合名目化文本。

我们设计了这个DocumentRenderer类以便操作这个已经在Java中可用的高级 文天机能。 按照可重用和可扩展类的原则,我们利用了一些现有的工具 (Java.Swing.Text Package用它来对显示功效举办名目化)使打印功效可以或许显 示在纸上。用这种要领设计DocumentRenderer使我们可以或许用比前面接头过的要领 少写近200行的代码来成立这个类。

除了能少写代码之外,利用DocumentRenderer 实现中的现有工具还提供了一 些特另外成果使得该类越发通用。在最初设计这个类的时候,我们只是规划将 HTML文档打印出来。而添加一些成果来打印其他范例的文档则是厥后的想法。当 我们发明只需在用于HTML 打印类的代码中加上约6行的特别代码就可以打印一个 Rich Text Format文档时,便在这个项目标后期添加了这个成果。

显示文档

DocumentRenderer可以或许用来打印几类包括在JEditorPane中的文档。我们用三 种范例的文档(JEditorPane可以或许缺省识此外)测试了这个printer类: HTMLDocuments、PlainDocuments和Rich Text Format文档。只需要做一些很小 的窜改,这个类就应该可以将包括在JEditorPane中的其他范例文档打印出来了 。

DocumentRenderer类将一个文档的打印形式从其视频显示中区分出来了。这 就使你可以或许针对特定的打印功效举办文本名目化,而会不影响其屏幕显示。 DocumentRenderer回收所有打印页面的实际巨细来显示文本并计较出行间距 (line break)。当文档的宽度不敷以显示在打印页面上时,该类会答允利用缩 放(scaling)。

DocumentRenderer相当智能。分页符不会将一行单一语句分放到两个页面上 。字符也不会被切成两半,不会象欣赏器在处理惩罚一般打印时会在这一页末端显示 一句话的上半部门而在下一页的顶部显示这句话的下半部门。这个类可以或许处理惩罚大 量字体、颜色和小图标。分栏文本的显示也没有问题。对付每一个JEditorPane 可以或许显示的文本特性,凡是DocumentRenderer都可以将这种机能泛起到纸上。

你只需利用两行代码便可以将DocumentRenderer团结到你的措施中去了。用 一个不带参数的结构器建设这个类的实例,再挪用一个符合的打印要领来处理惩罚其 他工作。好比,以下代码将打印这个htmlDocument,它是HTMLDocument类的一个 有效实例:

DocumentRenderer DocumentRenderer = new
DocumentRenderer();
DocumentRenderer.print(htmlDocument);

它给用户显示一个打印对话框,答允用户选择打印机、打印数量等,同时还 有一个打消打印的选项。

PlainDocuments利用了print(PlainDocument)要领,回收和HTMLDocuments相 同的方法执行打印。由于在Java中不能直接会见Rich Text Format文档,所以你 必需将这种范例的文档发送到DocumentRenderer中(通过将它封装到一个 JEditorPane里),就象这样:DocumentRenderer.print(jeditorPane);

这里的jeditorPane是JEditorPane的一个有效实例,个中包括一个Rich Text Format文档。

为了给用户提供利便,你可以挪用DocumentRenderer的pageDialog要领来显 示一个打印对话框以便用户可以调解页面巨细、页边配置和纸的打印偏向 (orientation)。DocumentRenderer还提供了一种要领使开拓人员可以选择是 否对那些无法在打印宽度内完全显示的文档举办按比例缩放。我们认为可以或许举办 缩放凡是是较量好的选择,因为它可以或许防备文本在正确的页边处被分隔,但它似 乎较量适合让用户去选择。这种名为setScaleWidthToFit(boolean)的要领提供 了按比例缩放的选项。你必需确定在挪用打印要领之前挪用这个scaling和 pageDialog要领。

相识DocumentRenderer

DocumentRenderer用于执行显示一个打印对话框并通过利用在Java Swing Printing API中可用的尺度化东西开始打印操纵。由于在利用这个 DocumentRenderer类时无需完全相识这个API,并且该API已经在许多处所被具体 描写过,因此这里我们就不再先容它了。这个用于DocumentRenderer类的源代码 中还包罗了这个打印逻辑的完整文档。

#p#分页标题#e#

然而我们或者应该表明一下DocumentRenderer用来在单独打印页面中定位文 本的进程,以便你相识这个类所提供的改造成果,这会帮你回首这个Java打印过 程凡是遵循的显示文档的逻辑。

文档凡是是以一种简朴的方法举办打印的。首先,文档会被放入JEditorPane 。你可以将打印进程想象为在JEditorPane 的上面安排一个矩形框(其巨细和页 面打印区的巨细相等),并对个中的内容举办打印而无需体贴外面的部门。

这个矩形的上沿与JEditorPane 顶部齐平,矩形框内部的区域会被绘制 (paint)。假如矩形的下沿穿过文本,不消去管它;字符会在打印页面的底部 被分隔。打印第二页时,矩形的上沿被向下移至前面被下沿所占据的那一行,该 进程被反复执行。由于第二页正亏得第一页竣事的处所开始,因此在第一页底部 被分隔的字符会呈此刻第二页的顶部。后头几页也是一样。

为了制止从行间断开,DocumentRenderer会仔细检侧文档以测定是否一个单 独文本和页面完整契合。这样会比只是在JEditorPane中放一个矩形框并打印其 中内容的结果更佳。


#p#副标题#e#

绘制视图(View)

假如将JEditorPane看作仅包括了一个文档的要领,你就不能测定所有文本的 位置或巨细了。一个文档对付这个任务来说太大了,文档或者会契合于一个单一 页面,或者不会。为了使文档可以或许完整契合于打印纸,你必需将它分成一些小的 部门以便对每个部门的位置举办检测。

幸运的是,Java Swing Text Package提供了一个View类,它能使你将文档分 成单一的、适于绘制的部门。你可以将JEditorPane想象成是由几个视图部门组 成的;此刻你就可以完全基于这些小部门的巨细和位置来打印文档了。

View类的子类用于处理惩罚可视性组件(visual component)中的显示和打印文 本的任务。然而,处理惩罚打印文本的很多措施员没有意识到的是视图可以在显示到 纸上时提供这些沟通的成果。尽量对视图问题举办具体接头是本文以外的话题, 但在接头文档打印时对它有一个大抵的相识照旧很有须要的。

在Swing中,视图被看成处理惩罚文本显示的容器。在树型目次中一个根视图可以 有多个视图分支。在这些分支的端部会显示代表真实文本的叶视图(leaf view )。

将这个视图的树型布局看成一个由单一的、大的、包括整个文本的视图来考 虑。这个文档视图被分成几个段落视图,它被依次分成几个单独的行。尽量真实 事情中的视图环境要比这个简朴的描写巨大的多,但该例子中显示了如何通过视 图来将一个文档分成契合于打印纸的小的部门。通过查察每一行,你可以测定它 是否完全契合于打印纸而不会在底部被分隔。假如行数契合,就执行打印,假如 不契合,则将它记录下来以便在下一页中执行打印。

包括在JEditorPane中的视图采纳了一种和在JPanel中的组件行为相雷同的操 作。一个主要区别在于视图不要求机关打点器(layout managers)来举办位置 处理惩罚;它们会本身参加机关。这样一来,在JEditorPane中的视图就会象一个真 实的组件和机关打点器一样举办操纵。视图知道如何查察、如何绘制本身以及在 那边显示其子文档。

视图并不是被直接成立的。更确切地说,它们是由ViewFactory子类的工场( factory)来生成的。一个ViewFactory生成一个文档并将它们分成根视图以及所 需的分支视图和叶视图。工场会凭据这种方法来处理惩罚这些乏味的理会文档和计较 机关的事情。

你很少可以或许直接和这些工场打交道。对许多部门来说,它们是被自动挪用的 。在JEditorPane中配置文档并挪用JEditorPane.validate()要领来将文档发送 的适合的工场中,该工场则会返回所需的视图。然后这些视图会被用在组件的布 局上。

打印视图

DocumentRenderer类可以或许将需要打印的文档放入jeditorPane中,它是 JEditorPane的一个实例。jeditorPane的宽度抉择了打印页面的巨细并且它会调 用一个验证要领来执行机关。DocumentRenderer不会显示这个JEditorPane,因 此屏幕显示不会生效。需要被打印的根视图是通过一个有点巨大的jeditorPane 用户界面挪用来得到的:

View rootView =jeditorPane.getUI().getRootView(jeditorPane);

这个rootView及其子视图大概会对所需信息举办查询以便对打印文档举办布 局。这些视图在每部门文本的绘制情况(graphical context)中提供了坐标和 巨细。通过这些信息你就可以或许测定这部门文本是否和打印页面相契合。假如契合 ,则DocumentRenderer将执行打印;假如不契合,该类将对这个用来打印这部门 文本而不将其分隔的分页符举办测定。

#p#分页标题#e#

由于视图知道如何自行绘制,因此你无需本身配置字体或颜色。 DocumentRenderer以多种字体和颜色通过挪用一个简朴视图的paint要领来处理惩罚 式样文本(styled text)。

然而这个视图的树型布局也存在一个问题。你不能确定在一个代表打印文本 的叶视图竣事之前分支视图从根视图中被分出了屡次。你可以通过利用 DocumentRenderer 类中的一个简朴的轮回要领来办理这个问题。

printView要领轮回颠末视图的分支布局来查找可打印的叶视图。这种要领将 一个视图作为个中一个参数。它从根视图开始对每个视图举办查抄以测定它是否 有相关的子视图。假如有,则printView会依次挪用每个子视图将其作为其视图 参数。这样一来,这个要领最终会运行至整个树型布局。当该要领发明一个不带 子视图的叶视图时,它会在用于打印的绘制情况中检测它的位置。这个要领只用 于绘制那些完全契合于该情况的可打印部门的叶视图。当一个叶视图分跨 (straddle)页面的底部时,这个要领就会记录该页面上沿的位置以便使下一页 从这个位置开始。因此分页符就不会从文本的行傍边断开了。

假如你想要更深入地相识打印视图的用法,你可以查找DocumentRenderer类 的源代码。我们对它举办了注释讲授。由于它只有不到200行的代码,因此我们 有富裕的时间来给它加上注释。

该类的范围

我们在Java SDK 1.3和1.4版本中对DocumentRenderer举办过测试,尽量它应 该是合用于实现Swing的所有Java版本的。DocumentRenderer是通过尺度的Java 技能来运行的,因此它不能实现比Java自己更好或更糟的文本绘制。在 JEditorPane中不能显示的字符也将无法显示在纸上。

Java在Windows情况下对文本举办测按时有一个小问题。由于文本没有被准确 地测定,一些位置大概有些偏离。由于这些错误很小所以凡是不是什么大问题, 但它会在对文本右对齐(right-justified )时变得很贫苦。因此,要只管制止 利用右对齐方法。DocumentRenderer类不会发生这个问题,它好像也不会呈此刻 Linux情况中。

最后要说的是,大图标是不能被打印出来的。在Java中不能将它们显示在页 面中,但小图标是没有问题的。

在Java中执行打印不再会是一个巨大的问题了。只需简朴地写两行代码并通 过DocumentRenderer类来将高级的文本打印成果添加到你的措施中可以了。

    关键字:

在线提交作业