Javascript <=> Java interop

V

VK

I would be glad for comments on my j2j.class applet. It uses JSObject
and MAYSCRIPT applet flag for either way communication between
Javascript and Java. For the testing purposes it is minimalistic:
Javascript function calls applet public method and applet in turn
calls the callback Javascript function. All relevant comments are in
Java source. Compiled class if needed at http:\\javascript.myplus.org/
j2j.class

HTML page:

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script>
function test() {
var japp = document.getElementById('J2J');
japp.callJava(['echo', 'foo']);
}

function echo() {
window.alert('Java applet says: "Here!"');
}
</script>
</head>

<body>

<p><applet id="J2J" width="12" height="12" code="j2j.class" mayscript>
<param name="bgcolor" value="#FF0000">
<dfn style="color:red"
title="Java applet is not launched">Java</dfn>
</applet></p>

<p><button type="button" onclick="test()">Test</button></p>

</body>
</html>


Java j2j.class source:

/********************************************
* Java <=> JavaScript interoperability
*
* This applet needs to be run on a HTML page
* with <applet> tag properly set in order to
* be fully functional.
*
* This applet is written to be compatible
* with any Java platform down to JDK 1.1,
* so no Swing extensions are used.
*
* Programmed by VK [[email protected]]
*
********************************************/


import java.awt.*;


import java.applet.*;


import netscape.javascript.*;
/* LiveConnect package will be used to communicate between
* Java applet and JavaScript/DOM methods on the HTML page.
* Remember that the JVM used at the development time has
* nothing to do with the JVM used by browsers to run your
* applet. Respectively if you decide to recompile this
* applet using JCreator, NetBeans or any other IDE tool
* you'll get a package loading error. To make it work you
* have to add LiveConnect package to your classpath.
* Depending on what JMV plugin you already have installed,
* there are several places to choose from:
* 1. Sun Java plug-in
* Add to your classpath plugin.jar which is located in
* the /lib subdirectory of the installed plugin, e.g.:
* C:\Program Files\Java\jre1.6.0_07\lib\plugin.jar
* Note: Sun plug-ins prior JRE 1.4.2 have this package
* named jaws.jar so look for it instead if you have an
* ancient JRE plug-in installed and nothing else.
* 2. Microsoft JVM (MJVM)
* Add to your classpath plugin.jar which is harder to
* locate because the MJVM installer places packages in
* randomly named folders as a security mesure. Search
* in \%Systemroot%\Java sub-folders for the .cab file
* containing plugin.jar and add it to the classpath.
* 3. Netscape 3.x - 4.x JVM
* Add to your classpath java40.jar which is located in
* \java\classes subdirectory inside the Netscape setup
* directory.
*
* It is absolutely irrelevant from where the package comes
* from and even if it contains anything usable at all.
* At runtime on a HTML page applets will use the package
* from the available plug-in that runs the applet. And for
* Java IDE you cannot test and work with JSObject anyway,
* it will give you an Error. So all this buzz from above
* is only to pacify the compiler so you could get .class
* from your .java source. The testing has to be done after
* that from a HTML page.
*
* For curious ones:
* internally netscape.javascript.* subclasses and extends
* sun.plugin.javascript.* package members located in the
* same .jar archive.
*
* MAYSCRIPT !
* Do not forget to add mayscript flag attribute to your
* applet tag: <applet ... mayscript>
* By default LiveConnect is disabled and an attempt to use
* JSObject will be ignored (loopholed) or it will raise a
* security exception.
* To have LiveConnect enabled for an applet, set mayscript
* flag on.
* Do not use <object> and do not use pseudo-XHTML syntax
* like mayscript="true". Use the universally supported
* <applet> tag and mayscript attribute without any value.
*
* SIZE does matter !
* Java applets have security restriction for their minimum
* size: 10px X 10px. In the past there were discrepancies
* between browsers to treat it as "no lesser than 10px" or
* "starting from 10px and lesser". To be on the safe side,
* use 11px or 12px for WIDTH and HEIGHT. So it can be like
*
* <applet width="12" height="12" code="j2j.class" mayscript>
* <param name="bgcolor" value="#C0C0C0">
* <dfn style="color:red"
* title="Java applet is not launched">Java</dfn>
* </applet>
*/




public class j2j extends Applet {

// String to return on getAppletInfo() call:
final String appletInfo = "j2j v.1.2";


// If bgcolor parameter is missing or invalid then
// applet canvas will be painted in this color:
Color defaultBgColor = Color.WHITE;


// Applet may fail to instantiate JSObject or the
// communication may be blocked, yet it should be
// still running at least for the reason to not
// make a black or gray spot on your HTML page.
// mayScript flag (set to true if JSObject is OK)
// is used to check before LiveConnect-related
// operations:
boolean mayScript = false;


// [window] host object reference holder:
JSObject Win;


// [document] object reference holder:
JSObject Doc;




public void init() {

setBgColor();

}




public void start() {

// While [window] object is available immediately,
// DOM object may not be available on init() stage
// so it is more reliable to obtain the necessary
// references on start() stage.

getJSObjects();

}




public void stop() {

/* NOP */

}




public void destroy() {

// Release references, most importantly DOM refs.

Win = null;
Doc = null;

}




synchronized Object callJavaScript(String method,
Object[] args) {

if (mayScript) {
Win.call(method, args);
}

return null;

}




public synchronized boolean callJava(Object[] Args) {

String method;

Object[] args;

int i;

if (mayScript && Args.length >= 1) {

method = (String)Args[0];

// honnestly hate this:
args = new Object[Args.length-1];
for (i = 1; i < Args.length; i++) {
args[i-1] = Args;
}
// end of hate

callJavaScript(method, args);
return true;
}

else {
return false;
}

}




void setBgColor() {

String bgColor;

int r, g, b;

Color c;

bgColor = this.getParameter("bgcolor");
if (bgColor == null) {
this.setBackground(defaultBgColor);
}
else {
if ( bgColor.startsWith("#") && bgColor.length() == 7 ) {
try {
r = Integer.parseInt(bgColor.substring(1,3), 16);
g = Integer.parseInt(bgColor.substring(3,5), 16);
b = Integer.parseInt(bgColor.substring(5,7), 16);
c = new Color(r, g, b);
this.setBackground(c);
}
catch (Exception e) {
this.setBackground(defaultBgColor);
}
}
else {
this.setBackground(defaultBgColor);
}
}

}




void getJSObjects() {

String errorMessage = "";

try {
Win = JSObject.getWindow(this);
Doc = (JSObject)Win.getMember("document");
}
catch (Exception e) {
errorMessage = "JSObject interop is disabled: " +
"possibly \"mayscript\" flag is not set.";
}
catch (Error err) {
errorMessage = "You cannot operate with JSObject " +
"if your applet is running stay-alone: run it in " +
"a browser as a component of a HTML page.";
}
finally {
if (errorMessage.equals("")) {
mayScript = true;
}
else {
System.err.println(errorMessage);
}
}

}




public String getAppletInfo() {

return appletInfo;

}




}

end of Java source
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top