使用applet时无法获取默认打印机名称 - ZK Framework

时间:2015-12-21 11:26:19

标签: java printing applet zk zul

我想直接从网页打印我的文件。为此,我使用以下参考并尝试与ZUL和Composer一起实现。

http://tonny-bruckers.blogspot.in/2012/11/printing-files-directly-from-web-page.html

ZUL文件: -

<zk>
<applet code = "PrintApplet.class" codebase = "applet/" id="printApplet" width="400px" style="border: 1px" />
<button id="btnClickMe" label="Click Me" sclass="light-btn"/>
</zk>

PrintApplet.class存在于&#34; WebContent / applet&#34;。

public class AppletComposer extends GenericForwardComposer<Window> {
    private Applet printApplet;
    public void doOverrideAfterComposer(Window comp) throws Exception {

    }
    public void onClick$btnClickMe(Event event) throws Exception {
        String Originalstr = "ByteArrayInputStream Example!";
        byte[] Originalbytes = Originalstr.getBytes();
        ByteArrayInputStream bis=new ByteArrayInputStream(Originalbytes);
        printApplet.invoke("print", bis);
    }
}

PrintApplet类: -

public class PrintApplet extends Applet {
    public void init() 
    {

    }
    public void print(ByteArrayInputStream bis) throws PrintException 
    {
        PrintService service = PrintServiceLookup.lookupDefaultPrintService();
        if (service != null) {
            DocFlavor psFormat = DocFlavor.INPUT_STREAM.PDF;
            PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();    
            DocPrintJob job = service.createPrintJob();
            Doc pdfDoc = new SimpleDoc(bis,psFormat, null);
            job.print(pdfDoc, attributes);         
        }
    }
}

我可以使用这种方法调用PrintApplet,但是将Null作为服务。 PrintApplet可以正常使用AppletViewer和普通的Java Application,但在使用上述方法时无法获得默认的打印机服务。

1 个答案:

答案 0 :(得分:2)

  

首先,我想提一下 APPLET始终在客户端运行,APPLET仅与从中下载的服务器进行通信。

     

这就是为什么我们必须指定codebase目录,以便我们可以在客户端浏览器上下载applet,然后从浏览器获取JAVA Platform Environment插件,然后在客户端JRE环境中运行。

     

因此,我们必须非常谨慎地正确安装JDK环境。   要跟踪applet日志,我们可以使用java applet控制台工具' jconsole '。

APPLET在客户端浏览器上正常运行的步骤:

  1. 在浏览器(firefox,chrome,opera)中检查JAVA平台插件是否存在,因为要从浏览器运行applet,我们需要安装并启用插件。

    如果你正在使用linux机器:比它有点复杂, 您可以在此处找到如何为LINUX-BROWSER启用插件:

    http://www.oracle.com/technetwork/java/javase/manual-plugin-install-linux-136395.html

  2. 启用applet的控制台日志,当它在客户端JRE上执行时,我们可以查看它以进行跟踪。

    路径:JDK_DIR / bin / jcontrol

    [JControl窗口] [1]

    仅用于开发目的:您可以降低安全性

  3. 我们必须在每次构建新applet时清除applet的缓存,以反映我们首先清除缓存所需的最新更改,否则它将加载缓存的applet类。

    要清除我们可以使用' javaws -viewer '

    路径:JAVA_HOME / bin / javaws -viewer

    [清除小程序缓存] [2]

  4.   

    根据您的代码,您的服务器端代码(zul和composer)是完美的,但问题出在applet代码上。

         

    您正在寻找print()方法中的默认打印机,这是一次性配置代码。它必须在init()。

         

    <强> PrintApplet.java

    public class PrintApplet extends Applet {
    
     private static final long serialVersionUID = 1L;
     private PrintService service;
    
     public void init() 
     {
        JOptionPane.showMessageDialog(null, "Inside INIT()");
        if(null==service){
            service = PrintServiceLookup.lookupDefaultPrintService();
            System.out.println(service.getName());
        } else {
            System.out.println(service.getName());
        }
     }
     public void print(String str) throws PrintException 
     {
        JOptionPane.showMessageDialog(null, "Inside print()");
        JOptionPane.showMessageDialog(null, "String is:::"+str);
        cPrint cP = new cPrint(str, service);
        System.out.println((Integer) AccessController.doPrivileged(cP));
     }
    }
    
      

    你需要另一个AccessController实现来访问默认的打印机locate和print。

         

    <强> cPrint.java

    class cPrint implements PrivilegedAction<Object> {
     String str;
     PrintService service;
    
     public cPrint(String str, PrintService argPrintService) {
    
        this.str = str;
        this.service = argPrintService;
    
     };
     public Object run() {
        // privileged code goes here
        InputStream is = null;
        try 
        {
            JOptionPane.showMessageDialog(null, "String is:::"+str);
            byte[] Originalbytes = str.getBytes();
            JOptionPane.showMessageDialog(null, "Original bytes:::"+Originalbytes);
            is=new ByteArrayInputStream(Originalbytes);
            FileWriter fstream = new FileWriter("/home/test/out.pdf");  
            BufferedWriter out = new BufferedWriter(fstream);  
            for (Byte b: Originalbytes) {  
                out.write(b);  
            }  
            out.close();
            DocPrintJob printJob = service.createPrintJob();
            Doc doc;
            DocAttributeSet docAttrSet = new HashDocAttributeSet();
            PrintRequestAttributeSet printReqAttr = new HashPrintRequestAttributeSet();
            doc = new SimpleDoc(is, DocFlavor.INPUT_STREAM.AUTOSENSE, docAttrSet);
            PrintJobWatcher pjDone = new PrintJobWatcher(printJob);
            printJob.print(doc, printReqAttr);
            pjDone.waitForDone();
            // It is now safe to close the input stream
            is.close();
         } 
         catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
            return 1;
         } 
        return 0;
      }
      static class PrintJobWatcher {
        // true iff it is safe to close the print job's input stream
        boolean done = false;
    
        PrintJobWatcher(DocPrintJob job) {
            // Add a listener to the print job
            job.addPrintJobListener(new PrintJobAdapter() {
                public void printJobCanceled(PrintJobEvent pje) {
                    allDone();
                }
                public void printJobCompleted(PrintJobEvent pje) {
                    allDone();
                }
                public void printJobFailed(PrintJobEvent pje) {
                    allDone();
                }
                public void printJobNoMoreEvents(PrintJobEvent pje) {
                    allDone();
                }
                void allDone() {
                    synchronized (PrintJobWatcher.this) {
                        done = true;
                        PrintJobWatcher.this.notify();
                    }
                }
            });
        }
        public synchronized void waitForDone() {
            try {
                while (!done) {
                    wait();
                }
            } catch (InterruptedException e) {
            }
        }
     }
    }
    
      
        

    <强> cPrint(STR,PrintService的)

             

    如果您希望打印文件或字节数组字符串,则str可以是文件名。

             

    在我的例子中,我期望字节数组,所以我从作曲家的applet给出的字节数组中创建pdf文件,然后它将被发送到默认的打印机到给定的 PrintService

             

    因此,zk中applet的实际流程是为了获取默认打印机和打印的访问权限,这是[图表] [3]。