Imprimindo com atributos (Controle de Bandeja, Duplex, etc…) usando a biblioteca javax.print

Eu tenho tentado por algum tempo para determinar uma maneira de usar obiblioteca padrão de impressão Java para imprimir arquivos - especificamente, documentos PDF - comcertos atributos - especificamente, para determinadas bandejas ou usando duplex.

Existe muita documentação sobre como isso deve ser feito e, de fato, pesquisei e experimentei esses métodos. A maneira típica é algo assim:

public static void main (String [] args) {
    try {

        PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);

        //Acquire Printer
        PrintService printer = null;
        for (PrintService serv: pservices) {
            System.out.println(serv.toString());
            if (serv.getName().equals("PRINTER_NAME_BLAH")) {
                printer = serv;
            }
        }

        if (printer != null) {
            System.out.println("Found!");


            //Open File
            FileInputStream fis = new FileInputStream("FILENAME_BLAH_BLAH.pdf");

            //Create Doc out of file, autosense filetype
            Doc pdfDoc = new SimpleDoc(fis, DocFlavor.INPUT_STREAM.AUTOSENSE, null);

            //Create job for printer
            DocPrintJob printJob = printer.createPrintJob();

            //Create AttributeSet
            PrintRequestAttributeSet pset = new HashPrintRequestAttributeSet();

            //Add MediaTray to AttributeSet
            pset.add(MediaTray.TOP);

            //Add Duplex Option to AttributeSet
            pset.add(Sides.DUPLEX);

            //Print using Doc and Attributes
            printJob.print(pdfDoc, pset);

            //Close File
            fis.close();

        }

    }
    catch (Throwable t) {
        t.printStackTrace();
    }
}

Em suma, você faz o seguinte

Encontre a impressoraCrie um PrinterJobCrie um AttributeSetAdicionar Atributos ao AttributeSet, como Bandeja e DuplexChame a impressão no trabalho da impressora usando o AttributeSet

O problema aqui é que, apesar de ser a maneira documentada de fazer isso, bem como o que eu encontrei de vários tutoriais, esse método ...não funciona. Agora lembre-se, eu sei que isso não soa muito descritivo, mas me ouça.Eu não digo isso levemente...

A documentação oficial do PrinterJob Na verdade, menciona que o AttributeSet é ignorado na implementação padrão.Código fonte visto aqui mostra que isso é verdade - os atributos são passados ​​e ignorados inteiramente.

Então, aparentemente, você precisa de algum tipo de versão estendida da classe, que é possivelmente baseada nas impressoras específicas e suas capacidades? Eu tentei escrever algum código de teste que me diria tais capacidades - nós temos uma grande variedade de impressoras configuradas no escritório, grandes ou pequenas, simples ou cheias de sinos e assobios - para não mencionar vários drivers no meu computador apenas para pseudo Drivers de impressoras que apenas criam documentos e simulam impressoras sem precisar de nenhum tipo de hardware. O código de teste é o seguinte:

public static void main (String [] args) {

    PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);

    for (PrintService serv: pservices) {
        System.out.println(serv.toString());

        printFunctionality(serv, "Trays", MediaTray.class);
        printFunctionality(serv, "Copies", Copies.class);
        printFunctionality(serv, "Print Quality", PrintQuality.class);
        printFunctionality(serv, "Color", ColorSupported.class);
        printFunctionality(serv, "Media Size", MediaSize.class);
        printFunctionality(serv, "Accepting Jobs", PrinterIsAcceptingJobs.class);
    }
}

private static void printFunctionality(PrintService serv, String attrName, Class<? extends Attribute> attr) {
    boolean isSupported = serv.isAttributeCategorySupported(attr);
    System.out.println("    " + attrName + ": " + (isSupported ? "Y" : "N"));
}

Os resultados que encontrei foram que todas as impressoras, sem exceção, retornaram que "cópias" eram suportadas e todos os outros atributos não eram. Além disso, todos os recursos da impressora eram idênticos, independentemente de quão implausível isso pudesse parecer.

A questão inevitável é multi-camadas: como alguém envia atributos de uma maneira que eles são registrados? Além disso, como se detecta adequadamente os recursos de uma impressora? De fato, a classe PrinterJob é realmente estendida de uma maneira utilizável, ou os atributos são sempre ignorados?

Exemplos que eu encontrei em toda a Internet parecem sugerir que a resposta para a última questão é "Não, eles são sempre ignorados", o que parece ridículo para mim (mas cada vez mais mais crível à medida que vasculho centenas de páginas).É este código que a Sun simplesmente configurou, mas nunca funcionou para um estado completo? Se então,Existem alternativas?

questionAnswers(4)

yourAnswerToTheQuestion