--- old/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2016-09-01 14:28:31.675882400 +0530 +++ new/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2016-09-01 14:28:31.178882400 +0530 @@ -30,7 +30,6 @@ import java.awt.Color; import java.awt.Dialog; import java.awt.Frame; -import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; @@ -39,7 +38,6 @@ import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; -import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -55,7 +53,6 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Enumeration; import java.util.Locale; import sun.awt.image.ByteInterleavedRaster; @@ -74,7 +71,6 @@ import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.ResolutionSyntax; import javax.print.attribute.Size2DSyntax; -import javax.print.attribute.standard.Chromaticity; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.DialogTypeSelection; @@ -96,11 +92,6 @@ import javax.print.attribute.standard.SheetCollate; import javax.print.attribute.standard.Sides; -import sun.print.PageableDoc; -import sun.print.ServiceDialog; -import sun.print.SunPrinterJobService; -import sun.print.SunPageSelection; - /** * A class which rasterizes a printer job. * @@ -836,9 +827,16 @@ Rectangle gcBounds = gc.getBounds(); int x = gcBounds.x+50; int y = gcBounds.y+50; - ServiceDialog pageDialog = new ServiceDialog(gc, x, y, service, - DocFlavor.SERVICE_FORMATTED.PAGEABLE, - attributes, (Frame)null); + ServiceDialog pageDialog; + if (w instanceof Frame) { + pageDialog = new ServiceDialog(gc, x, y, service, + DocFlavor.SERVICE_FORMATTED.PAGEABLE, + attributes,(Frame)w); + } else { + pageDialog = new ServiceDialog(gc, x, y, service, + DocFlavor.SERVICE_FORMATTED.PAGEABLE, + attributes, (Dialog)w); + } Rectangle dlgBounds = pageDialog.getBounds(); // if portion of dialog is not within the gc boundary @@ -944,6 +942,14 @@ Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); if (w != null) { grCfg = w.getGraphicsConfiguration(); + /* Add DialogOwner attribute to set the owner of this print dialog + * only if it is not set already + * (it might be set in java.awt.PrintJob.printDialog) + */ + if (attributes.get(DialogOwner.class) == null) { + attributes.add(w instanceof Frame ? new DialogOwner((Frame)w) : + new DialogOwner((Dialog)w)); + } } else { grCfg = GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice().getDefaultConfiguration(); @@ -1013,8 +1019,9 @@ DocFlavor.SERVICE_FORMATTED.PAGEABLE, attributes); } - attributes.remove(PrinterJobWrapper.class); - + attributes.remove(PrinterJobWrapper.class); + attributes.remove(DialogOwner.class); + if (newService == null) { return false; } @@ -1426,7 +1433,7 @@ * @see java.awt.print.Pageable * @see java.awt.print.Printable */ - public void print() throws PrinterException { + public void print() throws PrinterException { print(attributes); } --- old/src/java.desktop/share/classes/sun/print/DialogOwner.java 2016-09-01 14:28:34.512882400 +0530 +++ new/src/java.desktop/share/classes/sun/print/DialogOwner.java 2016-09-01 14:28:34.026882400 +0530 @@ -25,9 +25,11 @@ package sun.print; +import java.awt.Dialog; import javax.print.attribute.Attribute; import javax.print.attribute.PrintRequestAttribute; import java.awt.Frame; +import java.awt.Window; /** * Class DialogOwner is a printing attribute class that identifies @@ -42,7 +44,7 @@ public final class DialogOwner implements PrintRequestAttribute { - private Frame dlgOwner; + private Window dlgOwner; /** * Construct a new dialog owner attribute with the given frame. @@ -53,11 +55,19 @@ dlgOwner = frame; } + /** + * Construct a new dialog owner attribute with the given dialog. + * + * @param dialog the dialog that owns the print dialog + */ + public DialogOwner(Dialog dialog) { + dlgOwner = dialog; + } /** * Returns the string table for class DialogOwner. */ - public Frame getOwner() { + public Window getOwner() { return dlgOwner; } --- old/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java 2016-09-01 14:28:37.135882400 +0530 +++ new/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java 2016-09-01 14:28:36.621382400 +0530 @@ -478,9 +478,12 @@ } DialogOwner dlgOwner = (DialogOwner)attributes.get(DialogOwner.class); - Frame ownerFrame = (dlgOwner != null) ? dlgOwner.getOwner() : null; + Window owner = (dlgOwner != null) ? dlgOwner.getOwner() : null; - WPrintDialog dialog = new WPrintDialog(ownerFrame, this); + WPrintDialog dialog = (owner instanceof Frame) ? + new WPrintDialog((Frame)owner, this) : + new WPrintDialog((Dialog)owner, this); + dialog.setRetVal(false); dialog.setVisible(true); boolean prv = dialog.getRetVal(); @@ -498,9 +501,10 @@ title = rb.getString("dialog.printtofile"); } catch (MissingResourceException e) { } - FileDialog fileDialog = new FileDialog(ownerFrame, title, - FileDialog.SAVE); - + FileDialog fileDialog = (owner instanceof Frame) ? + new FileDialog((Frame)owner, title, FileDialog.SAVE) : + new FileDialog((Dialog)owner, title, FileDialog.SAVE); + URI destURI = dest.getURI(); // Old code destURI.getPath() would return null for "file:out.prn" // so we use getSchemeSpecificPart instead. @@ -531,10 +535,17 @@ ((pFile != null) && (!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) { - (new PrintToFileErrorDialog(ownerFrame, + if (owner instanceof Frame) { + (new PrintToFileErrorDialog((Frame)owner, + ServiceDialog.getMsg("dialog.owtitle"), + ServiceDialog.getMsg("dialog.writeerror")+" "+fullName, + ServiceDialog.getMsg("button.ok"))).setVisible(true); + } else { + (new PrintToFileErrorDialog((Dialog)owner, ServiceDialog.getMsg("dialog.owtitle"), ServiceDialog.getMsg("dialog.writeerror")+" "+fullName, ServiceDialog.getMsg("button.ok"))).setVisible(true); + } fileDialog.setVisible(true); fileName = fileDialog.getFile(); --- /dev/null 2016-09-01 14:28:39.000000000 +0530 +++ new/test/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java 2016-09-01 14:28:39.249382400 +0530 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 7064425 6948907 + * @summary Verifies if owner Frame is associated with page dialog of PrinterJob + * @run main/manual TestPageDlgFrameAssociation + */ +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +public class TestPageDlgFrameAssociation { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static Button print; + private static Label dialogName; + private static Frame frame; + private static boolean start; + private static Thread t; + + public static void main(String args[]) throws Exception { + SwingUtilities.invokeAndWait(() -> { + doTest(TestPageDlgFrameAssociation::frameTest); + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("Page dialog not disposed." + + " Page dialog is not associated with owner Frame`"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + private static void frameTest() { + Panel panel =new Panel(); + + print = new Button("PageDialog"); + print.setActionCommand("PageDialog"); + print.addActionListener((e) -> { + PrinterJob job = PrinterJob.getPrinterJob(); + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + t.start(); + start = true; + PageFormat pf = job.pageDialog(aset); + }); + + panel.add(print); + + frame = new Frame("Test Frame"); + frame.setLayout (new BorderLayout ()); + frame.add(panel,"South"); + frame.pack(); + frame.setVisible(true); + + t = new Thread (() -> { + if (start) { + try { + Thread.sleep(5000); + } catch (InterruptedException ex) {} + frame.dispose(); + } + }); + } + + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A Frame with PageDialog Button is shown. Press PageDialog.\n" + + " A page dialog will be shown. Do not press any button.\n" + + " After 5 secs the frame along with this page dialog will be disposed.\n" + + " If the page dialog is not disposed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + + } +} --- /dev/null 2016-09-01 14:28:42.000000000 +0530 +++ new/test/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java 2016-09-01 14:28:41.305882400 +0530 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 7064425 6948907 + * @summary Verifies if owner Frame is associated with print dialog of PrinterJob + * @run main/manual TestPrintDlgFrameAssociation + */ +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.print.PrinterJob; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +public class TestPrintDlgFrameAssociation { + private static Thread mainThread; + private static boolean testPassed; + private static boolean testGeneratedInterrupt; + private static Button print; + private static Label dialogName; + private static Frame frame; + private static boolean start; + private static Thread t; + + public static void main(String args[]) throws Exception { + SwingUtilities.invokeAndWait(() -> { + doTest(TestPrintDlgFrameAssociation::frameTest); + }); + mainThread = Thread.currentThread(); + try { + Thread.sleep(60000); + } catch (InterruptedException e) { + if (!testPassed && testGeneratedInterrupt) { + throw new RuntimeException("Print dialog not disposed." + + " Print dialog is not associated with owner Frame`"); + } + } + if (!testGeneratedInterrupt) { + throw new RuntimeException("user has not executed the test"); + } + } + + private static void frameTest() { + Panel panel =new Panel(); + + print = new Button("PrintDialog"); + print.setActionCommand("PrintDialog"); + print.addActionListener((e) -> { + PrinterJob job = PrinterJob.getPrinterJob(); + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + t.start(); + start = true; + job.printDialog(aset); + }); + + panel.add(print); + + frame = new Frame("Test Frame"); + frame.setLayout (new BorderLayout ()); + frame.add(panel,"South"); + frame.pack(); + frame.setVisible(true); + + t = new Thread (() -> { + if (start) { + try { + Thread.sleep(5000); + } catch (InterruptedException ex) {} + frame.dispose(); + } + }); + } + + + public static synchronized void pass() { + testPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + public static synchronized void fail() { + testPassed = false; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } + + private static void doTest(Runnable action) { + String description + = " A Frame with PrintDialog Button is shown. Press PrintDialog.\n" + + " A print dialog will be shown. Do not press any button.\n" + + " After 5 secs the frame along with this print dialog will be disposed.\n" + + " If the print dialog is not disposed, press FAIL else press PASS"; + + final JDialog dialog = new JDialog(); + dialog.setTitle("printSelectionTest"); + JTextArea textArea = new JTextArea(description); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + action.run(); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("main dialog closing"); + testGeneratedInterrupt = false; + mainThread.interrupt(); + } + }); + + } +}