如何获得我设置的纸张来源?
这是一个简短的例子:
public class PrinterPaperSourceTest extends Application { public static void main(String[] args) { launch( args ); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Printer"); Button btn = new Button(); btn.setText("Show Printer Settings "); btn.setOnAction( new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { PrinterJob job = PrinterJob.createPrinterJob(Printer.getDefaultPrinter()); job.showPageSetupDialog(null); Alert alert = new Alert(AlertType.INFORMATION); PaperSource paperSource = job.getJobSettings().getPaperSource(); alert.setContentText("PaperSource: " + paperSource.getName()); alert.show(); } }); StackPane root = new StackPane(); root.getChildren().add(btn); primaryStage.setScene(new Scene(root,300,250)); primaryStage.show(); } }
解决方法
Media is the IPP attribute that identifies the medium on which to print. The Media attribute is an important attribute to understand,but is relatively complex.
The Java Print Service API defines three subclasses of the abstract class Media to reflect the overloaded Media attribute in the IPP specification: MediaSizeName,MediaName and MediaTray. All the Media subclasses have the Media category,for which each subclass defines different standard attribute values. […]
The value of the Media attribute is always a String,but because the attribute is overloaded,its value determines the type of media to which the attribute refers. For example,the IPP pre-defined set of attribute values include the values “a4” and “top-tray”. If Media is set to the value “a4” then the Media attribute refers to the size of paper,but if Media is set to “top-tray” then the Media attribute refers to the paper source. […]
In most cases,applications will use either MediaSizeName or MediaTray. The MediaSizeName class enumerates the media by size. The MediaTray class enumerates the paper trays on a printer,which usually include a main tray and a manual Feed tray. The IPP 1.1 specification does not provide for specifying both the media size and the media tray at the same time,which means,for example,that an application cannot request size A4 paper from the manual tray. A future revision of the IPP specification might provide for a way to request more than one type of media at a time,in which case the JPS API will most likely be enhanced to implement this change.
因此,MediaTray(或纸张来源)不是独立参数,如果Media属性已经由其他两种方式之一(MediaSizeName或MediaName)定义,则无法设置.这正是页面设置对话框所发生的情况.
J2DPrinterJob类(来自com.sun.prism.j2d.print包)包含对话框代码并更新打印作业设置(我通过调试您的应用程序找到了这个).以下是此类中从对话框更新纸张来源设置的方法.
private void updatePaperSource() { Media m = (Media)printReqAttrSet.get(Media.class); if (m instanceof MediaTray) { PaperSource s = j2dPrinter.getPaperSource((MediaTray)m); if (s != null) { settings.setPaperSource(s); } } }
我测试了不同的场景,结果是一样的:当updatePaperSource()开始执行时,Media属性已经被定义为MediaSizeName类型.所以if分支中的语句永远不会被执行,这就是为什么纸质来源没有更新的原因.
我怀疑纸张类型或纸张尺寸优先于纸张来源,并且因为页面设置对话框始终定义纸张类型(没有“自动”选项),它会使纸张来源的选择超载,以避免属性冲突.这实际上使这个选项无用.
它可能是JDK中的错误或有意的设计决策.无论如何,考虑到它来自Java内部API中的私有方法,我没有看到解决JavaFX中这个问题的简单方法.