How to Use Dynamic Web TWAIN with ZK Framework

ZK is a Java Web framework that similar to GWT. Some developers have no idea how they can integrate DWT (Dynamic Web TWAIN) into a ZK Web project. I have successfully made it. The process is not too hard, but a little bit tricky.

First ZK Web Project with Eclipse and Maven

  1. Install Eclipse.
  2. Install M2Eclipse.
  3. Add ZK Maven Archetype: Window > Preferences > Mave > Archetypes > Add Remote Catalog > Catalog File “http://mavensync.zkoss.org/maven2/”.
  4. Create a Maven project: File > New > Project > Maven > Maven Project.
  5. Select zk-archetype-webappzk webapp
  6. Specify group id and artifact id. zk group id
  7. Run app: Run As > Maven Build…
  8. Enter jetty:start in Goals, and then click Run.run zk project
  9. Visit http://localhost:8080/dwt/index.zul.

For more information, please read – Create and Run Your First ZK Application with Eclipse and Maven.

How to Make Dynamic Web TWAIN Work with ZK

In ZK, UI is described in zul files. To load third-party HTML resources to the file, we can use the HTML tag:

<html><![CDATA[

// TODO:

]]></html>

Copy the Resources folder from <Dynamic Web TWAIN>\Resources to webapp:

zk project structure

Refer to the sample HelloWorld.html that located at <Dynamic Web TWAIN SDK>\Samples\Getting Started, copy the source code to index.zul:

<html><![CDATA[

<script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"> </script>
<script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"> </script>
<input type="button" value="Scan" onclick="AcquireImage();" />

<div id="dwtcontrolContainer"></div>

<script type="text/javascript">
        function AcquireImage() {
            var DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer'); // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'.
            DWObject.IfDisableSourceAfterAcquire = true;    // Source will be closed automatically after acquisition.
            DWObject.SelectSource();                        // Select a Data Source (a device like scanner) from the Data Source Manager.            
            DWObject.OpenSource();                          // Open the source. You can set resolution, pixel type, etc. after this method. Please refer to the sample 'Scan' -> 'Custom Scan' for more info.
            DWObject.AcquireImage();                        // Acquire image(s) from the Data Source. Please NOTE this is a asynchronous method. In other words, it doesn't wait for the Data Source to come back. 
            // In order to do things during the scanning, you can use the events OnPostTransfer and OnPostAllTransfers. Please check out the sample UseEvent.html
        }
</script>

]]></html>

Run the project to see what will happen:
Nothing displayed, and the scan button cannot work at all!

If you run the sample code independently as an HTML file, there is no problem. Why cannot the code work in ZK framework?

As debug the JavaScript code, you will find the value of DWObject is null, which means it failed to initialize the object with the div element dwtcontrolContainer. We should choose the right timing that all UI elements have been successfully initialized. To fix this issue, change the DWT settings and manually load the UI element as follows.

Edit dynamsoft.webtwain.config.js:

Dynamsoft.WebTwainEnv.AutoLoad = false;

Change index.zul:

<zk>
	<window apply="org.zkoss.bind.BindComposer"
		viewModel="@id('vm')@init('com.dynamsoft.dwt.MyViewModel')"
		validationMessages="@id('vmsgs')" >

		<html><![CDATA[
		<script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js" defer="true"> </script>
    	<script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js" defer="true"> </script>

        <input type="button" value="Scan" onclick="AcquireImage();" />

	    <!-- dwtcontrolContainer is the default div id for Dynamic Web TWAIN control. 
	         If you need to rename the id, you should also change the id in dynamsoft.webtwain.config.js accordingly. -->
	    <div id="dwtcontrolContainer"></div>

	    <script type="text/javascript" defer="true">

	    	window.onload = function(){
                Dynamsoft.WebTwainEnv.Unload();
	   			Dynamsoft.WebTwainEnv.Load();
			};

	        function AcquireImage() {
	            var DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer'); // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'.
	            DWObject.IfDisableSourceAfterAcquire = true;    // Source will be closed automatically after acquisition.
	            DWObject.SelectSource();                        // Select a Data Source (a device like scanner) from the Data Source Manager.            
	            DWObject.OpenSource();                          // Open the source. You can set resolution, pixel type, etc. after this method. Please refer to the sample 'Scan' -> 'Custom Scan' for more info.
	            DWObject.AcquireImage();                        // Acquire image(s) from the Data Source. Please NOTE this is a asynchronous method. In other words, it doesn't wait for the Data Source to come back. 
	            // In order to do things during the scanning, you can use the events OnPostTransfer and OnPostAllTransfers. Please check out the sample UseEvent.html
	        }
	    </script>
	        ]]></html>     

	</window>
</zk>

Refresh your page, you will see DWT component works now.

Reference

Source Code

https://github.com/dynamsoftsamples/dwt-zk-framework