简体   繁体   English

如何在 Java 中制作非阻塞 PrinterJob pageDialog?

[英]How to make a non-blocking PrinterJob pageDialog in Java?

Below is code to create a simple window with a useless button in it and a PrintingJob that automatically opens a page dialog when the program starts:下面是创建一个简单的 window 的代码,其中包含一个无用的按钮和一个在程序启动时自动打开页面对话框的 PrintingJob:

import java.awt.BorderLayout;
import java.awt.print.PrinterJob;
import javax.swing.JButton;
import javax.swing.JFrame;

public class DummyCode {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new JButton("TEST"), BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
    PrinterJob pj = PrinterJob.getPrinterJob();
    pj.pageDialog(pj.defaultPage());
  }
}

Current behavior: The page dialog blocks user inputs to the rest of the application - it's not possible to click or move the application window.当前行为:页面对话框阻止用户对应用程序 rest 的输入 - 无法单击或移动应用程序 window。

Wanted behavior: The page dialog shall not block user inputs to the rest of the application - it shall be possible to click and move the application window.想要的行为:页面对话框不应阻止用户对应用程序 rest 的输入 - 应该可以单击并移动应用程序 window。

From what I can see pageDialog() creates a WPageDialog which extends Dialog and is hardcoded to set modal=true, aka it blocks user input to other top-level windows when shown.从我所见, pageDialog()创建了一个WPageDialog ,它扩展了Dialog并被硬编码为设置 modal=true,也就是当显示时它会阻止用户输入到其他顶级 windows。 I essentially want modal=false such that user input to other top-level windows are not blocked by the dialog, but this is not immediately modifiable.我本质上想要 modal=false 以便用户输入到其他顶级 windows 不会被对话框阻止,但这不能立即修改。

Running the pageDialog in it's own thread does not resolve the issue.在它自己的线程中运行 pageDialog 并不能解决问题。

Is there some nifty workaround for this to achieve the wanted behavior?是否有一些巧妙的解决方法可以实现所需的行为?

Here is an example of creating a ServiceDialog explicitly, which doesn't block the origin JFrame (or anything really).这是一个显式创建 ServiceDialog 的示例,它不会阻止原点 JFrame (或其他任何东西)。

mport sun.print.ServiceDialog;

import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.print.PrinterJob;

public class TestPrint {

    public static void main(String[] args) throws Exception{
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton test = new JButton("TEST");
        test.addActionListener(evt -> System.out.println("action!"));

        frame.getContentPane().add(test, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);

        final GraphicsConfiguration gc =
            GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        PrintService service = PrinterJob.getPrinterJob().getPrintService();
        ServiceDialog log = new ServiceDialog(gc, 500, 500, service, DocFlavor.SERVICE_FORMATTED.PAGEABLE, new HashPrintRequestAttributeSet(), frame);
        log.setModal(false);
        log.setVisible(true);
        System.out.println("waiting");
    }
}

Something that probably shouldn't be done.可能不应该做的事情。 The example at the bottom starts a separate process with jshell running and creates the print dialog.底部的示例启动了一个运行 jshell 的单独进程并创建了打印对话框。 The original gui stays responsive.原始 gui 保持响应。

import java.awt.BorderLayout;
import java.awt.print.PrinterJob;
import java.awt.Dialog;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class DummyCode {

    static void drain(Process proc) throws Exception{
        InputStream is = proc.getInputStream();
        InputStreamReader reader = new InputStreamReader( is, "UTF8");
        new Thread( ()->{
            char[] buffer = new char[512];
            try{
                int read = reader.read(buffer, 0, 512);
                while(read >= 0 ){
                    System.out.println( new String(buffer, 0, read ) );
                    read = reader.read(buffer, 0, 512);
                }            
            } catch(IOException e){
                e.printStackTrace();
            } 
        } ).start();     
    }

  public static void main(String[] args) throws Exception{
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JButton test = new JButton("TEST");
    test.addActionListener(evt -> System.out.println("action!"));
    
    frame.getContentPane().add(test, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
    Process proc = Runtime.getRuntime().exec("/usr/bin/jshell");
    
    drain(proc);
    
    OutputStream os = proc.getOutputStream();
    OutputStreamWriter writer = new OutputStreamWriter( os, "UTF8" );
    writer.write( "import java.awt.print.PrinterJob;\n");
    writer.write( "PrinterJob pj = PrinterJob.getPrinterJob();\n");
    writer.write( "pj.pageDialog(pj.defaultPage());\n");
    writer.flush();
    
  }
}    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM