Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8040273

PrinterJob.printDialog() returns false if null default Windows printer

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 7u40
    • client-libs
    • 2d
    • windows_7

      FULL PRODUCT VERSION :
      C:\Users\jhebert>java -version
      java version "1.7.0_40"
      Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
      Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      C:\Users\jhebert>ver

      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      If there is no default Windows printer set, printing through Java using PrinterJob.printDialog() to always returns false whether the user clicks on print or cancel which will cause the print to be considered as cancelled.

      This contradicts the documentation for PrinterJob.printDialog(), which states that printDialog() should only return false if the user clicks cancel.

      Printing through non Java applications in Windows still function with a null Windows default printer.

      REGRESSION. Last worked in version 7u40

      ADDITIONAL REGRESSION INFORMATION:
      C:\Users\jhebert>java -version
      java version "1.7.0_40"
      Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
      Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      This problem can be reproduced by setting the following registry entry to null to simulate having no default Windows printer selected (registry entry's exactly location will depend on version of Windows):

      [HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows]

      Set "Device"="null???


      Once this is done, any previously selected default Windows printer will be cleared.


      This can occur organically in a Citrix environment if a Java application is opened on two Citrix sessions using the same Citrix blade because the the second time logging into Citrix will clear any default preferences, leaving them with null values.


      Once the default Windows printer has been cleared, calling the following code will behave unexpectedly:

      PrinterJob pJob = PrinterJob.getPrinterJob();

      PrintService[] services = PrinterJob.lookupPrintServices(); // This returns the list of valid and available printers

      PrintService printer = pJob.getPrintService(); // Printer will be null the default Windows printer is null

      print = pJob.printDialog(); // print will be false regardless of whether user click print or cancel in the print dialog

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I had expected pJob.printDialog() to return true when the user clicked on print.

      The documentation for java.awt.print.PrinterJob.printDialog() says that it only returns false when the user clicks on cancel, which is not what I found.
      ACTUAL -
      pJob.printDialog() returned false when the user clicked on print or on cancel.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class TestPrint {

          /**
           * @param args the command line arguments
           */
          public static void main( String[] args ) {
              System.out.println( "TestPrint1 Result: " + testPrint1() );
              System.out.println( "TestPrint2 Result: " + testPrint2() );
          }

          private static boolean testPrint1() {
              PrinterJob pJob = PrinterJob.getPrinterJob();
              PrintService printer = pJob.getPrintService(); // Printer will be null the default Windows printer is null
              boolean print = pJob.printDialog(); // print will be false regardless of whether user click print or cancel

              return print;
          }

          private static boolean testPrint2() {
              PrinterJob pJob = PrinterJob.getPrinterJob();
              if ( pJob.getPrintService() == null ) { // If null print service, set the print service to first available printer
                  setPrintServiceToFirstPrinter( pJob );
              }
              boolean print = pJob.printDialog(); // print will now return true if the user clicks print

              return print;

          }

          private static void setPrintServiceToFirstPrinter( PrinterJob job ) {
              try {
                  PrintService[] services = PrinterJob.lookupPrintServices();

                  if ( services.length > 0 ) {
                      job.setPrintService( services[0] );
                  }
              } catch ( Exception e ) {
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      If the print service is null, set the print service to any available service before using the PrinterJob.
      Once the print service is set, printDialog will return true when the user clicks on Print.

      This is what I did in testPrint2() in the above source code.

            prr Philip Race
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: