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.
2 * Back 2 Browser Bytecode Translator
3 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
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.
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.
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.
18 package org.apidesign.bck2brwsr.launcher.impl;
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;
51 * Demonstrates a WebView object accessing a web page.
53 * @see javafx.scene.web.WebView
54 * @see javafx.scene.web.WebEngine
56 public class FXBrwsr extends Application {
57 private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName());
60 public void start(Stage primaryStage) throws Exception {
61 Pane root = new WebViewPane(getParameters().getUnnamed());
62 primaryStage.setScene(new Scene(root, 1024, 768));
67 * Create a resizable WebView pane
69 private class WebViewPane extends Pane {
70 private final JVMBridge bridge = new JVMBridge();
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);
82 JVMBridge.addBck2BrwsrLoad(new InitBck2Brwsr(eng));
83 } catch (TooManyListenersException ex) {
84 LOG.log(Level.SEVERE, null, ex);
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 ");
92 eng.setOnAlert(new EventHandler<WebEvent<String>>() {
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());
101 VBox box = new VBox();
102 box.setAlignment(Pos.CENTER);
104 box.setPadding(new Insets(10));
105 box.getChildren().addAll(text, button);
107 dialogStage.setScene(new Scene(box));
109 button.setCancelButton(true);
110 button.setOnAction(new EventHandler<ActionEvent>() {
112 public void handle(ActionEvent t) {
117 dialogStage.centerOnScreen();
118 dialogStage.showAndWait();
121 GridPane grid = new GridPane();
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);
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);
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);
157 private class InitBck2Brwsr implements ChangeListener<Void>, Runnable {
158 private final WebEngine eng;
160 public InitBck2Brwsr(WebEngine eng) {
165 public synchronized void changed(ObservableValue<? extends Void> ov, Void t, Void t1) {
166 Platform.runLater(this);
169 } catch (InterruptedException ex) {
170 LOG.log(Level.SEVERE, null, ex);
175 public synchronized void run() {