java - 使用小程序时无法获取默认打印机名称 - ZK Framework

标签 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 存在于“WebContent/applet”中。

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 应用程序一起工作正常,但在使用上述方法时无法获得默认打印机服务。

最佳答案

First I want to mention that APPLET IS ALWAYS RUN ON CLIENT SIDE and APPLET only communicates to the server which from it is downloaded.

That’s why we have to specify codebase directory, so that we can download the applet on client browser by then JAVA Platform Environment plugin from browser takes on control, which in turn run on client JRE environment.

So we have to be very carefully that JDK environment is installed properly. To trace applet log we can use of java applet console tool ‘jconsole’.


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

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

    如果你在 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时,为了反射(reflect)最新的更改,我们需要先清除缓存,否则它将加载缓存的Applet类。

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

    路径:JAVA_HOME/bin/javaws -viewer

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


As per your code, your server side code (zul and composer) are perfect but the problem is at applet code.

You are looking for a default printer in print() method, which are one time configuration codes. It has to be in 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));
 }
}

And you need another implementation of AccessController to give access to the default printer locate and 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)

Where str can be file name if you want file to be print, or byte array string.

Here in my example, I expected byte array, so I create pdf file from byte array given by the applet from the composer and then it'll sent to the default printer to the given PrintService.

So Actual flow for applet in zk to get access for default printer and to print is by this [graph][3].

关于java - 使用小程序时无法获取默认打印机名称 - ZK Framework,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34394577/

相关文章:

java - Equals 方法中浮点/ double 实例变量的相等比较是否应该准确?

java - LibGDX 无法正确渲染 (Mac)

printing - 打印 JavaFx TableView 的内容

javascript - 如何使用 Angular (4.0) 进行打印

java - 同时使用按键事件和鼠标事件

java - 为什么我的 Java Applet 中的 Swing 在鼠标快速悬停时会闪烁?

java - Oracle 只读 JDBC 连接

css - 打印的页表标题仅在没有分页符的表上重复

java - 新闻文章 : Write to server disk without PHP?

java - 如何使用 javax.ws.rs.* 和 Glassfish 从 GET HTTP 方法检索参数?