jaroslav@845: /** jaroslav@845: * Back 2 Browser Bytecode Translator jaroslav@845: * Copyright (C) 2012 Jaroslav Tulach jaroslav@845: * jaroslav@845: * This program is free software: you can redistribute it and/or modify jaroslav@845: * it under the terms of the GNU General Public License as published by jaroslav@845: * the Free Software Foundation, version 2 of the License. jaroslav@845: * jaroslav@845: * This program is distributed in the hope that it will be useful, jaroslav@845: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@845: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@845: * GNU General Public License for more details. jaroslav@845: * jaroslav@845: * You should have received a copy of the GNU General Public License jaroslav@845: * along with this program. Look for COPYING file in the top folder. jaroslav@845: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@845: */ jaroslav@845: package org.apidesign.bck2brwsr.launcher.impl; jaroslav@845: jaroslav@845: import java.util.List; jaroslav@1004: import java.util.TooManyListenersException; jaroslav@845: import java.util.logging.Level; jaroslav@845: import java.util.logging.Logger; jaroslav@845: import javafx.application.Application; jaroslav@1004: import javafx.application.Platform; jaroslav@845: import javafx.beans.value.ChangeListener; jaroslav@845: import javafx.beans.value.ObservableValue; jaroslav@845: import javafx.event.ActionEvent; jaroslav@845: import javafx.event.EventHandler; jaroslav@845: import javafx.geometry.HPos; jaroslav@845: import javafx.geometry.Insets; jaroslav@854: import javafx.geometry.Pos; jaroslav@845: import javafx.geometry.VPos; jaroslav@845: import javafx.scene.Node; jaroslav@845: import javafx.scene.Scene; jaroslav@845: import javafx.scene.control.Button; jaroslav@845: import javafx.scene.layout.ColumnConstraints; jaroslav@845: import javafx.scene.layout.GridPane; jaroslav@845: import javafx.scene.layout.Pane; jaroslav@845: import javafx.scene.layout.Priority; jaroslav@845: import javafx.scene.layout.VBox; jaroslav@854: import javafx.scene.text.Text; jaroslav@845: import javafx.scene.web.WebEngine; jaroslav@845: import javafx.scene.web.WebEvent; jaroslav@845: import javafx.scene.web.WebView; jaroslav@854: import javafx.stage.Modality; jaroslav@845: import javafx.stage.Stage; jaroslav@845: import netscape.javascript.JSObject; jaroslav@845: jaroslav@845: /** jaroslav@845: * Demonstrates a WebView object accessing a web page. jaroslav@845: * jaroslav@845: * @see javafx.scene.web.WebView jaroslav@845: * @see javafx.scene.web.WebEngine jaroslav@845: */ jaroslav@845: public class FXBrwsr extends Application { jaroslav@845: private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName()); jaroslav@845: jaroslav@845: @Override jaroslav@845: public void start(Stage primaryStage) throws Exception { jaroslav@845: Pane root = new WebViewPane(getParameters().getUnnamed()); jaroslav@845: primaryStage.setScene(new Scene(root, 1024, 768)); jaroslav@1005: LOG.info("Showing the stage"); jaroslav@845: primaryStage.show(); jaroslav@1005: LOG.log(Level.INFO, "State shown: {0}", primaryStage.isShowing()); jaroslav@845: } jaroslav@845: jaroslav@845: /** jaroslav@845: * Create a resizable WebView pane jaroslav@845: */ jaroslav@845: private class WebViewPane extends Pane { jaroslav@845: private final JVMBridge bridge = new JVMBridge(); jaroslav@845: jaroslav@845: public WebViewPane(List params) { jaroslav@1005: LOG.log(Level.INFO, "Initializing WebView with {0}", params); jaroslav@845: VBox.setVgrow(this, Priority.ALWAYS); jaroslav@845: setMaxWidth(Double.MAX_VALUE); jaroslav@845: setMaxHeight(Double.MAX_VALUE); jaroslav@845: WebView view = new WebView(); jaroslav@845: view.setMinSize(500, 400); jaroslav@845: view.setPrefSize(500, 400); jaroslav@845: final WebEngine eng = view.getEngine(); jaroslav@1004: try { jaroslav@1004: JVMBridge.addBck2BrwsrLoad(new InitBck2Brwsr(eng)); jaroslav@1004: } catch (TooManyListenersException ex) { jaroslav@1004: LOG.log(Level.SEVERE, null, ex); jaroslav@1004: } jaroslav@1004: jaroslav@845: if (params.size() > 0) { jaroslav@1005: LOG.log(Level.INFO, "loading page {0}", params.get(0)); jaroslav@845: eng.load(params.get(0)); jaroslav@1005: LOG.fine("back from load"); jaroslav@845: } jaroslav@845: eng.setOnAlert(new EventHandler>() { jaroslav@845: @Override jaroslav@845: public void handle(WebEvent t) { jaroslav@854: final Stage dialogStage = new Stage(); jaroslav@854: dialogStage.initModality(Modality.WINDOW_MODAL); jaroslav@854: dialogStage.setTitle("Warning"); jaroslav@854: final Button button = new Button("Close"); jaroslav@854: final Text text = new Text(t.getData()); jaroslav@854: jaroslav@854: VBox box = new VBox(); jaroslav@854: box.setAlignment(Pos.CENTER); jaroslav@854: box.setSpacing(10); jaroslav@854: box.setPadding(new Insets(10)); jaroslav@854: box.getChildren().addAll(text, button); jaroslav@854: jaroslav@854: dialogStage.setScene(new Scene(box)); jaroslav@854: jaroslav@854: button.setCancelButton(true); jaroslav@854: button.setOnAction(new EventHandler() { jaroslav@854: @Override jaroslav@854: public void handle(ActionEvent t) { jaroslav@854: dialogStage.close(); jaroslav@854: } jaroslav@854: }); jaroslav@854: jaroslav@854: dialogStage.centerOnScreen(); jaroslav@854: dialogStage.showAndWait(); jaroslav@845: } jaroslav@845: }); jaroslav@845: GridPane grid = new GridPane(); jaroslav@845: grid.setVgap(5); jaroslav@845: grid.setHgap(5); jaroslav@845: GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS); jaroslav@845: 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)); jaroslav@856: grid.getChildren().addAll(view); jaroslav@845: getChildren().add(grid); jaroslav@845: } jaroslav@845: jaroslav@854: boolean initBck2Brwsr(WebEngine webEngine) { jaroslav@845: JSObject jsobj = (JSObject) webEngine.executeScript("window"); jaroslav@854: LOG.log(Level.FINE, "window: {0}", jsobj); jaroslav@853: Object prev = jsobj.getMember("bck2brwsr"); jaroslav@853: if ("undefined".equals(prev)) { jaroslav@853: System.getProperties().put("webEngine", webEngine); jaroslav@853: jsobj.setMember("bck2brwsr", bridge); jaroslav@854: return true; jaroslav@845: } jaroslav@854: return false; jaroslav@845: } jaroslav@845: jaroslav@845: @Override jaroslav@845: protected void layoutChildren() { jaroslav@845: List managed = getManagedChildren(); jaroslav@845: double width = getWidth(); jaroslav@845: double height = getHeight(); jaroslav@845: double top = getInsets().getTop(); jaroslav@845: double right = getInsets().getRight(); jaroslav@845: double left = getInsets().getLeft(); jaroslav@845: double bottom = getInsets().getBottom(); jaroslav@845: for (int i = 0; i < managed.size(); i++) { jaroslav@845: Node child = managed.get(i); jaroslav@845: layoutInArea(child, left, top, width - left - right, height - top - bottom, 0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER); jaroslav@845: } jaroslav@845: } jaroslav@1004: jaroslav@1004: private class InitBck2Brwsr implements ChangeListener, Runnable { jaroslav@1004: private final WebEngine eng; jaroslav@1004: jaroslav@1004: public InitBck2Brwsr(WebEngine eng) { jaroslav@1004: this.eng = eng; jaroslav@1004: } jaroslav@1004: jaroslav@1004: @Override jaroslav@1004: public synchronized void changed(ObservableValue ov, Void t, Void t1) { jaroslav@1004: Platform.runLater(this); jaroslav@1004: try { jaroslav@1004: wait(); jaroslav@1004: } catch (InterruptedException ex) { jaroslav@1004: LOG.log(Level.SEVERE, null, ex); jaroslav@1004: } jaroslav@1004: } jaroslav@1004: jaroslav@1004: @Override jaroslav@1004: public synchronized void run() { jaroslav@1004: initBck2Brwsr(eng); jaroslav@1004: notifyAll(); jaroslav@1004: } jaroslav@1004: } jaroslav@845: } jaroslav@845: jaroslav@845: }