rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/FXBrwsr.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 17 Apr 2013 17:04:40 +0200
branchfx
changeset 1004 04efef2a9c1e
parent 856 8d6534b67252
child 1005 512984207634
permissions -rw-r--r--
Rather than piggybacking on first alert call, use the fact that the server and FX Web View are in the same VM and notify the view that bck2brwsr.js is about to be served from the server.
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.bck2brwsr.launcher.impl;
    19 
    20 import java.util.List;
    21 import java.util.TooManyListenersException;
    22 import java.util.logging.Level;
    23 import java.util.logging.Logger;
    24 import javafx.application.Application;
    25 import javafx.application.Platform;
    26 import javafx.beans.value.ChangeListener;
    27 import javafx.beans.value.ObservableValue;
    28 import javafx.event.ActionEvent;
    29 import javafx.event.EventHandler;
    30 import javafx.geometry.HPos;
    31 import javafx.geometry.Insets;
    32 import javafx.geometry.Pos;
    33 import javafx.geometry.VPos;
    34 import javafx.scene.Node;
    35 import javafx.scene.Scene;
    36 import javafx.scene.control.Button;
    37 import javafx.scene.layout.ColumnConstraints;
    38 import javafx.scene.layout.GridPane;
    39 import javafx.scene.layout.Pane;
    40 import javafx.scene.layout.Priority;
    41 import javafx.scene.layout.VBox;
    42 import javafx.scene.text.Text;
    43 import javafx.scene.web.WebEngine;
    44 import javafx.scene.web.WebEvent;
    45 import javafx.scene.web.WebView;
    46 import javafx.stage.Modality;
    47 import javafx.stage.Stage;
    48 import netscape.javascript.JSObject;
    49 
    50 /**
    51  * Demonstrates a WebView object accessing a web page.
    52  *
    53  * @see javafx.scene.web.WebView
    54  * @see javafx.scene.web.WebEngine
    55  */
    56 public class FXBrwsr extends Application {
    57     private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName());
    58 
    59     @Override
    60     public void start(Stage primaryStage) throws Exception {
    61         Pane root = new WebViewPane(getParameters().getUnnamed());
    62         primaryStage.setScene(new Scene(root, 1024, 768));
    63         primaryStage.show();
    64     }
    65     
    66     /**
    67      * Create a resizable WebView pane
    68      */
    69     private class WebViewPane extends Pane {
    70         private final JVMBridge bridge = new JVMBridge();
    71 
    72         public WebViewPane(List<String> params) {
    73             VBox.setVgrow(this, Priority.ALWAYS);
    74             setMaxWidth(Double.MAX_VALUE);
    75             setMaxHeight(Double.MAX_VALUE);
    76             WebView view = new WebView();
    77             view.setMinSize(500, 400);
    78             view.setPrefSize(500, 400);
    79             final WebEngine eng = view.getEngine();
    80             LOG.log(Level.FINE, "params : {0}", params);
    81             try {
    82                 JVMBridge.addBck2BrwsrLoad(new InitBck2Brwsr(eng));
    83             } catch (TooManyListenersException ex) {
    84                 LOG.log(Level.SEVERE, null, ex);
    85             }
    86             
    87             if (params.size() > 0) {
    88                 LOG.log(Level.FINE, "loading page {0}", params.get(0));
    89                 eng.load(params.get(0));
    90                 LOG.fine("done loading page ");
    91             }
    92             eng.setOnAlert(new EventHandler<WebEvent<String>>() {
    93                 @Override
    94                 public void handle(WebEvent<String> t) {
    95                     final Stage dialogStage = new Stage();
    96                     dialogStage.initModality(Modality.WINDOW_MODAL);
    97                     dialogStage.setTitle("Warning");
    98                     final Button button = new Button("Close");
    99                     final Text text = new Text(t.getData());
   100                     
   101                     VBox box = new VBox();
   102                     box.setAlignment(Pos.CENTER);
   103                     box.setSpacing(10);
   104                     box.setPadding(new Insets(10));
   105                     box.getChildren().addAll(text, button);
   106                     
   107                     dialogStage.setScene(new Scene(box));
   108                     
   109                     button.setCancelButton(true);
   110                     button.setOnAction(new EventHandler<ActionEvent>() {
   111                         @Override
   112                         public void handle(ActionEvent t) {
   113                             dialogStage.close();
   114                         }
   115                     });
   116                     
   117                     dialogStage.centerOnScreen();
   118                     dialogStage.showAndWait();
   119                 }
   120             });
   121             GridPane grid = new GridPane();
   122             grid.setVgap(5);
   123             grid.setHgap(5);
   124             GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
   125             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));
   126             grid.getChildren().addAll(view);
   127             getChildren().add(grid);
   128         }
   129 
   130         boolean initBck2Brwsr(WebEngine webEngine) {
   131             JSObject jsobj = (JSObject) webEngine.executeScript("window");
   132             LOG.log(Level.FINE, "window: {0}", jsobj);
   133             Object prev = jsobj.getMember("bck2brwsr");
   134             if ("undefined".equals(prev)) {
   135                 System.getProperties().put("webEngine", webEngine);
   136                 jsobj.setMember("bck2brwsr", bridge);
   137                 return true;
   138             }
   139             return false;
   140         }
   141 
   142         @Override
   143         protected void layoutChildren() {
   144             List<Node> managed = getManagedChildren();
   145             double width = getWidth();
   146             double height = getHeight();
   147             double top = getInsets().getTop();
   148             double right = getInsets().getRight();
   149             double left = getInsets().getLeft();
   150             double bottom = getInsets().getBottom();
   151             for (int i = 0; i < managed.size(); i++) {
   152                 Node child = managed.get(i);
   153                 layoutInArea(child, left, top, width - left - right, height - top - bottom, 0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
   154             }
   155         }
   156 
   157         private class InitBck2Brwsr implements ChangeListener<Void>, Runnable {
   158             private final WebEngine eng;
   159 
   160             public InitBck2Brwsr(WebEngine eng) {
   161                 this.eng = eng;
   162             }
   163 
   164             @Override
   165             public synchronized void changed(ObservableValue<? extends Void> ov, Void t, Void t1) {
   166                 Platform.runLater(this);
   167                 try {
   168                     wait();
   169                 } catch (InterruptedException ex) {
   170                     LOG.log(Level.SEVERE, null, ex);
   171                 }
   172             }
   173 
   174             @Override
   175             public synchronized void run() {
   176                 initBck2Brwsr(eng);
   177                 notifyAll();
   178             }
   179         }
   180     }
   181     
   182 }