Hacky way (relies on singleton) to get FX working. Can attach @On(event=CLICK) and show alert in FX WebView now fx
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 14 Mar 2013 09:22:28 +0100
branchfx
changeset 845859804c78010
parent 844 023cda5b8b0b
child 851 c285a78302af
Hacky way (relies on singleton) to get FX working. Can attach @On(event=CLICK) and show alert in FX WebView now
javaquery/api/pom.xml
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java
javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java
rt/launcher/pom.xml
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/WebViewLauncher.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/FXBrwsr.java
rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/JVMBridge.java
     1.1 --- a/javaquery/api/pom.xml	Wed Mar 13 16:20:03 2013 +0100
     1.2 +++ b/javaquery/api/pom.xml	Thu Mar 14 09:22:28 2013 +0100
     1.3 @@ -73,5 +73,12 @@
     1.4        <version>${project.version}</version>
     1.5        <scope>test</scope>
     1.6      </dependency>
     1.7 +    <dependency>
     1.8 +        <groupId>com.oracle</groupId>
     1.9 +        <artifactId>javafx</artifactId>
    1.10 +        <version>2.2</version>
    1.11 +        <scope>system</scope>
    1.12 +        <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
    1.13 +    </dependency>
    1.14    </dependencies>
    1.15  </project>
     2.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Wed Mar 13 16:20:03 2013 +0100
     2.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/PageProcessor.java	Thu Mar 14 09:22:28 2013 +0100
     2.3 @@ -265,7 +265,8 @@
     2.4              }
     2.5              w.append("  }\n");
     2.6              if (dispatchCnt > 0) {
     2.7 -                w.append("class OnDispatch implements OnHandler {\n");
     2.8 +                // XXX: sun.misc.Trampoline cannot call public methods in non-public classes
     2.9 +                w.append("public class OnDispatch implements OnHandler {\n");
    2.10                  w.append("  private final int dispatch;\n");
    2.11                  w.append("  OnDispatch(int d) { dispatch = d; }\n");
    2.12                  w.append("  public void onEvent(Object ev) {\n");
     3.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Wed Mar 13 16:20:03 2013 +0100
     3.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/api/Element.java	Thu Mar 14 09:22:28 2013 +0100
     3.3 @@ -17,6 +17,8 @@
     3.4   */
     3.5  package org.apidesign.bck2brwsr.htmlpage.api;
     3.6  
     3.7 +import javafx.scene.web.WebEngine;
     3.8 +import netscape.javascript.JSObject;
     3.9  import org.apidesign.bck2brwsr.core.JavaScriptBody;
    3.10  
    3.11  /** Represents a generic HTML element.
    3.12 @@ -73,13 +75,26 @@
    3.13          + "};\n"
    3.14      )
    3.15      final void on(OnEvent ev, OnHandler r) {
    3.16 +        WebEngine e = web();
    3.17 +        JSObject add = (JSObject)e.executeScript(
    3.18 +              "var x = {}; x.add = new Function('e','attr','r', "
    3.19 +            + "  'window.document.getElementById(e)[attr] = function(ev) { var d = ev ? ev : null; try { r.onEvent(d); } catch (x) { alert(\"OK\" + r[\"onEvent\"] + \"e\" + d + x); } };'"
    3.20 +            + "); x;");
    3.21 +        add.call("add", id, ev.id, r);
    3.22 +    }
    3.23 +    
    3.24 +    private static WebEngine web() {
    3.25 +        return (WebEngine) System.getProperties().get("webEngine");
    3.26      }
    3.27  
    3.28      /** Shows alert message dialog in a browser.
    3.29       * @param msg the message to show
    3.30       */
    3.31      @JavaScriptBody(args = "msg", body = "alert(msg);")
    3.32 -    public static native void alert(String msg);
    3.33 +    public static void alert(String msg) {
    3.34 +        JSObject obj = (JSObject) web().executeScript("window");
    3.35 +        obj.call("alert", msg);
    3.36 +    }
    3.37  
    3.38      /** Generic way to query any attribute of this element.
    3.39       * @param property name of the attribute
     4.1 --- a/rt/launcher/pom.xml	Wed Mar 13 16:20:03 2013 +0100
     4.2 +++ b/rt/launcher/pom.xml	Thu Mar 14 09:22:28 2013 +0100
     4.3 @@ -58,6 +58,12 @@
     4.4        <groupId>${project.groupId}</groupId>
     4.5        <artifactId>vm4brwsr</artifactId>
     4.6        <version>${project.version}</version>
     4.7 +      <exclusions>
     4.8 +        <exclusion>
     4.9 +          <artifactId>emul.mini</artifactId>
    4.10 +          <groupId>org.apidesign.bck2brwsr</groupId>
    4.11 +        </exclusion>
    4.12 +      </exclusions>
    4.13      </dependency>
    4.14    </dependencies>
    4.15  </project>
     5.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Wed Mar 13 16:20:03 2013 +0100
     5.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Thu Mar 14 09:22:28 2013 +0100
     5.3 @@ -91,6 +91,10 @@
     5.4      public void addClassLoader(ClassLoader url) {
     5.5          this.loaders.add(url);
     5.6      }
     5.7 +    
     5.8 +    ClassLoader[] loaders() {
     5.9 +        return loaders.toArray(new ClassLoader[loaders.size()]);
    5.10 +    }
    5.11  
    5.12      public void showURL(String startpage) throws IOException {
    5.13          if (!startpage.startsWith("/")) {
    5.14 @@ -144,7 +148,7 @@
    5.15  
    5.16          final ServerConfiguration conf = s.getServerConfiguration();
    5.17          if (addClasses) {
    5.18 -            conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
    5.19 +            conf.addHttpHandler(new VM(this, resources), "/bck2brwsr.js");
    5.20              conf.addHttpHandler(new Classes(resources), "/classes/");
    5.21          }
    5.22          return s;
    5.23 @@ -436,6 +440,27 @@
    5.24          }
    5.25      }
    5.26  
    5.27 +    void generateBck2BrwsrJS(StringBuilder sb, Bck2Brwsr.Resources loader) throws IOException {
    5.28 +        Bck2Brwsr.generate(sb, loader);
    5.29 +        sb.append(
    5.30 +            "(function WrapperVM(global) {"
    5.31 +            + "  function ldCls(res) {\n"
    5.32 +            + "    var request = new XMLHttpRequest();\n"
    5.33 +            + "    request.open('GET', '/classes/' + res, false);\n"
    5.34 +            + "    request.send();\n"
    5.35 +            + "    if (request.status !== 200) return null;\n"
    5.36 +            + "    var arr = eval('(' + request.responseText + ')');\n"
    5.37 +            + "    return arr;\n"
    5.38 +            + "  }\n"
    5.39 +            + "  var prevvm = global.bck2brwsr;\n"
    5.40 +            + "  global.bck2brwsr = function() {\n"
    5.41 +            + "    var args = Array.prototype.slice.apply(arguments);\n"
    5.42 +            + "    args.unshift(ldCls);\n"
    5.43 +            + "    return prevvm.apply(null, args);\n"
    5.44 +            + "  };\n"
    5.45 +            + "})(this);\n");
    5.46 +    }
    5.47 +
    5.48      private class Res implements Bck2Brwsr.Resources {
    5.49          @Override
    5.50          public InputStream get(String resource) throws IOException {
    5.51 @@ -498,27 +523,10 @@
    5.52      private static class VM extends HttpHandler {
    5.53          private final String bck2brwsr;
    5.54  
    5.55 -        public VM(Res loader) throws IOException {
    5.56 +        public VM(Bck2BrwsrLauncher l, Res loader) throws IOException {
    5.57              StringBuilder sb = new StringBuilder();
    5.58 -            Bck2Brwsr.generate(sb, loader);
    5.59 -            sb.append(
    5.60 -                  "(function WrapperVM(global) {"
    5.61 -                + "  function ldCls(res) {\n"
    5.62 -                + "    var request = new XMLHttpRequest();\n"
    5.63 -                + "    request.open('GET', '/classes/' + res, false);\n"
    5.64 -                + "    request.send();\n"
    5.65 -                + "    if (request.status !== 200) return null;\n"
    5.66 -                + "    var arr = eval('(' + request.responseText + ')');\n"
    5.67 -                + "    return arr;\n"
    5.68 -                + "  }\n"
    5.69 -                + "  var prevvm = global.bck2brwsr;\n"
    5.70 -                + "  global.bck2brwsr = function() {\n"
    5.71 -                + "    var args = Array.prototype.slice.apply(arguments);\n"
    5.72 -                + "    args.unshift(ldCls);\n"
    5.73 -                + "    return prevvm.apply(null, args);\n"
    5.74 -                + "  };\n"
    5.75 -                + "})(this);\n"
    5.76 -            );
    5.77 +            l.generateBck2BrwsrJS(
    5.78 +                  sb, loader);
    5.79              this.bck2brwsr = sb.toString();
    5.80          }
    5.81  
     6.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Wed Mar 13 16:20:03 2013 +0100
     6.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Thu Mar 14 09:22:28 2013 +0100
     6.3 @@ -102,7 +102,7 @@
     6.4       * @throws IOException if something goes wrong
     6.5       */
     6.6      public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
     6.7 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
     6.8 +        Bck2BrwsrLauncher l = new WebViewLauncher();
     6.9          l.addClassLoader(classes);
    6.10          l.showURL(startpage);
    6.11          return l;
    6.12 @@ -116,7 +116,7 @@
    6.13       * @exception IOException if something goes wrong.
    6.14       */
    6.15      public static Closeable showDir(File directory, String startpage) throws IOException {
    6.16 -        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
    6.17 +        Bck2BrwsrLauncher l = new WebViewLauncher();
    6.18          l.showDirectory(directory, startpage);
    6.19          return l;
    6.20      }
     7.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/WebViewLauncher.java	Wed Mar 13 16:20:03 2013 +0100
     7.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/WebViewLauncher.java	Thu Mar 14 09:22:28 2013 +0100
     7.3 @@ -17,47 +17,32 @@
     7.4   */
     7.5  package org.apidesign.bck2brwsr.launcher;
     7.6  
     7.7 +import org.apidesign.bck2brwsr.launcher.impl.FXBrwsr;
     7.8  import java.io.IOException;
     7.9  import java.lang.reflect.Method;
    7.10  import java.net.URI;
    7.11  import java.net.URL;
    7.12  import java.net.URLClassLoader;
    7.13  
    7.14 -import java.util.List;
    7.15  import java.util.concurrent.Executors;
    7.16 -import javafx.application.Application;
    7.17 +import java.util.logging.Level;
    7.18 +import java.util.logging.Logger;
    7.19  import javafx.application.Platform;
    7.20 -import javafx.beans.value.ChangeListener;
    7.21 -import javafx.beans.value.ObservableValue;
    7.22 -import javafx.event.ActionEvent;
    7.23 -import javafx.event.EventHandler;
    7.24 -import javafx.geometry.HPos;
    7.25 -import javafx.geometry.Insets;
    7.26 -import javafx.geometry.VPos;
    7.27 -import javafx.scene.Node;
    7.28 -import javafx.scene.Scene;
    7.29 -import javafx.scene.control.Button;
    7.30 -import javafx.scene.control.TextField;
    7.31 -import javafx.scene.layout.ColumnConstraints;
    7.32 -import javafx.scene.layout.GridPane;
    7.33 -import javafx.scene.layout.Pane;
    7.34 -import javafx.scene.layout.Priority;
    7.35 -import javafx.scene.layout.VBox;
    7.36 -import javafx.scene.web.WebEngine;
    7.37 -import javafx.scene.web.WebView;
    7.38 -import javafx.stage.Stage;
    7.39 +import org.apidesign.bck2brwsr.launcher.impl.JVMBridge;
    7.40 +import org.apidesign.vm4brwsr.Bck2Brwsr;
    7.41  
    7.42  /**
    7.43   *
    7.44   * @author Jaroslav Tulach <jtulach@netbeans.org>
    7.45   */
    7.46  final class WebViewLauncher extends Bck2BrwsrLauncher {
    7.47 +    private static final Logger LOG = Logger.getLogger(WebViewLauncher.class.getName());
    7.48      static {
    7.49          try {
    7.50              Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
    7.51              m.setAccessible(true);
    7.52              URL l = new URL("file://" + System.getProperty("java.home") + "/lib/jfxrt.jar");
    7.53 -            System.err.println("url : " + l);
    7.54 +            LOG.log(Level.INFO, "url : {0}", l);
    7.55              m.invoke(ClassLoader.getSystemClassLoader(), l);
    7.56          } catch (Exception ex) {
    7.57              throw new LinkageError("Can't add jfxrt.jar on the classpath", ex);
    7.58 @@ -71,108 +56,39 @@
    7.59      @Override
    7.60      protected Object[] showBrwsr(final URI url) throws IOException {
    7.61          try {
    7.62 +            JVMBridge.registerClassLoaders(loaders());
    7.63              Executors.newSingleThreadExecutor().submit(new Runnable() {
    7.64                  @Override
    7.65                  public void run() {
    7.66 -                    WebViewBrowser.launch(WebViewBrowser.class, url.toString());
    7.67 +                    FXBrwsr.launch(FXBrwsr.class, url.toString());
    7.68                  }
    7.69              });
    7.70          } catch (Throwable ex) {
    7.71 -            ex.printStackTrace();
    7.72 +            LOG.log(Level.WARNING, "Can't open WebView", ex);
    7.73          }
    7.74          return null;
    7.75      }
    7.76 -
    7.77 +    
    7.78 +    @Override
    7.79 +    void generateBck2BrwsrJS(StringBuilder sb, Bck2Brwsr.Resources loader) throws IOException {
    7.80 +        sb.append("(function() {\n"
    7.81 +            + "  this.jvmBridge = new Array();\n"
    7.82 +            + "  this.jvmBridge.loadClass = Array.prototype.push;\n"
    7.83 +            + "  var bridge = this.jvmBridge;\n"
    7.84 +            + "  this.bck2brwsr = function() { return {\n"
    7.85 +            + "     loadClass : function(name) {\n"
    7.86 +            + "       return bridge.loadClass(name);\n"
    7.87 +            + "     }"
    7.88 +            + "  }; };\n"
    7.89 +            + "})(window);\n"
    7.90 +        );
    7.91 +    }
    7.92 +    
    7.93 +    
    7.94 +    
    7.95      @Override
    7.96      public void close() throws IOException {
    7.97          Platform.exit();
    7.98      }
    7.99      
   7.100 -    
   7.101 -
   7.102 -    /**
   7.103 -     * Demonstrates a WebView object accessing a web page.
   7.104 -     *
   7.105 -     * @see javafx.scene.web.WebView
   7.106 -     * @see javafx.scene.web.WebEngine
   7.107 -     */
   7.108 -    public static class WebViewBrowser extends Application {
   7.109 -
   7.110 -        @Override
   7.111 -        public void start(Stage primaryStage) throws Exception {
   7.112 -            Pane root = new WebViewPane(getParameters().getUnnamed());
   7.113 -            primaryStage.setScene(new Scene(root, 1024, 768));
   7.114 -            primaryStage.show();
   7.115 -        }
   7.116 -
   7.117 -        /**
   7.118 -         * Create a resizable WebView pane
   7.119 -         */
   7.120 -        public class WebViewPane extends Pane {
   7.121 -
   7.122 -            public WebViewPane(List<String> params) {
   7.123 -                VBox.setVgrow(this, Priority.ALWAYS);
   7.124 -                setMaxWidth(Double.MAX_VALUE);
   7.125 -                setMaxHeight(Double.MAX_VALUE);
   7.126 -
   7.127 -                WebView view = new WebView();
   7.128 -                view.setMinSize(500, 400);
   7.129 -                view.setPrefSize(500, 400);
   7.130 -                final WebEngine eng = view.getEngine();
   7.131 -                final TextField locationField = new TextField();
   7.132 -                System.err.println("params : " + params);
   7.133 -                if (params.size() > 0) {
   7.134 -                    eng.load(params.get(0));
   7.135 -                    locationField.setText(params.get(0));
   7.136 -                }
   7.137 -                locationField.setMaxHeight(Double.MAX_VALUE);
   7.138 -                Button goButton = new Button("Go");
   7.139 -                goButton.setDefaultButton(true);
   7.140 -                EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
   7.141 -                    @Override
   7.142 -                    public void handle(ActionEvent event) {
   7.143 -                        eng.load(locationField.getText().startsWith("http://") ? locationField.getText()
   7.144 -                            : "http://" + locationField.getText());
   7.145 -                    }
   7.146 -                };
   7.147 -                goButton.setOnAction(goAction);
   7.148 -                locationField.setOnAction(goAction);
   7.149 -                eng.locationProperty().addListener(new ChangeListener<String>() {
   7.150 -                    @Override
   7.151 -                    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
   7.152 -                        locationField.setText(newValue);
   7.153 -                    }
   7.154 -                });
   7.155 -                GridPane grid = new GridPane();
   7.156 -                grid.setVgap(5);
   7.157 -                grid.setHgap(5);
   7.158 -                GridPane.setConstraints(locationField, 0, 0, 1, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.SOMETIMES);
   7.159 -                GridPane.setConstraints(goButton, 1, 0);
   7.160 -                GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
   7.161 -                grid.getColumnConstraints().addAll(
   7.162 -                    new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true),
   7.163 -                    new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true));
   7.164 -                grid.getChildren().addAll(locationField, goButton, view);
   7.165 -                getChildren().add(grid);
   7.166 -            }
   7.167 -
   7.168 -            @Override
   7.169 -            protected void layoutChildren() {
   7.170 -                List<Node> managed = getManagedChildren();
   7.171 -                double width = getWidth();
   7.172 -                double height = getHeight();
   7.173 -                double top = getInsets().getTop();
   7.174 -                double right = getInsets().getRight();
   7.175 -                double left = getInsets().getLeft();
   7.176 -                double bottom = getInsets().getBottom();
   7.177 -                for (int i = 0; i < managed.size(); i++) {
   7.178 -                    Node child = managed.get(i);
   7.179 -                    layoutInArea(child, left, top,
   7.180 -                        width - left - right, height - top - bottom,
   7.181 -                        0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
   7.182 -                }
   7.183 -            }
   7.184 -        }
   7.185 -    }
   7.186 -    
   7.187  }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/FXBrwsr.java	Thu Mar 14 09:22:28 2013 +0100
     8.3 @@ -0,0 +1,169 @@
     8.4 +/**
     8.5 + * Back 2 Browser Bytecode Translator
     8.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     8.7 + *
     8.8 + * This program is free software: you can redistribute it and/or modify
     8.9 + * it under the terms of the GNU General Public License as published by
    8.10 + * the Free Software Foundation, version 2 of the License.
    8.11 + *
    8.12 + * This program is distributed in the hope that it will be useful,
    8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.15 + * GNU General Public License for more details.
    8.16 + *
    8.17 + * You should have received a copy of the GNU General Public License
    8.18 + * along with this program. Look for COPYING file in the top folder.
    8.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    8.20 + */
    8.21 +package org.apidesign.bck2brwsr.launcher.impl;
    8.22 +
    8.23 +import java.util.List;
    8.24 +import java.util.logging.Level;
    8.25 +import java.util.logging.Logger;
    8.26 +import javafx.application.Application;
    8.27 +import javafx.beans.value.ChangeListener;
    8.28 +import javafx.beans.value.ObservableValue;
    8.29 +import javafx.concurrent.Worker;
    8.30 +import javafx.event.ActionEvent;
    8.31 +import javafx.event.EventHandler;
    8.32 +import javafx.geometry.HPos;
    8.33 +import javafx.geometry.Insets;
    8.34 +import javafx.geometry.VPos;
    8.35 +import javafx.scene.Node;
    8.36 +import javafx.scene.Scene;
    8.37 +import javafx.scene.control.Button;
    8.38 +import javafx.scene.control.TextField;
    8.39 +import javafx.scene.layout.ColumnConstraints;
    8.40 +import javafx.scene.layout.GridPane;
    8.41 +import javafx.scene.layout.Pane;
    8.42 +import javafx.scene.layout.Priority;
    8.43 +import javafx.scene.layout.VBox;
    8.44 +import javafx.scene.web.WebEngine;
    8.45 +import javafx.scene.web.WebEvent;
    8.46 +import javafx.scene.web.WebView;
    8.47 +import javafx.stage.Stage;
    8.48 +import javax.swing.JOptionPane;
    8.49 +import netscape.javascript.JSObject;
    8.50 +
    8.51 +/**
    8.52 + * Demonstrates a WebView object accessing a web page.
    8.53 + *
    8.54 + * @see javafx.scene.web.WebView
    8.55 + * @see javafx.scene.web.WebEngine
    8.56 + */
    8.57 +public class FXBrwsr extends Application {
    8.58 +    private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName());
    8.59 +
    8.60 +    @Override
    8.61 +    public void start(Stage primaryStage) throws Exception {
    8.62 +        Pane root = new WebViewPane(getParameters().getUnnamed());
    8.63 +        primaryStage.setScene(new Scene(root, 1024, 768));
    8.64 +        primaryStage.show();
    8.65 +    }
    8.66 +    
    8.67 +    /**
    8.68 +     * Create a resizable WebView pane
    8.69 +     */
    8.70 +    private class WebViewPane extends Pane {
    8.71 +        private final JVMBridge bridge = new JVMBridge();
    8.72 +
    8.73 +        public WebViewPane(List<String> params) {
    8.74 +            VBox.setVgrow(this, Priority.ALWAYS);
    8.75 +            setMaxWidth(Double.MAX_VALUE);
    8.76 +            setMaxHeight(Double.MAX_VALUE);
    8.77 +            WebView view = new WebView();
    8.78 +            view.setMinSize(500, 400);
    8.79 +            view.setPrefSize(500, 400);
    8.80 +            final WebEngine eng = view.getEngine();
    8.81 +            final TextField locationField = new TextField();
    8.82 +            LOG.info("params : " + params);
    8.83 +            if (params.size() > 0) {
    8.84 +                eng.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
    8.85 +                    @Override
    8.86 +                    public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) {
    8.87 +                        LOG.info("about to init bck2brwsr");
    8.88 +                        initBck2Brwsr(eng);
    8.89 +                        LOG.info("done init of bck2brwsr");
    8.90 +                    }
    8.91 +                });
    8.92 +                LOG.info("loading page " + params.get(0));
    8.93 +                eng.load(params.get(0));
    8.94 +                LOG.info("done loading page ");
    8.95 +                locationField.setText(params.get(0));
    8.96 +            }
    8.97 +            locationField.setMaxHeight(Double.MAX_VALUE);
    8.98 +            Button goButton = new Button("Go");
    8.99 +            goButton.setDefaultButton(true);
   8.100 +            EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
   8.101 +                @Override
   8.102 +                public void handle(ActionEvent event) {
   8.103 +                    eng.load(locationField.getText().startsWith("http://") ? locationField.getText() : "http://" + locationField.getText());
   8.104 +                }
   8.105 +            };
   8.106 +            goButton.setOnAction(goAction);
   8.107 +            locationField.setOnAction(goAction);
   8.108 +            eng.locationProperty().addListener(new ChangeListener<String>() {
   8.109 +                @Override
   8.110 +                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
   8.111 +                    locationField.setText(newValue);
   8.112 +                }
   8.113 +            });
   8.114 +            eng.setOnAlert(new EventHandler<WebEvent<String>>() {
   8.115 +                @Override
   8.116 +                public void handle(WebEvent<String> t) {
   8.117 +                    JOptionPane.showMessageDialog(null, t.getData());
   8.118 +                }
   8.119 +            });
   8.120 +            GridPane grid = new GridPane();
   8.121 +            grid.setVgap(5);
   8.122 +            grid.setHgap(5);
   8.123 +            GridPane.setConstraints(locationField, 0, 0, 1, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.SOMETIMES);
   8.124 +            GridPane.setConstraints(goButton, 1, 0);
   8.125 +            GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
   8.126 +            grid.getColumnConstraints().addAll(new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true), new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true));
   8.127 +            grid.getChildren().addAll(locationField, goButton, view);
   8.128 +            getChildren().add(grid);
   8.129 +        }
   8.130 +
   8.131 +        void initBck2Brwsr(WebEngine webEngine) {
   8.132 +            JSObject jsobj = (JSObject) webEngine.executeScript("window");
   8.133 +            LOG.info("window: " + jsobj);
   8.134 +            System.getProperties().put("webEngine", webEngine);
   8.135 +            Object prev = jsobj.getMember("jvmBridge");
   8.136 +            if (prev instanceof JSObject) {
   8.137 +                jsobj.setMember("jvmBridge", bridge);
   8.138 +                JSObject jso = (JSObject) prev;
   8.139 +                Object len = jso.getMember("length");
   8.140 +                if (len instanceof Integer) {
   8.141 +                    for (int i = 0; i < (Integer) len; i++) {
   8.142 +                        Object slt = jso.getSlot(i);
   8.143 +                        if (slt instanceof String) {
   8.144 +                            try {
   8.145 +                                bridge.loadClass((String) slt);
   8.146 +                            } catch (ClassNotFoundException ex) {
   8.147 +                                LOG.log(Level.SEVERE, null, ex);
   8.148 +                            }
   8.149 +                        }
   8.150 +                    }
   8.151 +                    LOG.info("bck2brwsr: " + jsobj.getMember("bck2brwsr"));
   8.152 +                }
   8.153 +            }
   8.154 +        }
   8.155 +
   8.156 +        @Override
   8.157 +        protected void layoutChildren() {
   8.158 +            List<Node> managed = getManagedChildren();
   8.159 +            double width = getWidth();
   8.160 +            double height = getHeight();
   8.161 +            double top = getInsets().getTop();
   8.162 +            double right = getInsets().getRight();
   8.163 +            double left = getInsets().getLeft();
   8.164 +            double bottom = getInsets().getBottom();
   8.165 +            for (int i = 0; i < managed.size(); i++) {
   8.166 +                Node child = managed.get(i);
   8.167 +                layoutInArea(child, left, top, width - left - right, height - top - bottom, 0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
   8.168 +            }
   8.169 +        }
   8.170 +    }
   8.171 +    
   8.172 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/JVMBridge.java	Thu Mar 14 09:22:28 2013 +0100
     9.3 @@ -0,0 +1,46 @@
     9.4 +/**
     9.5 + * Back 2 Browser Bytecode Translator
     9.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     9.7 + *
     9.8 + * This program is free software: you can redistribute it and/or modify
     9.9 + * it under the terms of the GNU General Public License as published by
    9.10 + * the Free Software Foundation, version 2 of the License.
    9.11 + *
    9.12 + * This program is distributed in the hope that it will be useful,
    9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.15 + * GNU General Public License for more details.
    9.16 + *
    9.17 + * You should have received a copy of the GNU General Public License
    9.18 + * along with this program. Look for COPYING file in the top folder.
    9.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    9.20 + */
    9.21 +package org.apidesign.bck2brwsr.launcher.impl;
    9.22 +
    9.23 +/**
    9.24 + *
    9.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    9.26 + */
    9.27 +public final class JVMBridge {
    9.28 +    private static ClassLoader[] ldrs;
    9.29 +        
    9.30 +    public static void registerClassLoaders(ClassLoader[] loaders) {
    9.31 +        ldrs = loaders.clone();
    9.32 +    }
    9.33 +    
    9.34 +    public Class<?> loadClass(String name) throws ClassNotFoundException {
    9.35 +        System.err.println("trying to load " + name);
    9.36 +        ClassNotFoundException ex = null;
    9.37 +        if (ldrs != null) for (ClassLoader l : ldrs) {
    9.38 +            try {
    9.39 +                return Class.forName(name, true, l);
    9.40 +            } catch (ClassNotFoundException ex2) {
    9.41 +                ex = ex2;
    9.42 +            }
    9.43 +        }
    9.44 +        if (ex == null) {
    9.45 +            ex = new ClassNotFoundException("No loaders");
    9.46 +        }
    9.47 +        throw ex;
    9.48 +    }
    9.49 +}