I need to pop-up a file open dialog in a web page, and have the user select a file (not for upload!). Because I need access to the full file path, I cannot use a form/input. Thus, I use a signed Java applet.
In my test case a Java applet method is called from a javascript function. The applet method opens a file open dialog (JFileChooser). If left idle for approx. 30", the applet gets killed by Safari(*). In my testing Chrome is nicer, it pops-up the "unresponsive" alert, whereas Firefox apparently doesn't care.
IIUC, this is a Safari-specific behavior, but it is very inconvenient. I need that dialog to stay up until the user makes a choice. I looked at threading the JFileChooser but that path seems to be way more complicated, and doing all the work in Javascript alone is not possible, for known security reasons. Do you have a clean solution to this?
(*) JVM ends in an InterruptedException
Your problem stems from the fact that dialogs in Java behave as blocking method calls (its actually an amazing engineering trick how they do it that I wish other toolkits would adopt). So when your javascript invokes the method onto the Java code it's waiting for that dialog to be dismissed. The browser detects that the javascript thread hasn't returned in a while and simply decides it's dead locked and kills it. Hence the Java applet goes down with the page.
You'll need to transition that into an asynchronous style interaction. The call Javascript makes should return immediately. You can use SwingUtilities.invokeLater() in Java to push that call off the Javascript calling thread. The trick then is once the dialog is dismissed you need Java to call Javascript. So you'll have javascript register some sort of callback mechanism. Something like the following. I can't remember how external javascript -> java works exactly so this is just pseudo code to illustrate the idea:
function showFileDialog() {
applet.showFileDialog( function( filepath ) {
if( filepath ) {
alert( "Hey they picked " + filepath );
} // must have hit cancel if filepath is null
} );
}
Meanwhile in Java:
public void showFileDialog( JavascriptFunction someJavascriptFunction ) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
JFileChooserDialog chooser = new JFileChooser();
...
int option = chooser.showOpenDialog( parent );
someJavascriptFunction.invoke( option == JFileChooser.APPROVE_OPTION ?
chooser.getSelectedFile().getAbsolutePath() :
null );
}
});
}