1

使用 DJ Native Swing 可以在 Java 应用程序中显示网页。当您这样做时,也可以使用“命令”协议从浏览器与 java 运行时环境进行通信。该文档有一个代码片段,演示了它的用法:


function sendCommand( command ){
    var s = 'command://' + encodeURIComponent( command );

    for( var i = 1; i < arguments.length; s+= '&' + encodeURIComponent( arguments[i++] ) );
      window.location = s;
}

看起来这里似乎是使用命令协议而不是 http 对 url 的常规 GET 请求。虽然当我创建和图像、脚本标记或只是和 ajax 获取请求时没有响应并且没有触发 java 运行时中的断点。

我不想设置 window.location 因为我不想离开我当前所在的页面。使用链接导航到命令 url 确实有效,但它也会导航离开当前页面。该页面使用 OpenLayers 和 dojo。(我也试过dojo.io.script

4

1 回答 1

2

经过一番工作,我找到了一种与 java 运行时通信的简洁方法,每次通信时都不会触发页面刷新。它的灵感来自于 JSONP 在当今大多数浏览器中绕过跨域限制的工作方式。因为 iFrame 也会触发command://url,所以可以使用这种技术执行类似 JSONP 的操作。客户端(浏览器)的代码:


dojo.provide( "nmpo.io.java" );
dojo.require( "dojo.io.script" );

nmpo.io.java = dojo.delegate( dojo.io.script, { 
    attach: function(/*String*/id, /*String*/url, /*Document?*/frameDocument){
        //  summary:
        //      creates a new  tag pointing to the specified URL and
        //      adds it to the document.
        //  description:
        //      Attaches the script element to the DOM.  Use this method if you
        //      just want to attach a script to the DOM and do not care when or
        //      if it loads.        
        var frame = dojo.create( "iframe", { 
            id: id,
            frameborder:  0,
            framespacing: 0
        }, dojo.body( ) );

        dojo.style( frame, { display: "none" } );
        dojo.attr( frame, { src: url } );
        return frame;
    },

    _makeScriptDeferred: function(/*Object*/args){
        //summary: 
        //      sets up a Deferred object for an IO request.
        var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);

        var ioArgs = dfd.ioArgs;
        ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
        ioArgs.canDelete = false;

        //Special setup for jsonp case
        ioArgs.jsonp = args.callbackParamName || args.jsonp;

        if(ioArgs.jsonp){
            //Add the jsonp parameter.
            ioArgs.query = ioArgs.query || "";
            if(ioArgs.query.length > 0){
                ioArgs.query += "&";
            }
            ioArgs.query += ioArgs.jsonp
                + "="
                + (args.frameDoc ? "parent." : "")
                + "nmpo.io.java.jsonp_" + ioArgs.id + "._jsonpCallback";

            ioArgs.frameDoc = args.frameDoc;

            //Setup the Deferred to have the jsonp callback.
            ioArgs.canDelete = true;
            dfd._jsonpCallback = this._jsonpCallback;
            this["jsonp_" + ioArgs.id] = dfd;
        }
        return dfd; // dojo.Deferred
    }
});

当一个请求被发送到 java 运行时,一个回调参数将被提供,并且webBrowser.executeJavascript( callbackName + "(" + json + ");" );可以执行一个动作来触发浏览器中的回调。

使用示例客户端:


dojo.require( "nmpo.io.java" );
nmpo.io.java.get({
    // For some reason the first paramater (the one after the '?') is never in the
    // paramater array in the java runtime. As a work around we stick in a dummy.
    url: "command://sum?_",
    callbackParamName: "callback",
    content: {
        numbers: [ 1, 2, 3, 4, 5 ].join( "," )
    },
    load: function( result ){
        console.log( "A result was returned, the sum was [ " + result.result + " ]" );  
    }   
});

用法示例java:


webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
    @Override
    public void commandReceived(WebBrowserCommandEvent e) {
        // Check if you have the right command here, left out for the example
        // Parse the paramaters into a Hashtable or something, also left out for the example
        int sum = 0;
        for( String number : arguments.get( "numbers" ).split( "," ) ){
            sum += Integer.parseInt( number );
        }

        // Execute the javascript callback like would happen with a regular JSONP call.
        webBrowser.executeJavascript( arguments.get( "callback" ) + "({ result: " + sum + " });" );
    }
});

同样在框架中使用 IE,我强烈建议使用 firebug lite,IE 的开发工具不可用。

于 2010-11-04T12:58:23.943 回答