--- /dev/null 2018-05-25 11:37:39.280540387 -0700 +++ new/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java 2018-06-05 12:26:16.496041896 -0700 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2018, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.print.attribute.standard; + +import java.awt.Window; +import javax.print.attribute.Attribute; +import javax.print.attribute.PrintRequestAttribute; +import sun.print.DialogOwnerAccessor; + +/** + * An attribute class used to support requesting a print or page setup dialog + * be kept displayed on top of all windows or some specific window. + *

+ * Constructed without any arguments it will request that a print or page + * setup dialog be configured as if the application directly was to specify + * {@code java.awt.Window.setAlwaysOnTop(true)}, subject to permission checks. + *

+ * Constructed with a {@link java.awt.Window} parameter, it requests that + * the dialog be owned by the specified window. + * + * @since 11 + */ +public final class DialogOwner implements PrintRequestAttribute { + + private static class Accessor extends DialogOwnerAccessor { + + public long getOwnerID(DialogOwner owner) { + return owner.getID(); + } + } + + static private Accessor accessor = new Accessor(); + static { + DialogOwnerAccessor.setAccessor(accessor); + } + + private static final long serialVersionUID = -1901909867156076547L; + + private Window owner; + private transient long id; + + /** + * Constructs an instance which can be used to request + * {@code java.awt.Window.setAlwaysOnTop(true)} behaviour. + * This should be used where there is no application preferred owner window. + * Whether this has any effect depends on if always on top is supported + * for this platform and the particular dialog to be displayed. + */ + public DialogOwner() { + } + + /** + * Constructs an instance which can be used to request that the + * specified {@link java.awt.Window} be the owner of the dialog. + * @param owner window. + */ + public DialogOwner(Window owner) { + this.owner = owner; + } + + /** + * Constructs an instance which requests that the dialog be displayed + * as if it were a child of a native platform window, specified + * using its opqaue platform identifier or handle. + * This is useful mainly for the case where the id represents a window + * which may not be an AWT {@code Window}, but instead was created by + * another UI toolkit, such as OpenJFX. + * Any effect is platform dependent. + * @param id a native window identifier or handle + */ + DialogOwner(long id) { + this.id = id; + } + + /** + * Returns a native platform id or handle, if one was specified, + * otherwise, zero. + * @return a native platform id. + */ + long getID() { + return id; + } + + /** + * Returns a {@code Window owner}, if one was specified, + * otherwise {@code null}. + * @return an owner window. + */ + public Window getOwner() { + return owner; + } + + /** + * Get the printing attribute class which is to be used as the "category" + * for this printing attribute value. + *

+ * For class {@code DialogOwner}, the category is class + * {@code DialogOwner} itself. + * + * @return printing attribute class (category), an instance of class + * {@link Class java.lang.Class} + */ + public final Class getCategory() { + return DialogOwner.class; + } + + /** + * Get the name of the category of which this attribute value is an + * instance. + *

+ * For class {@code DialogOwner}, the category name is + * {@code "dialog-owner"}. + * + */ + public final String getName() { + return "dialog-owner"; + + } +} --- /dev/null 2018-05-25 11:37:39.280540387 -0700 +++ new/src/java.desktop/share/classes/sun/print/DialogOwnerAccessor.java 2018-06-05 12:26:16.996041877 -0700 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.print; + +import javax.print.attribute.standard.DialogOwner; + +public abstract class DialogOwnerAccessor { + + public abstract long getOwnerID(DialogOwner owner); + + public static DialogOwnerAccessor accessor = null; + + public static void setAccessor(DialogOwnerAccessor acc) { + accessor = acc; + } + + public static long getID(DialogOwner owner) { + if (accessor == null || owner == null) { + return 0; + } else { + return accessor.getOwnerID(owner); + } + } +} --- old/src/java.desktop/share/classes/javax/print/ServiceUI.java 2018-06-05 12:26:17.764041847 -0700 +++ new/src/java.desktop/share/classes/javax/print/ServiceUI.java 2018-06-05 12:26:17.500041857 -0700 @@ -35,11 +35,11 @@ import javax.print.attribute.Attribute; import javax.print.attribute.AttributeSet; +import javax.print.attribute.standard.DialogOwner; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.Fidelity; -import sun.print.DialogOwner; import sun.print.ServiceDialog; import sun.print.SunAlternateMedia; @@ -185,6 +185,7 @@ DialogOwner dlgOwner = (DialogOwner)attributes.get(DialogOwner.class); Window owner = (dlgOwner != null) ? dlgOwner.getOwner() : null; + boolean setOnTop = (dlgOwner != null) && (owner == null); Rectangle gcBounds = (gc == null) ? GraphicsEnvironment. getLocalGraphicsEnvironment().getDefaultScreenDevice(). @@ -208,6 +209,12 @@ flavor, attributes, (Dialog)owner); } + if (setOnTop) { + try { + dialog.setAlwaysOnTop(true); + } catch (SecurityException e) { + } + } Rectangle dlgBounds = dialog.getBounds(); // if portion of dialog is not within the gc boundary --- old/src/java.desktop/share/classes/sun/print/PrintJob2D.java 2018-06-05 12:26:18.276041828 -0700 +++ new/src/java.desktop/share/classes/sun/print/PrintJob2D.java 2018-06-05 12:26:18.020041837 -0700 @@ -60,6 +60,7 @@ import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.DialogTypeSelection; +import javax.print.attribute.standard.DialogOwner; import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.PrintQuality; --- old/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2018-06-05 12:26:18.800041807 -0700 +++ new/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2018-06-05 12:26:18.544041817 -0700 @@ -74,6 +74,7 @@ import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Destination; import javax.print.attribute.standard.DialogTypeSelection; +import javax.print.attribute.standard.DialogOwner; import javax.print.attribute.standard.Fidelity; import javax.print.attribute.standard.JobName; import javax.print.attribute.standard.JobSheets; @@ -830,8 +831,15 @@ int x = gcBounds.x+50; int y = gcBounds.y+50; ServiceDialog pageDialog; + boolean setOnTop = false; if (onTop != null) { attributes.add(onTop); + Window owner = onTop.getOwner(); + if (owner != null) { + w = owner; // use the one specifed by the app + } else if (DialogOwnerAccessor.getID(onTop) == 0) { + setOnTop = true; + } } if (w instanceof Frame) { pageDialog = new ServiceDialog(gc, x, y, service, @@ -842,6 +850,12 @@ DocFlavor.SERVICE_FORMATTED.PAGEABLE, attributes, (Dialog)w); } + if (setOnTop) { + try { + pageDialog.setAlwaysOnTop(true); + } catch (SecurityException e) { + } + } Rectangle dlgBounds = pageDialog.getBounds(); @@ -988,8 +1002,7 @@ * (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)); + attributes.add(new DialogOwner(w)); } } else { grCfg = GraphicsEnvironment.getLocalGraphicsEnvironment(). @@ -2581,7 +2594,7 @@ } } - private DialogOnTop onTop = null; + private DialogOwner onTop = null; private long parentWindowID = 0L; @@ -2597,9 +2610,9 @@ private void setParentWindowID(PrintRequestAttributeSet attrs) { parentWindowID = 0L; - onTop = (DialogOnTop)attrs.get(DialogOnTop.class); + onTop = (DialogOwner)attrs.get(DialogOwner.class); if (onTop != null) { - parentWindowID = onTop.getID(); + parentWindowID = DialogOwnerAccessor.getID(onTop); } } } --- old/src/java.desktop/share/classes/sun/print/ServiceDialog.java 2018-06-05 12:26:19.416041784 -0700 +++ new/src/java.desktop/share/classes/sun/print/ServiceDialog.java 2018-06-05 12:26:19.168041793 -0700 @@ -184,8 +184,22 @@ isAWT = true; } - if (attributes.get(DialogOnTop.class) != null) { - setAlwaysOnTop(true); + if (attributes.get(DialogOwner.class) != null) { + DialogOwner owner = (DialogOwner)attributes.get(DialogOwner.class); + /* When the ServiceDialog is constructed the caller of the + * constructor checks for this attribute and if it specifies a + * window then it will use that in the constructor instead of + * inferring one from keyboard focus. + * In this case the owner of the dialog is the same as that + * specified in the attribute and we do not need to set the + * on top property + */ + if ((getOwner() == null) || (owner.getOwner() != getOwner())) { + try { + setAlwaysOnTop(true); + } catch (SecurityException e) { + } + } } Container c = getContentPane(); c.setLayout(new BorderLayout()); @@ -278,8 +292,15 @@ this.asOriginal = attributes; this.asCurrent = new HashPrintRequestAttributeSet(attributes); - if (attributes.get(DialogOnTop.class) != null) { - setAlwaysOnTop(true); + if (attributes.get(DialogOwner.class) != null) { + /* See comments in same block in initPrintDialog */ + DialogOwner owner = (DialogOwner)attributes.get(DialogOwner.class); + if ((getOwner() == null) || (owner.getOwner() != getOwner())) { + try { + setAlwaysOnTop(true); + } catch (SecurityException e) { + } + } } Container c = getContentPane(); --- old/src/java.desktop/unix/classes/sun/print/IPPPrintService.java 2018-06-05 12:26:19.960041763 -0700 +++ new/src/java.desktop/unix/classes/sun/print/IPPPrintService.java 2018-06-05 12:26:19.716041772 -0700 @@ -25,6 +25,8 @@ package sun.print; +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; import javax.print.attribute.*; import javax.print.attribute.standard.*; import javax.print.DocFlavor; @@ -1071,6 +1073,11 @@ catList.add(PrinterResolution.class); } + if (GraphicsEnvironment.isHeadless() == false) { + catList.add(DialogOwner.class); + catList.add(DialogTypeSelection.class); + } + supportedCats = new Class[catList.size()]; catList.toArray(supportedCats); Class[] copyCats = new Class[supportedCats.length]; @@ -1392,10 +1399,38 @@ } } return false; - } if (attr.getCategory() == PrinterResolution.class) { + } else if (attr.getCategory() == PrinterResolution.class) { if (attr instanceof PrinterResolution) { return isSupportedResolution((PrinterResolution)attr); } + } else if (attr.getCategory() == DialogOwner.class) { + DialogOwner owner = (DialogOwner)attr; + // ID not supported on any dialog type on Unix platforms. + if (DialogOwnerAccessor.getID(owner) != 0) { + return false; + } + // On Mac we have no control over the native dialog. + DialogTypeSelection dst = (attributes == null) ? null : + (DialogTypeSelection)attributes.get(DialogTypeSelection.class); + if (PrintServiceLookupProvider.isMac() && + dst == DialogTypeSelection.NATIVE) { + return false; + } + // The other case is always a Swing dialog on all Unix platforms. + // So we only need to check that the toolkit supports + // always on top. + if (owner.getOwner() != null) { + return true; + } else { + return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported(); + } + } else if (attr.getCategory() == DialogTypeSelection.class) { + if (PrintServiceLookupProvider.isMac()) { + return true; + } else { + DialogTypeSelection dst = (DialogTypeSelection)attr; + return attr == DialogTypeSelection.COMMON; + } } return true; } --- old/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2018-06-05 12:26:20.488041743 -0700 +++ new/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2018-06-05 12:26:20.232041753 -0700 @@ -31,6 +31,8 @@ import java.util.ArrayList; import java.util.Locale; +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; import javax.print.DocFlavor; import javax.print.DocPrintJob; import javax.print.PrintService; @@ -54,6 +56,8 @@ import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.CopiesSupported; import javax.print.attribute.standard.Destination; +import javax.print.attribute.standard.DialogOwner; +import javax.print.attribute.standard.DialogTypeSelection; import javax.print.attribute.standard.Fidelity; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; @@ -619,10 +623,15 @@ } public Class[] getSupportedAttributeCategories() { - int totalCats = otherAttrCats.length; - Class[] cats = new Class[totalCats]; - System.arraycopy(otherAttrCats, 0, cats, 0, otherAttrCats.length); - return cats; + ArrayList> categList = new ArrayList<>(otherAttrCats.length); + for (Class c : otherAttrCats) { + categList.add(c); + } + if (GraphicsEnvironment.isHeadless() == false) { + categList.add(DialogOwner.class); + categList.add(DialogTypeSelection.class); + } + return categList.toArray(new Class[categList.size()]); } public boolean @@ -1023,6 +1032,24 @@ flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) { return false; } + } else if (attr.getCategory() == DialogOwner.class) { + DialogOwner owner = (DialogOwner)attr; + // ID not supported on any dialog type on Unix platforms. + if (DialogOwnerAccessor.getID(owner) != 0) { + return false; + } + // UnixPrintService is not used on Mac, so this is + // always some Unix system that does not have CUPS/IPP + // Which means we always use a Swing dialog and we need + // only check if alwaysOnTop is supported by the toolkit. + if (owner.getOwner() != null) { + return true; + } else { + return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported(); + } + } else if (attr.getCategory() == DialogTypeSelection.class) { + DialogTypeSelection dts = (DialogTypeSelection)attr; + return dts == DialogTypeSelection.COMMON; } return true; } --- old/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java 2018-06-05 12:26:21.044041722 -0700 +++ new/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java 2018-06-05 12:26:20.792041731 -0700 @@ -79,6 +79,7 @@ import javax.print.attribute.standard.SheetCollate; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.Destination; +import javax.print.attribute.standard.DialogOwner; import javax.print.attribute.standard.OrientationRequested; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaSizeName; @@ -95,7 +96,6 @@ import sun.print.Win32PrintService; import sun.print.PrintServiceLookupProvider; import sun.print.ServiceDialog; -import sun.print.DialogOwner; import java.awt.Frame; import java.io.FilePermission; --- old/src/java.desktop/windows/classes/sun/print/Win32PrintService.java 2018-06-05 12:26:21.656041698 -0700 +++ new/src/java.desktop/windows/classes/sun/print/Win32PrintService.java 2018-06-05 12:26:21.404041708 -0700 @@ -25,6 +25,8 @@ package sun.print; +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; import java.awt.Window; import java.awt.print.PrinterJob; import java.io.File; @@ -54,6 +56,8 @@ import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.CopiesSupported; import javax.print.attribute.standard.Destination; +import javax.print.attribute.standard.DialogOwner; +import javax.print.attribute.standard.DialogTypeSelection; import javax.print.attribute.standard.Fidelity; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaSizeName; @@ -1042,6 +1046,10 @@ categList.add(PrinterResolution.class); } + if (GraphicsEnvironment.isHeadless() == false) { + categList.add(DialogOwner.class); + categList.add(DialogTypeSelection.class); + } return categList.toArray(new Class[categList.size()]); } @@ -1585,6 +1593,23 @@ (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) { return false; } + } else if (category == DialogTypeSelection.class) { + return true; // isHeadless was checked by category support + } else if (category == DialogOwner.class) { + DialogOwner owner = (DialogOwner)attr; + DialogTypeSelection dts = (attributes == null) ? null : + (DialogTypeSelection)attributes.get(DialogTypeSelection.class); + if (dts == DialogTypeSelection.NATIVE) { + return DialogOwnerAccessor.getID(owner) != 0; + } else { + if (DialogOwnerAccessor.getID(owner) != 0) { + return false; + } else if (owner.getOwner() != null) { + return true; + } else { + return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported(); + } + } } return true; } --- /dev/null 2018-05-25 11:37:39.280540387 -0700 +++ new/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java 2018-06-05 12:26:21.928041688 -0700 @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2018, 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 8203796 + @run main/manual DialogOwnerTest + @summary Test DialogOwner API +*/ + +import java.util.ArrayList; +import java.util.List; +import java.awt.GraphicsConfiguration; +import java.awt.GridLayout; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.print.PrinterJob; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.ServiceUI; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.DialogOwner; +import javax.print.attribute.standard.DialogTypeSelection; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +public class DialogOwnerTest extends JPanel { + + static final int NONE = 0x0; + static final int PRINT = 0x1; + static final int PAGE = 0x2; + static final int SWING2D = 0x4; + static final int NATIVE2D = 0x8; + static final int SERVICEUI = 0x10; + + static final int ONTOP = 0x20; + static final int OWNED = 0x40; + + static PrintService[] services = + PrintServiceLookup.lookupPrintServices(null, null); + + public static void main(String[] args) { + if (services.length == 0) { + System.out.println("No printers, exiting"); + return; + } else { + service = PrinterJob.getPrinterJob().getPrintService(); + } + SwingUtilities.invokeLater(() -> { + createUI(); + }); + while (!testFinished) { + try { + Thread.sleep(1000); + } catch (InterruptedException e){ + } + } + if (!testPassed) { + throw new RuntimeException("TEST FAILED."); + } + } + + + static final String otherText = + "This window is used to test on top behaviour\n" + + "For tests that are 'Owned' or 'On Top' the dialog\n" + + "must always stay above this window. Verify this\n " + + "by moving the dialog so that it partially obscures\n" + + "this window and then trying to raise this window."; + + static final String instructions = + " Instructions\n" + + "This tests that a print dialog stays on top of either another\n" + + "window, or on top of all windows.\n" + + "For Owned tests the window titled 'Owner Window' should always \n" + + "stay behind the print dialog.\n" + + "For On Top tests all windows should stay behind the owner window.\n" + + "This test tracks if you have checked all the scenarios and will\n" + + "not allow the test to pass unless you have visited them all.\n"; + + static PrintService service; + + public DialogOwnerTest() { + super(); + //setLayout(new GridLayout(24, 1)); + } + + static boolean isNative(int flags) { + return (flags & NATIVE2D) != 0; + } + + static boolean isCommon(int flags) { + return (flags & SWING2D) != 0; + } + + static boolean is2D(int flags) { + return (flags & SWING2D|NATIVE2D) != 0; + } + + static boolean isPage(int flags) { + return (flags & PAGE ) != 0; + } + + static JFrame frame; + static JFrame other; + static JButton pass; + static ArrayList panelList = new ArrayList(); + static volatile boolean testPassed, testFinished; + + int testCount = 0; + List testList = new ArrayList(); + + static void createUI() { + other = new JFrame("Owner Window"); + JTextArea otherTextArea = new JTextArea(otherText, 10, 40); + other.add(otherTextArea); + other.pack(); + other.setVisible(true); + other.setLocation(800, 100); + + frame = new JFrame("Test Dialog Owner"); + frame.pack(); + JTextArea instructionsPanel = new JTextArea(instructions, 10, 50); + instructionsPanel.setEditable(false); + frame.add("North", instructionsPanel); + DialogOwnerTest test = new DialogOwnerTest(); + + test.addTest("Owned Swing Print", OWNED, frame, PRINT|SWING2D); + test.addTest("On Top Swing Print", ONTOP, null, PRINT|SWING2D); + + test.addTest("Owned Swing Page", OWNED, frame, PAGE|SWING2D); + test.addTest("On Top Swing Page", ONTOP, null, PAGE|SWING2D); + + test.addTest("Owned javax.print", OWNED, frame, PRINT|SERVICEUI); + test.addTest("On Top javax.print", OWNED, null, PRINT|SERVICEUI); + + test.addTest("Owned Native Print", OWNED, frame, PRINT|NATIVE2D); + test.addTest("On Top Native Print", OWNED, null, PRINT|NATIVE2D); + + test.addTest("Owned Native Page", OWNED, frame, PAGE|NATIVE2D); + test.addTest("On Top Native Page", OWNED, null, PAGE|NATIVE2D); + + test.setLayout(new GridLayout(panelList.size()+2, 1)); + + pass = new JButton("Pass"); + pass.setEnabled(false); + pass.addActionListener((ActionEvent e) -> { + if (test.testList.size() > 0) { + return; + } + frame.dispose(); + other.dispose(); + System.out.println("User says test passed."); + testPassed = true; + testFinished = true; + }); + + JButton fail = new JButton("Fail"); + fail.addActionListener((ActionEvent e) -> { + frame.dispose(); + other.dispose(); + System.out.println("User says test failed."); + testPassed = false; + testFinished = true; + }); + + JPanel p = new JPanel(); + p.add(pass); + p.add(fail); + test.add(p); + + + for (JPanel panel : panelList) { + test.add(panel); + } + + frame.add("Center", test); + frame.pack(); + frame.setLocation(0,0); + frame.setVisible(true); + } + + boolean isSupported(PrintRequestAttributeSet aset, + int ownerFlags, Window owner, int dlgFlags) { + + boolean supported = true; + DialogOwner ownerAttr = null; + if (ownerFlags != NONE) { + if (ownerFlags == ONTOP) { + ownerAttr = new DialogOwner(); + } else if (ownerFlags == OWNED) { + ownerAttr = new DialogOwner(owner); + } + aset.add(ownerAttr); + } + if (is2D(dlgFlags)) { + DialogTypeSelection dst = null; + if (isNative(dlgFlags)) { + dst = DialogTypeSelection.NATIVE; + } else if (isCommon(dlgFlags)) { + dst = DialogTypeSelection.COMMON; + } + if (dst != null && + !service.isAttributeValueSupported(dst, null, aset)) { + //System.out.println("This DialogType not supported"); + supported = false; + } + if (dst != null) { + aset.add(dst); + } + if (ownerAttr != null && + !service.isAttributeValueSupported(ownerAttr, null, aset)) { + //System.out.println("This DialogOwner not supported"); + supported = false; + } + } + return supported; + } + + void addTest(String title, int ownerFlags, Window owner, int dlgFlags) { + + PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); + if (!isSupported(aset, ownerFlags, owner, dlgFlags)) { + return; + } + + // if we are here then this is supportable and worth testing + // and the attribute set is configured. + + String label = title + " Dialog"; + JButton button = new JButton(label); + JCheckBox tested = new JCheckBox("Tested"); + tested.setEnabled(false); + JPanel panel = new JPanel(); + panel.add(tested); + panel.add(button); + panelList.add(panel); + //add(panel); + testList.add(title); + if (++testCount != testList.size()) { + throw new RuntimeException("Test titles must be unique"); + } + + button.addActionListener((ActionEvent e) -> { + tested.setSelected(true); + testList.remove(title); + if (testList.isEmpty()) { + pass.setEnabled(true); + } + + if (is2D(dlgFlags)) { + PrinterJob job = PrinterJob.getPrinterJob(); + if (isPage(dlgFlags)) { + job.pageDialog(aset); + } else { + job.printDialog(aset); + } + } else { + GraphicsConfiguration gc = null; + int x = 0, y = 0; + ServiceUI.printDialog(gc, x, y, services, services[0], null,aset); + } + }); + } +} --- old/src/java.desktop/share/classes/sun/print/DialogOwner.java 2018-06-05 12:26:22.712041658 -0700 +++ /dev/null 2018-05-25 11:37:39.280540387 -0700 @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2007, 2014, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -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 - * the window that owns the print dialog. - * - *

