Java 打印托盘选择传奇

Java Printing Tray Selection Saga

虽然有几个关于托盘选择的问题,none 其中与我的问题有关。

这是我用来打印的代码:

private static void finalPrint(PDDocument pdoc, boolean pbStationary)
    throws BigBangJewelException
{
    PrintService lrefSvc;
    PrinterJob lrefPJob;
    Media lrefMedia;
    HashPrintRequestAttributeSet lobjSet;

    lrefSvc = getPrinter();

    lrefPJob = PrinterJob.getPrinterJob();

    try
    {
        lrefPJob.setPrintService(lrefSvc);
        lrefPJob.setPageable(pdoc);

        lrefMedia = null;
        if ( pbStationary )
            lrefMedia = getTray(lrefSvc);
        if ( lrefMedia != null )
        {
            lobjSet = new HashPrintRequestAttributeSet();
            lobjSet.add(lrefMedia);
            lrefPJob.print(lobjSet);
        }
        else
            lrefPJob.print();
    }
    catch (Throwable e)
    {
        throw new BigBangJewelException(e.getMessage(), e);
    }
}

private static PrintService getPrinter()
    throws BigBangJewelException
{
    String lstrPrinter;
    PrintService[] larrServices;
    int i;

    try
    {
        lstrPrinter = (String)Engine.getUserData().get("Printer");

        larrServices = PrinterJob.lookupPrintServices();

        for ( i = 0; i < larrServices.length; i++ )
        {
            if (larrServices[i].getName().indexOf(lstrPrinter) != -1)
                return larrServices[i];
        }
    }
    catch (Throwable e)
    {
        throw new BigBangJewelException(e.getMessage(), e);
    }

    throw new BigBangJewelException("Impressora definida (" + lstrPrinter + ") não encontrada.");
}

private static Media getTray(PrintService prefSvc)
{
    Media[] larrMedia;
    String lstrAux;
    int i;

    larrMedia = (Media[])prefSvc.getSupportedAttributeValues(Media.class, null, null);

    if ( larrMedia == null )
        return null;

    for ( i = 0; i < larrMedia.length; i++ )
    {
        lstrAux = larrMedia[i].toString().toLowerCase();
        if (lstrAux.contains("tray") && lstrAux.contains("3"))
        {
            return larrMedia[i];
        }
    }

    return null;
}

令人困惑的是,这段代码曾经有效。这台机器定义了一堆 Xerox 打印机,代码可以正确识别所需的打印机和所需的托盘,一切都运行良好。

然后,有一天,一夜之间,它停止工作了。它仍然找到正确的打印机,但现在,它总是打印到纸盘 1。

唯一改变的是机器上增加了一台额外的 HP 打印机。

我可以确认代码正在找到托盘并将其发送到打印作业,但它被忽略了。

同样,关于这个问题有很多问题,但我的问题是代码运行良好了四年,然后无故停止工作。

任何人都可以阐明这个主题吗?

编辑: 新信息:卸载 HP 打印机使 Xerox 打印机再次正常工作。为什么安装一个驱动程序会影响 Java 与其他驱动程序通信的能力?

编辑 2: 更多信息:如果我们安装 HP 全局打印机驱动程序而不是特定的打印机驱动程序,则一切正常。我将不回答这个问题,看看是否有人能在赏金到期前提出一个好的解释,然后我将把这个编辑放在一个答案中并接受它。

如果我没问错的话,你lobjSet的内容没变,只是打印结果不一样,安装了新的驱动

我检查了 PnterJob.print(PrintRequestAttributeSet) 的代码,惊讶地发现它完全忽略了属性集。

所以我查看了 PrintService 的来源,代码有点冗长,但我猜它以某种方式与已安装的打印机驱动程序交互以创建适当的实例。所以新的驱动程序改变了这个,返回一个不同的 PrintService。我无法说出这件事究竟以何种方式发生了变化,但如果您可以重新创建这两种情况(而且看起来您可以),那么使用调试器找到代码行为的确切位置应该相当容易变化。

我们的特殊情况的解决方案是更改 HP 打印机的打印机驱动程序。

最初,我们为有问题的打印机安装了特定的驱动程序,这导致了此行为。安装 HP 的全局驱动程序使问题消失。

不幸的是,我们不知道为什么。 Jens Schauder 的回答包含有关如何找出答案的线索。