7

After many years of successfully maintaining an applet that uses the good old:

<script src="foo.js"></script> 

method of embedding a Java applet, we're unable to cover our ears and sing "La la la!" anymore.

It's time to be using:

deployJava.runApplet()

When I fire this method using a click handler (here using an event listener on a button via jQuery, but it doesn't matter):

$('#button').click(function() {
  deployJava.runApplet(attributes, parameters, version);
});

...it wipes out the entire existing document and replaces it with the applet. All I need to know is how to target a specific DOM element to be the container for the applet, so that my page doesn't get wiped.

It seems like it would be an attribute I could pass in the form of target: someElement where "someElement" is either a DOM object or the element's ID as a string. But alas, I can't find documentation for such an attribute.

For the sake of being complete, here's what's being passed:

/*here is where I imagine there might be an applicable attribute */
var attributes = {
  name: "SomeName",
  code: "some.class",
  archive: "some.jar",
  width: 640,
  height: 400
};

var parameters = {
  someParameter: someValue
};

var version = "1.5";

I can document.write everything I need to rebuild a document, but I'm sure you can all well imagine how hideous that prospect seems to me.

Any pointers would be greatly appreciated.

slm
  • 15,396
  • 12
  • 109
  • 124
Greg Pettit
  • 10,749
  • 5
  • 53
  • 72
  • A bit more code and less text would have been better :-) – fvu Nov 22 '12 at 17:48
  • There's no code to speak of. I'll update just to show you, though. ;-) – Greg Pettit Nov 22 '12 at 17:53
  • 1
    Check out [dtjava.js](http://docs.oracle.com/javafx/2/deployment/deployment_toolkit.htm#FBJHAIHG), deployJava's younger brother that doesn't document.write – fvu Nov 22 '12 at 18:36
  • Looks promising. Not sure I'll have buy-in from the other stakeholders, but that seems to be the best alternative. The only other thing to do is never call the function dynamically (just call it during page render). – Greg Pettit Nov 22 '12 at 19:25
  • You might statically write the link into an element using `deployJava.js` that is dynamically set visible by changing the styles. – Andrew Thompson Nov 22 '12 at 23:49
  • That's an option worth exploring, Andrew. I can't remember for sure, but it seems to me that applets don't play well in non-displayed elements. Might be able to send it off-canvas at least, if 'display:none' doesn't work. – Greg Pettit Nov 23 '12 at 15:35
  • Think I had the same problem. No clean solution tho. http://stackoverflow.com/questions/13191111/trouble-to-display-deployjava-button-on-ajax-rerender . – Aksel Willgert Nov 23 '12 at 15:49

4 Answers4

7

As alternative to Christophe Roussy solution you may override document.write while running deployJava.runApplet.

Like so:

function docWriteWrapper(func) {
    var writeTo = document.createElement('del'),
        oldwrite = document.write,
        content = '';
    writeTo.id = "me";
    document.write = function(text) {
        content += text;
    }
    func();
    writeTo.innerHTML += content;
    document.write = oldwrite;
    document.body.appendChild(writeTo);
}

An then:

docWriteWrapper(function () {
    deployJava.runApplet(attributes, parameters, "1.6");
});

A little bit hackish but works like a charm;)

Community
  • 1
  • 1
Kolya Ay
  • 353
  • 3
  • 8
  • Wow, thanks for taking the time to bump and reply to this, Kolya! Certainly worth at least trying out! I'm too forgetful, so I'm going to go out on a limb and "accept" this... certainly the code looks plausible on visual inspection. :) – Greg Pettit Apr 15 '13 at 16:42
  • On a side note, the product is going to switch over to JNLP sooner than later, but I think we'll always have an applet option. – Greg Pettit Apr 15 '13 at 16:42
  • if you could take the time to add a few explanatory comments, it would have been great! – vasilisdmr Oct 20 '20 at 14:19
4

So the core of the problem is this: deployJava.js uses document.write. If you use this method AFTER page render (vs. as a part of the initial page render) it will first clear the document. Which has obvious negative repurcussions.

Although intended for JavaFX, people have reported success with dtjava.js, and I have every reason to believe it's a viable alternative.

However, other stakeholders on my team have already done work surrounding deployJava.js and are unwilling to throw away that work, which meant I needed to stick to deployJava.js. There's only one way to do this: make sure that deployJava is called during page render, not via Ajax, event, or other delayed trigger.

In the end, we are collecting our information, and passing it to a second page which will render the applet as expected. It works, and in most scenarios our clients will be doing this anyhow (collecting information, passing it server-side, and getting a redirect response), so it didn't make sense to force the issue. We are passing information via query string but you could probably use cookies and/or localstorage API instead, if you wanted the window.location to stay cleaner-looking.

Thanks for the replies, even though they were in the comment area. Other replies are still being taken on board if someone has a better way of doing it!

Greg Pettit
  • 10,749
  • 5
  • 53
  • 72
3

If you are using jQuery and want to target a specific dom element, rather than just appending:

function docWriteWrapper(jq, func) {
    var oldwrite = document.write, content = '';
    document.write = function(text) {
        content += text;
    }
    func();
    document.write = oldwrite;
    jq.html(content);
}

docWriteWrapper($('#mydiv'), function () {
    deployJava.runApplet(attributes, parameters, version);
});
jaydfwtx
  • 123
  • 1
  • 7
  • Thanks for the answer! It's funny how some questions have a slow burn, and people keep noticing clever ways to solve problems. Much appreciated! – Greg Pettit May 01 '13 at 22:03
  • This worked perfectly, and provides exactly what was asked for. – Derrick Aug 11 '13 at 00:35
1

To solve this annoying issue I downloaded and hacked deployJava.js at line 316, replaced the line by my own:

  // document.write(n + "\n" + p + "\n" + r);
  myDiv.append(n + "\n" + p + "\n" + r);

Where myDiv is a js global variable set to the desired div before calling runApplet:

myDiv = jQuery('#someDiv');

If you find a less intrusive solution let me know...

Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85