上传Javascript到JavaFX

时间:2013-06-04 20:19:31

标签: javascript webview javafx

我想了解有关JavaFX的更多信息,因此我尝试设置Webview。 我从Oracle网站复制了webview示例并添加了Upcall功能。 但它没有用。实际上我不知道如何在Webview中调试网站。 所以这是java代码:

package boersensim;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;


public class Main extends Application {
private Scene scene;
@Override public void start(Stage stage) {
    // create the scene
    stage.setTitle("Web View");
    scene = new Scene(new Browser(),750,500, Color.web("#666970"));
    stage.setScene(scene);
    //scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
    stage.show();
}

public static void main(String[] args){
    launch(args);
}
}
class Browser extends Region {

final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();

public Browser() {
    //apply the styles
    getStyleClass().add("browser");
    // load the web page
    webEngine.load("test.html");
    //add the web view to the scene
    getChildren().add(browser);

    JSObject jsobj = (JSObject) webEngine.executeScript("window");
    jsobj.setMember("java", new Bridge());
}
private Node createSpacer() {
    Region spacer = new Region();
    HBox.setHgrow(spacer, Priority.ALWAYS);
    return spacer;
}

@Override protected void layoutChildren() {
    double w = getWidth();
    double h = getHeight();
    layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
}

@Override protected double computePrefWidth(double height) {
    return 750;
}

@Override protected double computePrefHeight(double width) {
    return 500;
}
}

class Bridge {
public void exit() {
    //Platform.exit();
    System.out.print("Hello!UPCALL");
}
}

相应的HTML是:

Click<a href="#" onclick="java.exit();">here</a>to exit the application

当我点击链接时没有任何反应。

先谢谢你, 丹尼尔

3 个答案:

答案 0 :(得分:3)

在页面加载事件

上设置Bridge()
webEngine.setJavaScriptEnabled(true);
webEngine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<Worker.State>() {
                public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                    if (newState == Worker.State.SUCCEEDED) {                        
                        JSObject jso = (JSObject) webEngine.executeScript("window");
                        jso.setMember("java", new Bridge());
                    }

                }
            });

答案 1 :(得分:2)

我也遵循了本教程(可能是您使用过的教程): https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx

发现它导致JVM崩溃。所以我在JavaFX jira上报告了一个问题,我收到了以下回复:

  

从7u5开始,要求从JS调用的方法可以在Java意义上访问,即&gt;公共类的公共成员。 (这在文章的最后评论中提到)。在此&gt;特定测试用例中,Bridge应声明为公共类。

     

崩溃是在JDK8中修复的。现在抛出一个异常。

这很有效。

答案 2 :(得分:0)

丹尼尔(Daniel)代码中需要更改的三件事
1)将班级Bridge设为公开
2)启用webEngine.setJavaScriptEnabled(true);这样的JavaScript
3)在页面加载的事件(如贝娄)上设置Member Bridge()

webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {

        @Override
        public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
            // TODO Auto-generated method stub
             if (newValue == Worker.State.SUCCEEDED) {                        
                 JSObject jso = (JSObject) webEngine.executeScript("window");
                 jso.setMember("java", new Bridge());
             }

        }
    });

欢迎,丹尼尔