2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
6 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7 * Other names may be trademarks of their respective owners.
9 * The contents of this file are subject to the terms of either the GNU
10 * General Public License Version 2 only ("GPL") or the Common
11 * Development and Distribution License("CDDL") (collectively, the
12 * "License"). You may not use this file except in compliance with the
13 * License. You can obtain a copy of the License at
14 * http://www.netbeans.org/cddl-gplv2.html
15 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16 * specific language governing permissions and limitations under the
17 * License. When distributing the software, include this License Header
18 * Notice in each file and include the License file at
19 * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
20 * particular file as subject to the "Classpath" exception as provided
21 * by Oracle in the GPL Version 2 section of the License file that
22 * accompanied this code. If applicable, add the following below the
23 * License Header, with the fields enclosed by brackets [] replaced by
24 * your own identifying information:
25 * "Portions Copyrighted [year] [name of copyright owner]"
29 * The Original Software is NetBeans. The Initial Developer of the Original
30 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
32 * If you wish your version of this file to be governed by only the CDDL
33 * or only the GPL Version 2, indicate your decision by adding
34 * "[Contributor] elects to include this software in this distribution
35 * under the [CDDL or GPL Version 2] license." If you do not indicate a
36 * single choice of license, a recipient has the option to distribute
37 * your version of this file under either the CDDL, the GPL Version 2 or
38 * to extend the choice of license to its licensees as provided above.
39 * However, if you add GPL Version 2 code and therefore, elected the GPL
40 * Version 2 license, then the option applies only if the new code is
41 * made subject to such option by the copyright holder.
43 package org.netbeans.html.boot.fx;
46 import java.util.concurrent.CountDownLatch;
47 import java.util.concurrent.Executors;
48 import java.util.logging.Level;
49 import java.util.logging.Logger;
50 import javafx.application.Application;
51 import javafx.application.Platform;
52 import javafx.beans.value.ChangeListener;
53 import javafx.beans.value.ObservableValue;
54 import javafx.concurrent.Worker;
55 import javafx.event.ActionEvent;
56 import javafx.event.EventHandler;
57 import javafx.geometry.Insets;
58 import javafx.geometry.Pos;
59 import javafx.scene.Scene;
60 import javafx.scene.control.Button;
61 import javafx.scene.layout.BorderPane;
62 import javafx.scene.layout.VBox;
63 import javafx.scene.text.Text;
64 import javafx.scene.web.WebEvent;
65 import javafx.scene.web.WebView;
66 import javafx.stage.Modality;
67 import javafx.stage.Stage;
69 /** This is an implementation class, to implement browser builder API. Just
70 * include this JAR on classpath and the browser builder API will find
71 * this implementation automatically.
73 public class FXBrwsr extends Application {
74 private static final Logger LOG = Logger.getLogger(FXBrwsr.class.getName());
75 private static FXBrwsr INSTANCE;
76 private static final CountDownLatch FINISHED = new CountDownLatch(1);
77 private BorderPane root;
79 public static synchronized WebView findWebView(final URL url, final FXPresenter onLoad) {
80 if (INSTANCE == null) {
81 Executors.newFixedThreadPool(1).submit(new Runnable() {
85 FXBrwsr.launch(FXBrwsr.class);
86 } catch (Throwable ex) {
94 while (INSTANCE == null) {
97 } catch (InterruptedException ex) {
101 if (!Platform.isFxApplicationThread()) {
102 final WebView[] arr = {null};
103 final CountDownLatch waitForResult = new CountDownLatch(1);
104 Platform.runLater(new Runnable() {
107 arr[0] = INSTANCE.newView(url, onLoad);
108 waitForResult.countDown();
113 waitForResult.await();
115 } catch (InterruptedException ex) {
116 LOG.log(Level.INFO, null, ex);
121 return INSTANCE.newView(url, onLoad);
126 public void start(Stage primaryStage) throws Exception {
127 synchronized (FXBrwsr.class) {
129 FXBrwsr.class.notifyAll();
131 BorderPane r = new BorderPane();
132 Scene scene = new Scene(r, 800, 600);
133 primaryStage.setScene(scene);
138 private WebView newView(final URL url, final FXPresenter onLoad) {
139 final WebView view = new WebView();
140 view.setContextMenuEnabled(false);
141 view.getEngine().setOnAlert(new EventHandler<WebEvent<String>>() {
143 public void handle(WebEvent<String> t) {
144 final Stage dialogStage = new Stage();
145 dialogStage.initModality(Modality.WINDOW_MODAL);
146 dialogStage.setTitle("Warning");
147 final Button button = new Button("Close");
148 final Text text = new Text(t.getData());
149 VBox box = new VBox();
150 box.setAlignment(Pos.CENTER);
152 box.setPadding(new Insets(10));
153 box.getChildren().addAll(text, button);
154 dialogStage.setScene(new Scene(box));
155 button.setCancelButton(true);
156 button.setOnAction(new EventHandler<ActionEvent>() {
158 public void handle(ActionEvent t) {
162 dialogStage.centerOnScreen();
163 dialogStage.showAndWait();
166 root.setCenter(view);
167 final Worker<Void> w = view.getEngine().getLoadWorker();
168 w.stateProperty().addListener(new ChangeListener<Worker.State>() {
170 public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State newState) {
171 if (newState.equals(Worker.State.SUCCEEDED)) {
172 FXConsole.register(view.getEngine());
175 if (newState.equals(Worker.State.FAILED)) {
176 throw new IllegalStateException("Failed to load " + url);
183 static void waitFinished() {
188 } catch (InterruptedException ex) {
189 LOG.log(Level.INFO, null, ex);