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 }