- * IPP Compatibility: This is not an IPP attribute. - *

- * - */ -@SuppressWarnings("serial") // JDK-implementation class -public final class DialogOwner - implements PrintRequestAttribute { - - private Window dlgOwner; - - /** - * Construct a new dialog owner attribute with the given frame. - * - * @param frame the frame that owns the print dialog - */ - public DialogOwner(Frame frame) { - 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 Window getOwner() { - return dlgOwner; - } - - - /** - * Get the printing attribute class which is to be used as the "category" - * for this printing attribute value. - *

- * For class DialogOwner the category is class - * DialogOwner itself. - * - * @return Printing attribute class (category), an instance of class - * {@link java.lang.Class java.lang.Class}. - */ - public Class getCategory() { - return DialogOwner.class; - } - - - /** - * Get the name of the category of which this attribute value is an - * instance. - *

- * For class DialogOwner the category name is - * {@code "dialog-owner"}. - * - * @return Attribute category name. - */ - public String getName() { - return "dialog-owner"; - } - -} --- old/src/java.desktop/share/classes/sun/print/DialogOnTop.java 2018-06-05 12:26:23.076041644 -0700 +++ /dev/null 2018-05-25 11:37:39.280540387 -0700 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package sun.print; - -import javax.print.attribute.Attribute; -import javax.print.attribute.PrintRequestAttribute; - -/* - * An implementation class used to request the dialog be set always-on-top. - * It needs to be read and honoured by the dialog code which will use - * java.awt.Window.setAlwaysOnTop(true) in cases where it is supported. - */ -public class DialogOnTop implements PrintRequestAttribute { - - private static final long serialVersionUID = -1901909867156076547L; - - long id; - - public DialogOnTop() { - } - - public DialogOnTop(long id) { - this.id = id; - } - - public final Class getCategory() { - return DialogOnTop.class; - } - - public long getID() { - return id; - } - - public final String getName() { - return "dialog-on-top"; - } - - public String toString() { - return "dialog-on-top"; - } -}