Pass an Array between Java and JavascriptTag(s): Javascript interaction


Javascript can read directly a Java Array but the other way don't seem be true. NOTE : Reading a Java array from Javascript may crash your browser for some unknown reason. So it's safer to use the next technique!

A safe and simple way is to transform the Array as a big String with a known character used a separator. From there, it's trivial to do some manipulations to retrieve the array.

In the following example, the first button is used to read directly the Java array. The second button call a Java method which to transform the array as a string, then the Javascript function split() is used to retrieve the array. The third button will modify the Java array. A Javascript array is transformed with the function join() and on the Java-side, a StringTokenizer will do the rest.

[Java applet]

import java.awt.*;
import java.applet.*;
import java.util.*;

public class TestJavaArray extends Applet{
 public String  javaArray [] =
   { "array 1", "array 2" , "array 3" };

 public String [] getJavaArray() {
   return javaArray;
   }

public String getJavaArrayAsAString() {
   // you need more error checking here, of course...
   int k;
   String s = "";

   k = javaArray.length;
   s = javaArray[0];
   for (int i= 1 ; i < k; i++) {
      s += "|" + javaArray[i] ;
      }
   return s;
   }

 public void putJavaArray(String arrayAsAString) {
   int i = 0;
   String s;
   StringTokenizer st =
      new StringTokenizer(arrayAsAString, "|");

   while(st.hasMoreTokens()){
     javaArray[i++] = st.nextToken();
     }
   }
}

[HTML and Javascript]

<HTML><HEAD></HEAD><BODY>
<SCRIPT>
 function getJavaArray() {
    arrayFromJava = document.myApplet.getJavaArray();

    alert("Java Array length = " + arrayFromJava.length + "\r\n" +
          "element 2 is " + arrayFromJava[1]);
    }

function getJavaArrayAsAString() {
    var arrayAsAString =
       document.myApplet.getJavaArrayAsAString();
    realJsString = arrayAsAString + "";
    arrayFromJava = realJsString.split("|");
    alert("Java Array length = " + arrayFromJava.length + "\r\n" +
          "element 2 is " + arrayFromJava[1]);
    }

 function putJavaArray() {
    arrayFromJs = new Array("ARRAY 1", "ARRAY 2", "ARRAY 3");
    arrayAsAString = arrayFromJs.join("|");
    document.myApplet.putJavaArray(arrayAsAString);
    }

 </SCRIPT>
 <FORM>
 <INPUT type="button" value="get JAVA array"
    onClick = "getJavaArray();">
 <INPUT type="button" value="get JAVA array (as a string)"
     onClick = "getJavaArrayAsAString();">
 <INPUT type="button" value="put JAVA array"
    onClick = "putJavaArray();">
 </FORM>
 <APPLET CODE="TestJavaArray.class"
         NAME="myApplet"
         HEIGHT=0 WIDTH=0>
</APPLET></BODY></HTML>

Try it here.

Here an interesting piece of code submitted by M. Caetano which does basically the same thing. Note the use of regular expressions to keep the code short and compact. Since java classes are called directly by javascript, these functions won't work with IE (only with Netscape).

/*
  COPYJAVA  (by Mike Caetano)

  Array prototype method to transfer array elements between javascript and
  java

    java array arg fills this empty js array with elements from java array
    empty js array assigns its elements to string cast java array

    Use:
    // fill empty jsArray with the elements from the java array as strings
    var jsArray = [];
    jsArray.copyJava(javaArray)

    // fill a javaArray with the elements from jsArray cast as
    java.lang.String
    var javaArray2 = jsArray.copyJava()

    Note: doesn't include cast for netscape.javascript.JSObject
    - that requires a more stringent type checking
    ie. typeof( [object Layer] ) => netscape.javascript.JSObject
    - for now just don't call copyJava on an array of objects
---------------------------- */

function copyJava(arg_) {
  if ( /^\bnull\b$|^\bundefined\b$|^\s?$/i.test(arg_) ) {
     if ( this.length > 0 ) {
        var temp = makeJavaArray('String',this.length);
        var i=0; while ( i < this.length ) { temp[i] = ''+this[i++]; }
        return temp;
        }
     else {
        return null;
        }
     }
  else {
     if ( /^\bobject\b$/i.test(typeof(arg_)) ) {
        if ( this.length == 0 ) {
           var len = java.lang.reflect.Array.getLength(arg_);
           var i=0; while ( i < len ) { this[i] = ''+arg_[i++]; }
           }
        }
     }
  }

function makeJavaArray(type_,size_) {
  if ( !/^\bnull\b$|^\bundefined\b$|^\s?$/i.test(type_) ) {
   if (
    /boolean|byte|int|long|short|double
        |float|char|void|String|Object|Class|Thread/.test(type_)
    ) {
    var type = type_.charCodeAt(0)<91 ? 'java.lang.' + type_: type_;
    var size = !isNaN(Number(size_)) ? Number(size_) : 1;
    return ( new
       java.lang.reflect.Array.newInstance
             (java.lang.Class.forName(type),size)
       );
     } // else invalid cast
  } // else invalid args
}

blog comments powered by Disqus