如何在 Swing 中显示打印进度对话框?
如果我在实现 Printable 的类中执行此操作,
PrinterJob job = PrinterJob.getPrinterJob();
job.setJobName( /* some name */ );
Book book = new Book();
book.append(this, new PageFormat());
job.setPageable(book);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
}
catch (PrinterException ex) {
ex.printStackTrace();
}
}
它会起作用,但我的 Printable 类会被调用两次 print()
。 (大概是为了打印机驱动程序的资源分配目的)
如何正确显示进度条?就我而言,我知道需要执行多少个子打印任务,但如果我尝试显示它,进度条将从开始到结束进行两次,这对用户来说是可怕的反馈。而且我不想显示不确定的进度条......
我该怎么办?
澄清:我正在页面上打印一堆图。它们有点复杂,需要一段时间才能打印,所以我可能知道有 10 个对象要渲染,所以我想让进度条从 0 到 10,并在渲染 10 个对象中的每一个后递增它。 (或者,更好的是,从 0 到 20,假设我能以某种方式知道页面被渲染了两次。)
If I do this in my class that implements Printable,
PrinterJob job = PrinterJob.getPrinterJob();
job.setJobName( /* some name */ );
Book book = new Book();
book.append(this, new PageFormat());
job.setPageable(book);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
}
catch (PrinterException ex) {
ex.printStackTrace();
}
}
it works, but my Printable class gets print()
called twice. (presumably for resource allocation purposes by the printer driver)
How can I display a progress bar properly? In my case, I know how many sub-printing tasks need to execute, but if I try to display it, the progress bar will proceed from start to finish twice, which is horrible feedback for a user. And I'd rather not display an indeterminate progress bar....
What should I do?
clarification: I'm printing a bunch of plots on a page. They're somewhat intricate and take a while to print, so I might know that there's 10 objects to render, so I'd like to have my progress bar go from 0 to 10, and increment it after I render each of the 10 objects. (Or, even better, go from 0 to 20, assuming I could somehow know the page was being rendered twice.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看提供给 print 方法的参数,第一次调用它(至少对我来说),图形是 PeekGraphics 对象,第二次是 WPathGraphics 对象。在我的系统上,
RasterPrinterJob
正在创建一个 PeekGraphics 以获取有关在为实际打印作业设置图形之前先打印作业。根据您更新进度条的方式,您可能可以在勾选之前检查图形参数是否不是 PeekGraphics。
Looking at the arguments supplied to the print method, the first time it's called (for me at least), the graphics is a PeekGraphics object, and the second time is a WPathGraphics one. On my system,
RasterPrinterJob
is creating a PeekGraphics to get information about the print job before setting up the graphics for the real print job.Depending on how you're updating your progress bar, you might be able to just check that the graphics argument is not a PeekGraphics before you give it a tick.
我放弃了尝试预测或区分 print() 调用次数的想法。
@Atreys 的答案很有希望,但我可以使用不反射或导入私有
sun.*
类的唯一区别是sun.print.PeekGraphics
实现java.awt.image.ImageObserver
,而sun.awt.windows.WPathGraphics
则不然。 (getClass().getName() 在我的书中算作反射)我最终所做的是对
Printable.print()
的每个单独调用使用进度条,例如将进度重置为开始并推进打印的每个子步骤。为了防止用户抱怨进度条显示两次进度,每当调用 print() 时,我都会将标签更改为“Pass #{k}”,其中 {k} 是每次都会递增的计数器。
ps 从
Printable.print()
中取消打印作业的正确方法有点棘手。抛出 PrintAbortException 似乎无法正常工作,因为它结束了对 print() 的调用,但打印机驱动程序继续运行,尽管Printable
javadoc 说的是:相反,您必须将 print() 方法的 Graphics 参数转换为 PrintGraphics 对象,然后调用 PrintGraphics.getPrinterJob().cancel():
I gave up on the idea of trying to predict or distinguish the # of calls to print().
@Atreys' answer was promising, but the only difference that I could use w/o reflection or importing private
sun.*
classes was thatsun.print.PeekGraphics
implementsjava.awt.image.ImageObserver
, whereassun.awt.windows.WPathGraphics
does not. (getClass().getName() counts as reflection in my book)What I ended up doing was to use my progress bar for each individual call to
Printable.print()
, e.g. reset the progress to the beginning and advance it for each substep of print.To keep the users from complaining that the progress bar shows progress twice, I have a label that is changed to "Pass #{k}" whenever print() is called, where {k} is a counter that is incremented each time.
p.s. The proper way to cancel a print job from within
Printable.print()
is a little tricky. Throwing PrintAbortException doesn't seem to work correctly, as it ends the call to print() but the printer driver keeps going, despite the fact that thePrintable
javadoc says this:Instead, you have to cast the print() method's Graphics parameter as a PrintGraphics object, and then call PrintGraphics.getPrinterJob().cancel():