【问题标题】:Safari kills Java applet which launched an (idle) JFileChooserSafari 杀死了启动(空闲)JFileChooser 的 Java 小程序
【发布时间】:2012-03-09 13:41:04
【问题描述】:

我需要在网页中弹出一个文件打开对话框,并让用户选择一个文件(不用于上传!)。因为我需要访问完整的文件路径,所以我不能使用表单/输入。因此,我使用签名的 Java 小程序。

在我的测试用例中,Java 小程序方法是从 javascript 函数中调用的。 applet 方法打开一个文件打开对话框(JFileChooser)。如果闲置约。 30",小程序被 Safari(*) 杀死。在我的测试中,Chrome 更好,它会弹出“无响应”警报,而 Firefox 显然不在乎。

IIUC,这是 Safari 特有的行为,但非常不方便。我需要该对话框一直保持到用户做出选择为止。我查看了线程化 JFileChooser,但该路径似乎要复杂得多,并且出于已知的安全原因,仅在 Javascript 中完成所有工作是不可能的。你有一个干净的解决方案吗?

(*) JVM 以 InterruptedException 结束

【问题讨论】:

  • 可以用回调而不是“模态对话框”来实现它吗?它仍然可以是类似模式的(例如,始终在顶部)对话框。需要让 JavaScript 返回到它的主事件泵...
  • 能否请您详细说明一下,或者指出一些更详细的信息?
  • “在我的测试用例中,一个 Java 小程序方法是从一个 javascript 函数中调用的。” 也许浏览器注意到 JS 需要很长时间才能完成,这就是致命的原因它。如果是这种情况,解决方案可能是让小程序在完成后调用脚本。这样脚本就不会“阻塞浏览器”。
  • @AndrewThompson 感谢您的解释,这就是我的想法,但我不确定细节。

标签: java safari applet jfilechooser


【解决方案1】:

您的问题源于这样一个事实,即 Java 中的对话框表现为阻塞方法调用(它实际上是一个了不起的工程技巧,我希望其他工具包能够采用)。因此,当您的 javascript 在 Java 代码上调用该方法时,它正在等待该对话框被关闭。浏览器检测到 javascript 线程有一段时间没有返回,并简单地确定它已死锁并杀死它。因此,Java 小程序随页面一起关闭。

您需要将其转换为异步样式交互。 Javascript 进行的调用应立即返回。您可以在 Java 中使用 SwingUtilities.invokeLater() 将该调用推离 Javascript 调用线程。诀窍是一旦对话框被关闭,您需要 Java 来调用 Javascript。因此,您将让 javascript 注册某种回调机制。类似于以下内容。我不记得外部 javascript -> java 是如何工作的,所以这只是说明这个想法的伪代码:

function showFileDialog() {
    applet.showFileDialog( function( filepath ) {
       if( filepath ) {
          alert( "Hey they picked " + filepath );
       } // must have hit cancel if filepath is null
    } );
}

同时在 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 );
        }
    });
}

【讨论】:

  • 哦,伙计,我在开发一个完全通过阻塞 JDialogs 实现的应用程序时所经历的痛苦……我不知道我是否希望在另一个工具包上实现这一点。 ;)
  • @chubbard 感谢代码 sn-ps,他们让我朝着正确的方向前进。完整的解决方案稍微复杂一些,因为它包括一个签名的小程序,但基本上看起来像上面那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
相关资源
最近更新 更多