JDK-4507585 : PrinterJob dialogs cause redraw problems for Swing GUIs.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version:
    1.2.0,1.3.0,1.3.1,1.3.1_01,1.4.0,1.4.1,1.4.2 1.2.0,1.3.0,1.3.1,1.3.1_01,1.4.0,1.4.1,1.4.2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,windows_nt,windows_2000,windows_xp generic,windows_nt,windows_2000,windows_xp
  • CPU: x86,sparc
  • Submitted: 2001-09-26
  • Updated: 2003-10-23
  • Resolved: 2003-10-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b26Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description

Name: yyT116575			Date: 09/26/2001


D:\inferno>java -version
java version "1.3.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_01)
Java HotSpot(TM) Client VM (build 1.3.1_01, mixed mode)

Calling printDialog() or pageDialog() on a java.awt.print.PrinterJob yields
dialogs which when dragged do not trigger redraws of obscured Swing components
of that application. This looks terrible. Additionally these dialogs should
behave like normal modal dialogs but do not, i.e., they fall behind the
application's window and don't block interactions with the application's frame.

This testcase demonstrates the problem. In this example the main window is
small, but keep in mind that in reality it would be a full application.
Run the testcase and click on either the Print or Page Setup buttons and note
the following bugs.
Note that when either dialog comes up the main window no longer redraws as it
should.
Further note that the dialogs' modalities are strange--neither modal nor
modaless. For example, the dialog is allowed to fall behind the main window and
you can click on the main window's Minimize, Maximize and Close buttons.
The correct behavior of Print and Page Setup dialogs (and of modal dialogs in
general) is demonstrated in any Windows application, e.g., Notepad.exe. Note
that in these applications modal dialogs are completely blocking but allow the
application to continue to redraw its UI.

/*
 * A testcase to demonstrate redraw problems caused by PrinterJob dialogs.
 */
package buggy;

import java.awt.*;
import java.awt.print.*;
import java.awt.event.*;
import javax.swing.*;

public class Testcase extends JPanel {
  static JFrame m_frame;

  public Testcase() {
    JButton printBtn = new JButton("Print...");
    JButton pageBtn = new JButton("Page Setup...");

    printBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.printDialog();
      }
    });

    pageBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.pageDialog(job.defaultPage());
      }
    });

    add(printBtn, BorderLayout.CENTER);
    add(pageBtn, BorderLayout.CENTER);
  }

  public static void main(String str[]) {
    Testcase panel = new Testcase();
    m_frame = new JFrame("Testcase");
    m_frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);}
      });
    m_frame.getContentPane().add("Center", panel);
    m_frame.setLocation(200, 200);
    panel.setPreferredSize(new Dimension(200, 200));
    m_frame.pack();
    m_frame.setVisible(true);
  }
}
(Review ID: 132605) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger tiger-beta FIXED IN: tiger tiger-beta INTEGRATED IN: tiger-b26 tiger-beta
24-08-2004

EVALUATION If this is still reproducible in Tiger, we should fix it for that release. ###@###.### 2001-09-26 Name: atR10251 Date: 09/18/2003 PageSetup dialog is a native modal dialog. When it's displayed on EventDispatchThread it blocks the event pump. java.awt.Dialog solves this problem by starting new event pump. PrintDialog was fixed so that it is shown as if java.awt.Dialog is shown (really the native dialog is shown on another thread and new event pump is started on EventDispatchThread). So it's better to fix PageDialog in the same way. ====================================================================== I'll commit this to Tiger based on developer demand for the fix. ###@###.### 2003-09-26
26-09-2003

