Drukowanie za pomocą atrybutów (kontrola tacy, dupleks itp.) Za pomocą biblioteki javax.print

Od jakiegoś czasu próbuję określić sposób użyciastandardowa biblioteka Java Print do drukowania plików - w szczególności dokumentów PDF - za pomocąpewne atrybuty - w szczególności do niektórych tac lub przy użyciu dupleksu.

Istnieje wiele dokumentacji na temat tego, jak należy to zrobić, i rzeczywiście, zbadałem i wypróbowałem te metody. Typowy sposób to coś takiego:

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();
    }
}

Krótko mówiąc, robisz co następuje

Znajdź drukarkęUtwórz drukarkęUtwórz zestaw atrybutówDodaj atrybuty do zestawu atrybutów, takie jak taca i dupleksWywołaj drukowanie w zadaniu drukarki za pomocą AttributeSet

Problem polega na tym, że pomimo udokumentowanego sposobu wykonania tego, a także tego, co znalazłem w kilku samouczkach, ta metoda ...nie działa. Teraz pamiętajcie, wiem, że to nie brzmi bardzo dobrze, ale wysłuchajcie mnie.Nie mówię tego lekko...

Oficjalna dokumentacja dla PrinterJob faktycznie wspomina, że ​​AttributeSet jest ignorowany w domyślnej implementacji.Kod źródłowy widoczny tutaj pokazuje, że to prawda - atrybuty są przekazywane i ignorowane w całości.

Więc najwyraźniej potrzebujesz jakiejś rozszerzonej wersji klasy, która może być oparta na konkretnych drukarkach i ich możliwościach? Próbowałem napisać kod testowy, który powiedziałby mi takie możliwości - mamy dużą liczbę drukarek ustawionych w biurze, dużych lub małych, prostych lub pełnych dzwonków i gwizdków - nie wspominając o kilku sterownikach na moim komputerze tylko dla pseudo - sterowniki drukarki, które po prostu tworzą dokumenty i symulują drukarki bez przechodzenia do jakiegokolwiek sprzętu. Kod testu jest następujący:

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"));
}

Odkryłem, że każda drukarka, bez wyjątku, zwracała, że ​​„kopie” były obsługiwane, a wszystkie inne atrybuty nie. Ponadto możliwości każdej drukarki były identyczne, niezależnie od tego, jak mało prawdopodobne wydaje się to.

Nieuniknione pytanie jest wielowarstwowe: jak wysyłać atrybuty w sposób, w jaki są zarejestrowane? Dodatkowo, w jaki sposób prawidłowo wykryć możliwości drukarki? Rzeczywiście, czy klasa PrinterJob faktycznie została rozszerzona w użyteczny sposób, czy też atrybuty są zawsze ignorowane?

Przykłady, które znalazłem w Internecie Wydaje mi się, że odpowiedź na to drugie pytanie brzmi: „Nie, zawsze są ignorowane”, co wydaje mi się śmieszne (ale coraz bardziej wiarygodne, gdy przeglądam setki stron).Czy ten kod, który Sun po prostu skonfigurował, ale nigdy nie działał do stanu ukończonego? W takim razie,czy są jakieś alternatywy?

questionAnswers(4)

yourAnswerToTheQuestion