【问题标题】:JavaFX + Javascript : How to inject a Java object to an AMD moduleJavaFX + Javascript:如何将 Java 对象注入 AMD 模块
【发布时间】:2015-02-25 08:28:37
【问题描述】:

在试验 JavaFX + HTML5/JS 时,我遇到了 AMD 模块 (RequireJS)。

我知道如何注入 Java 对象并在“老式”Javascript(全局范围内的所有内容)中使用它们,但我现在想知道如何在 RequireJS 模块中注入 Java 对象。

有什么建议吗?


更新 1

由于我觉得我说得不够清楚,让我说得更具体一些。

我的目标是在浏览器控制台和 Java 控制台上显示我的 Javascript 日志,因为我不想包含 firebug-lite.j。为此(以简化的方式):

  1. Java:: 创建一个 DummyLogger 类

.

public class DummyLogger {
    void log(String msg) {
       System.out.println("LOG (JS) : " + msg); 
    }
}
  1. Java:: 将 DummyLogger 实例添加到 Javascript 窗口对象

.

WebView webView = new WebView()
webView.getEngine().load("index.html");
// Inject our Java logger interface to JS
final JSObject jsWnd = (JSObject) webView.getEngine().executeScript("window");
jsWnd.setMember("javaLogger", logger);
  1. Javascript:: 在我的模块“module/logger.js”中,公开一个日志函数,该函数同时使用 JS 控制台和 javaLogger(如果已定义)

.

define(function() {
    return {
        log: function(message) {
            console.log(message);

            // Forward to the injected Java logger only if it is defined
            if(typeof javaLogger !== 'undefined') {
                javaLogger.log(message);
            }
        }
    }
}

现在,我想知道是否可以在不污染窗口命名空间的情况下将 javaLogger 对象注入到 logger 模块(这有点像 AMD...)。

我的想法是做这样的事情:

  • 在 JS logger 模块上添加函数 setJavaLogger(logger)。
  • 使用该 setter 将 javaLogger 直接注入到 logger 模块

.

WebView webView = new WebView()
WebEngine engine = webView.getEngine();

engine.getLoadWorker().stateProperty().addListener(
    (observable, oldState, newState) -> {
        if (newState == Worker.State.SUCCEEDED) {
            final JSObject retVal = (JSObject) engine.executeScript(
                "require(['module/logger'], function(logger) { return logger; });"
            );
            retVal.call("setJavaLogger", logger);
        }
    }
);

engine.load("index.html");

不幸的是,这无济于事。 require 函数有返回值吗?

甚至可以在 Java 中检索我的记录器模块吗?

【问题讨论】:

  • 我刚刚读到:docs.oracle.com/javase/7/docs/technotes/guides/scripting/…。尽管明确说明了如何从 Javascript 调用 System.out.println(),但我仍然想知道如何正确地将 Java 对象注入 AMD 模块。我希望我的 Javascript 代码独立于 Java 类。我在这里尝试做的只是对 Java 和 Javascript 之间可能的交互的一个实验。

标签: java javascript javafx requirejs amd


【解决方案1】:

在 Java 中,可以通过以下方式访问 RequireJS 模块:

WebView webView = new WebView();
WebEngine engine = webView.getEngine();
engine.load("path/to/index.html");

// Assuming that somewhere in 'index.html', the loading of "module/logger" is triggered...

{ ... let some time pass ...} // 

final JSObject loggerModule = (JSObject) engine.executeScript(
    "require('module/logger')"
);
logger.call("trace", "hello world!");

警告: HTML 页面和 RequireJS 模块的加载都是异步的!

require(String) 的执行可能会失败并抛出 netscape.javascript.JSException,因为尚未加载 'module/logger'。此类异常应如下所示:

netscape.javascript.JSException: Error: Module name "module/logger" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
    at com.sun.webkit.dom.JSObject.fwkMakeException(JSObject.java:128)
    at com.sun.webkit.WebPage.twkExecuteScript(Native Method)
    at com.sun.webkit.WebPage.executeScript(WebPage.java:1426)
    at javafx.scene.web.WebEngine.executeScript(WebEngine.java:948)
    many more...

您将不得不找到一种或多或少有创意的方式来等待模块加载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多