【问题标题】:Java Printing Tray Selection SagaJava 打印托盘选择传奇
【发布时间】:2015-11-30 12:36:06
【问题描述】:

虽然有几个关于托盘选择的问题,但没有一个与我的问题有关。

这是我用来打印的代码:

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 全局打印机驱动程序而不是特定打印机驱动程序,则一切正常。我将留下未回答的问题,看看是否有人能在赏金到期之前提出一个好的解释,然后我将把这个编辑放在一个答案中并接受它。

【问题讨论】:

  • 来自异常等的日志可能是你的“灯”......这段代码几乎不可能为来自 SO 的人进行测试
  • 就是这样,没有例外。该设置会被忽略。
  • 我喜欢异常名称BigBangJewelException,但这样做毫无意义:throw new BigBangJewelException(e.getMessage(), e);。只需省略第一个参数。
  • 你的调试器说什么?如果调试很困难或不可能,您可以添加一些日志代码来找出发生了什么。 (我的猜测是 getTray() 方法开始返回 null - 也许对字符串内容的期望不成立?)
  • 不,你没有抓住重点。该代码有效。正确选择了纸盘并正确发送到打印作业。打印机本身(曾经)忽略它。问题中有其他信息。

标签: java printing tray


【解决方案1】:

如果我没听错的话,你lobjSet的内容没有改变,但打印结果不同,安装了新的驱动程序。

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

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

【讨论】:

  • 这听起来是个好主意,但不幸的是,这只发生在生产机器上,我无法调试它。我确实看过你提到的代码,确实很长。 +1 花时间看它。
  • 好吧,我不希望这笔赏金白白浪费,而且看起来没有人会想出更好的东西,所以,试试吧。 :)
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 2012-06-28
    相关资源
    最近更新 更多