SUGGESTED FIX Name: atR10251 Date: 09/19/2003 ------- WPageDialog.java ------- /* * %W% %E% * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package sun.awt.windows; import java.awt.Frame; import java.awt.Toolkit; import java.awt.peer.ComponentPeer; import java.awt.print.PrinterJob; import java.awt.print.PageFormat; import java.awt.print.Printable; public class WPageDialog extends WPrintDialog { PageFormat page; Printable painter; WPageDialog(Frame parent, PrinterJob control, PageFormat page, Printable painter) { super(parent, control); this.page = page; this.painter = painter; } public void addNotify() { synchronized(getTreeLock()) { if (getPeer() == null) { ComponentPeer peer = ((WToolkit)Toolkit.getDefaultToolkit()). createWPageDialog(this); setPeer(peer); } super.addNotify(); } } } ------- WPageDialogPeer.java ------- /* * %W% %E% * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package sun.awt.windows; public class WPageDialogPeer extends WPrintDialogPeer { WPageDialogPeer(WPageDialog target) { super(target); } public void show() { new Thread(new Runnable() { public void run() { WPageDialog pdlg = (WPageDialog)target; WPrinterJob pjob = (WPrinterJob)pdlg.pjob; // Call pageSetup even with no printer installed, this // will display Windows error dialog and return false. ((WPrintDialog)target).setRetVal(pjob.pageSetup(pdlg.page, pdlg.painter)); ((WPrintDialog)target).hide(); } }).start(); } } ------- WPrintDialog.java ------- *** /tmp/sccs.9HaabM Fri Sep 19 11:07:25 2003 --- WPrintDialog.java Thu Sep 18 14:30:40 2003 *************** *** 15,35 **** public class WPrintDialog extends Dialog { static { initIDs(); } ! private PrintJob job; ! private PrinterJob pjob; public WPrintDialog(Frame parent, PrinterJob control) { super(parent, true); this.pjob = control; setLayout(null); } // Use native code to circumvent access restrictions on Component.peer ! private native void setPeer(ComponentPeer peer); public void addNotify() { synchronized(getTreeLock()) { Container parent = getParent(); if (parent != null && parent.getPeer() == null) { --- 15,35 ---- public class WPrintDialog extends Dialog { static { initIDs(); } ! protected PrintJob job; ! protected PrinterJob pjob; public WPrintDialog(Frame parent, PrinterJob control) { super(parent, true); this.pjob = control; setLayout(null); } // Use native code to circumvent access restrictions on Component.peer ! protected native void setPeer(ComponentPeer peer); public void addNotify() { synchronized(getTreeLock()) { Container parent = getParent(); if (parent != null && parent.getPeer() == null) { ------- WPrinterJob.java ------- *** /tmp/sccs.GSa4jM Fri Sep 19 11:07:25 2003 --- WPrinterJob.java Thu Sep 18 15:13:32 2003 *************** *** 398,411 **** if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } PrintService service = getPrintService(); PageFormat pageClone = (PageFormat) page.clone(); ! // Call pageSetup even with no printer installed, this ! // will display Windows error dialog and return false. ! boolean doIt = pageSetup(pageClone, null); ! if (doIt && (service != null)) { // Update attributes, this will preserve the page settings. // - same code as in RasterPrinterJob.java updatePageAttributes(service, pageClone); return pageClone; --- 398,426 ---- if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } PrintService service = getPrintService(); PageFormat pageClone = (PageFormat) page.clone(); ! boolean result = false; ! ! /* ! * Fix for 4507585: show the native modal dialog the same way printDialog() does so ! * that it won't block event dispatching when called on EventDispatchThread. ! */ ! dialogOwner = new Frame(); ! if (dialogOwner != null) { ! dialogOwnerPeer = ! (java.awt.peer.ComponentPeer)dialogOwner.getPeer(); ! ! WPageDialog dialog = new WPageDialog(dialogOwner, this, pageClone, null); ! dialog.setRetVal(false); ! dialog.show(); ! result = dialog.getRetVal(); ! dialogOwner.dispose(); ! } ! ! if (result && (service != null)) { // Update attributes, this will preserve the page settings. // - same code as in RasterPrinterJob.java updatePageAttributes(service, pageClone); return pageClone; ------- WToolkit.java ------- *** /tmp/sccs.1wai4L Fri Sep 19 11:07:24 2003 --- WToolkit.java Thu Sep 18 15:24:18 2003 *************** *** 439,448 **** --- 439,454 ---- WPrintDialogPeer peer = new WPrintDialogPeer(target); targetCreatedPeer(target, peer); return peer; } + WPageDialogPeer createWPageDialog(WPageDialog target) { + WPageDialogPeer peer = new WPageDialogPeer(target); + targetCreatedPeer(target, peer); + return peer; + } + protected native void setDynamicLayoutNative(boolean b); public void setDynamicLayout(boolean b) { if (b == dynamicLayoutSetting) { return; ###@###.### 2003-09-19 ======================================================================
19-09-2003