--- old/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/print/J2DPrinterJob.java 2017-03-10 11:56:40.253425448 -0800 +++ new/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/print/J2DPrinterJob.java 2017-03-10 11:56:39.605425451 -0800 @@ -45,6 +45,7 @@ import javafx.stage.Window; import javax.print.PrintService; import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttribute; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.ResolutionSyntax; import javax.print.attribute.Size2DSyntax; @@ -76,9 +77,16 @@ import com.sun.javafx.print.PrinterJobImpl; import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.sg.prism.NGNode; +import com.sun.javafx.stage.WindowHelper; +import com.sun.javafx.tk.TKStage; import com.sun.javafx.tk.Toolkit; + import com.sun.prism.j2d.PrismPrintGraphics; +import java.lang.reflect.Constructor; +import java.security.AccessController; +import java.security.PrivilegedAction; + public class J2DPrinterJob implements PrinterJobImpl { javafx.print.PrinterJob fxPrinterJob; @@ -90,6 +98,25 @@ private PrintRequestAttributeSet printReqAttrSet; private volatile Object elo = null; + static private Class onTopClass = null; + PrintRequestAttribute getAlwaysOnTop(final long id) { + return AccessController.doPrivileged( + (PrivilegedAction) () -> { + + PrintRequestAttribute alwaysOnTop = null; + try { + if (onTopClass == null) { + onTopClass = Class.forName("sun.print.DialogOnTop"); + } + Constructor cons = + onTopClass.getConstructor(long.class); + alwaysOnTop = cons.newInstance(id); + } catch (Throwable t) { + } + return alwaysOnTop; + }); + } + public J2DPrinterJob(javafx.print.PrinterJob fxJob) { fxPrinterJob = fxJob; @@ -103,11 +130,21 @@ } printReqAttrSet = new HashPrintRequestAttributeSet(); printReqAttrSet.add(DialogTypeSelection.NATIVE); - j2dPageable = new J2DPageable(); pJob2D.setPageable(j2dPageable); } + private void setEnabledState(Window owner, boolean state) { + if (owner == null) { + return; + } + final TKStage stage = WindowHelper.getPeer(owner); + if (stage == null) { // just in case. + return; + } + Application.invokeAndWait(() -> stage.setEnabled(state)); + } + public boolean showPrintDialog(Window owner) { if (jobRunning || jobDone) { @@ -118,20 +155,37 @@ return true; } + if (onTopClass != null) { + printReqAttrSet.remove(onTopClass); + } + if (owner != null) { + long id = WindowHelper.getPeer(owner).getRawHandle(); + PrintRequestAttribute alwaysOnTop = getAlwaysOnTop(id); + if (alwaysOnTop != null) { + printReqAttrSet.add(alwaysOnTop); + } + } + boolean rv = false; syncSettingsToAttributes(); - if (!Toolkit.getToolkit().isFxUserThread()) { - rv = pJob2D.printDialog(printReqAttrSet); - } else { - // If we are on the event thread, we need to check whether we are - // allowed to call a nested event handler. - if (!Toolkit.getToolkit().canStartNestedEventLoop()) { - throw new IllegalStateException("Printing is not allowed during animation or layout processing"); + try { + setEnabledState(owner, false); + if (!Toolkit.getToolkit().isFxUserThread()) { + rv = pJob2D.printDialog(printReqAttrSet); + } else { + // If we are on the event thread, we need to check whether + // we are allowed to call a nested event handler. + if (!Toolkit.getToolkit().canStartNestedEventLoop()) { + throw new IllegalStateException( + "Printing is not allowed during animation or layout processing"); + } + rv = showPrintDialogWithNestedLoop(owner); } - rv = showPrintDialogWithNestedLoop(owner); - } - if (rv) { - updateSettingsFromDialog(); + if (rv) { + updateSettingsFromDialog(); + } + } finally { + setEnabledState(owner, true); } return rv; } @@ -171,18 +225,36 @@ if (GraphicsEnvironment.isHeadless()) { return true; } + + if (onTopClass != null) { + printReqAttrSet.remove(onTopClass); + } + if (owner != null) { + long id = WindowHelper.getPeer(owner).getRawHandle(); + PrintRequestAttribute alwaysOnTop = getAlwaysOnTop(id); + if (alwaysOnTop != null) { + printReqAttrSet.add(alwaysOnTop); + } + } + boolean rv = false; syncSettingsToAttributes(); - if (!Toolkit.getToolkit().isFxUserThread()) { - PageFormat pf = pJob2D.pageDialog(printReqAttrSet); - rv = pf != null; - } else { - // If we are on the event thread, we need to check whether we are - // allowed to call a nested event handler. - if (!Toolkit.getToolkit().canStartNestedEventLoop()) { - throw new IllegalStateException("Printing is not allowed during animation or layout processing"); + try { + setEnabledState(owner, false); + if (!Toolkit.getToolkit().isFxUserThread()) { + PageFormat pf = pJob2D.pageDialog(printReqAttrSet); + rv = pf != null; + } else { + // If we are on the event thread, we need to check whether + // we are allowed to call a nested event handler. + if (!Toolkit.getToolkit().canStartNestedEventLoop()) { + throw new IllegalStateException( + "Printing is not allowed during animation or layout processing"); + } + rv = showPageDialogFromNestedLoop(owner); } - rv = showPageDialogFromNestedLoop(owner); + } finally { + setEnabledState(owner, true); } if (rv) { updateSettingsFromDialog();