# HG changeset patch # User Jaroslav Tulach # Date 1444541072 -7200 # Node ID c535c36881af73f521d1f2fd388a4c12af37991d # Parent 2ea65c6d3a8b83fd0f058a41a9728b50d6f3aee8 #255831: BrowserBuilder.showAndWait can be used multiple times with JavaFX presenter. Demonstrated by running the boot-fx tests in 'fork once' mode. diff -r 2ea65c6d3a8b -r c535c36881af boot-fx/pom.xml --- a/boot-fx/pom.xml Sun Oct 04 14:55:01 2015 +0200 +++ b/boot-fx/pom.xml Sun Oct 11 07:24:32 2015 +0200 @@ -26,13 +26,6 @@ org.netbeans.html html4j-maven-plugin - - org.apache.maven.plugins - maven-surefire-plugin - - always - - diff -r 2ea65c6d3a8b -r c535c36881af boot-fx/src/main/java/org/netbeans/html/boot/fx/FXBrwsr.java --- a/boot-fx/src/main/java/org/netbeans/html/boot/fx/FXBrwsr.java Sun Oct 04 14:55:01 2015 +0200 +++ b/boot-fx/src/main/java/org/netbeans/html/boot/fx/FXBrwsr.java Sun Oct 11 07:24:32 2015 +0200 @@ -92,11 +92,22 @@ Executors.newFixedThreadPool(1).submit(new Runnable() { @Override public void run() { - try { - FXBrwsr.launch(FXBrwsr.class, callee); - } catch (Throwable ex) { - ex.printStackTrace(); - } finally { + if (!Platform.isFxApplicationThread()) { + try { + Platform.runLater(this); + } catch (IllegalStateException ex) { + try { + FXBrwsr.launch(FXBrwsr.class, callee); + } catch (Throwable t) { + t.printStackTrace(); + } finally { + FINISHED.countDown(); + } + } + } else { + FXBrwsr brwsr = new FXBrwsr(); + brwsr.start(new Stage(), callee); + INSTANCE = brwsr; FINISHED.countDown(); } } @@ -144,8 +155,12 @@ @Override public void start(Stage primaryStage) throws Exception { + start(primaryStage, this.getParameters().getRaw().get(0)); + } + + final void start(Stage primaryStage, String callee) { BorderPane r = new BorderPane(); - Object[] arr = findInitialSize(this.getParameters().getRaw().get(0)); + Object[] arr = findInitialSize(callee); Scene scene = new Scene(r, (Double)arr[2], (Double)arr[3]); primaryStage.setScene(scene); this.root = r; @@ -220,99 +235,22 @@ private WebView newView(final URL url, final FXPresenter onLoad) { final WebView view = new WebView(); view.setContextMenuEnabled(false); - view.getEngine().setOnAlert(new EventHandler>() { - @Override - public void handle(WebEvent t) { - final Stage dialogStage = new Stage(); - dialogStage.initModality(Modality.WINDOW_MODAL); - dialogStage.initOwner(stage); - ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N - dialogStage.setTitle(r.getString("AlertTitle")); // NOI18N - final Button button = new Button(r.getString("AlertCloseButton")); // NOI18N - final Text text = new Text(t.getData()); - VBox box = new VBox(); - box.setAlignment(Pos.CENTER); - box.setSpacing(10); - box.setPadding(new Insets(10)); - box.getChildren().addAll(text, button); - dialogStage.setScene(new Scene(box)); - button.setCancelButton(true); - button.setOnAction(new CloseDialogHandler(dialogStage, null)); - dialogStage.centerOnScreen(); - dialogStage.showAndWait(); - } - }); - view.getEngine().setConfirmHandler(new Callback() { - @Override - public Boolean call(String question) { - final Stage dialogStage = new Stage(); - dialogStage.initModality(Modality.WINDOW_MODAL); - dialogStage.initOwner(stage); - ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N - dialogStage.setTitle(r.getString("ConfirmTitle")); // NOI18N - final Button ok = new Button(r.getString("ConfirmOKButton")); // NOI18N - final Button cancel = new Button(r.getString("ConfirmCancelButton")); // NOI18N - final Text text = new Text(question); - final Insets ins = new Insets(10); - final VBox box = new VBox(); - box.setAlignment(Pos.CENTER); - box.setSpacing(10); - box.setPadding(ins); - final HBox buttons = new HBox(10); - buttons.getChildren().addAll(ok, cancel); - buttons.setAlignment(Pos.CENTER); - buttons.setPadding(ins); - box.getChildren().addAll(text, buttons); - dialogStage.setScene(new Scene(box)); - ok.setCancelButton(false); + Stage newStage; + BorderPane bp; + if (root == null) { + newStage = new Stage(); + newStage.initOwner(stage); + bp = new BorderPane(); + newStage.setScene(new Scene(bp)); + newStage.show(); + } else { + bp = root; + newStage = stage; + root = null; + } - final boolean[] res = new boolean[1]; - ok.setOnAction(new CloseDialogHandler(dialogStage, res)); - cancel.setCancelButton(true); - cancel.setOnAction(new CloseDialogHandler(dialogStage, null)); - dialogStage.centerOnScreen(); - dialogStage.showAndWait(); - return res[0]; - } - }); - view.getEngine().setPromptHandler(new Callback() { - @Override - public String call(PromptData prompt) { - final Stage dialogStage = new Stage(); - dialogStage.initModality(Modality.WINDOW_MODAL); - dialogStage.initOwner(stage); - ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N - dialogStage.setTitle(r.getString("PromptTitle")); // NOI18N - final Button ok = new Button(r.getString("PromptOKButton")); // NOI18N - final Button cancel = new Button(r.getString("PromptCancelButton")); // NOI18N - final Text text = new Text(prompt.getMessage()); - final TextField line = new TextField(); - if (prompt.getDefaultValue() != null) { - line.setText(prompt.getDefaultValue()); - } - final Insets ins = new Insets(10); - final VBox box = new VBox(); - box.setAlignment(Pos.CENTER); - box.setSpacing(10); - box.setPadding(ins); - final HBox buttons = new HBox(10); - buttons.getChildren().addAll(ok, cancel); - buttons.setAlignment(Pos.CENTER); - buttons.setPadding(ins); - box.getChildren().addAll(text, line, buttons); - dialogStage.setScene(new Scene(box)); - ok.setCancelButton(false); - - final boolean[] res = new boolean[1]; - ok.setOnAction(new CloseDialogHandler(dialogStage, res)); - cancel.setCancelButton(true); - cancel.setOnAction(new CloseDialogHandler(dialogStage, null)); - dialogStage.centerOnScreen(); - dialogStage.showAndWait(); - return res[0] ? line.getText() : null; - } - }); - root.setCenter(view); + attachHandlers(view, newStage); + bp.setCenter(view); final Worker w = view.getEngine().getLoadWorker(); w.stateProperty().addListener(new ChangeListener() { private String previous; @@ -362,6 +300,101 @@ return view; } + private static void attachHandlers(final WebView view, final Stage owner) { + view.getEngine().setOnAlert(new EventHandler>() { + @Override + public void handle(WebEvent t) { + final Stage dialogStage = new Stage(); + dialogStage.initModality(Modality.WINDOW_MODAL); + dialogStage.initOwner(owner); + ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N + dialogStage.setTitle(r.getString("AlertTitle")); // NOI18N + final Button button = new Button(r.getString("AlertCloseButton")); // NOI18N + final Text text = new Text(t.getData()); + VBox box = new VBox(); + box.setAlignment(Pos.CENTER); + box.setSpacing(10); + box.setPadding(new Insets(10)); + box.getChildren().addAll(text, button); + dialogStage.setScene(new Scene(box)); + button.setCancelButton(true); + button.setOnAction(new CloseDialogHandler(dialogStage, null)); + dialogStage.centerOnScreen(); + dialogStage.showAndWait(); + } + }); + view.getEngine().setConfirmHandler(new Callback() { + @Override + public Boolean call(String question) { + final Stage dialogStage = new Stage(); + dialogStage.initModality(Modality.WINDOW_MODAL); + dialogStage.initOwner(owner); + ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N + dialogStage.setTitle(r.getString("ConfirmTitle")); // NOI18N + final Button ok = new Button(r.getString("ConfirmOKButton")); // NOI18N + final Button cancel = new Button(r.getString("ConfirmCancelButton")); // NOI18N + final Text text = new Text(question); + final Insets ins = new Insets(10); + final VBox box = new VBox(); + box.setAlignment(Pos.CENTER); + box.setSpacing(10); + box.setPadding(ins); + final HBox buttons = new HBox(10); + buttons.getChildren().addAll(ok, cancel); + buttons.setAlignment(Pos.CENTER); + buttons.setPadding(ins); + box.getChildren().addAll(text, buttons); + dialogStage.setScene(new Scene(box)); + ok.setCancelButton(false); + + final boolean[] res = new boolean[1]; + ok.setOnAction(new CloseDialogHandler(dialogStage, res)); + cancel.setCancelButton(true); + cancel.setOnAction(new CloseDialogHandler(dialogStage, null)); + dialogStage.centerOnScreen(); + dialogStage.showAndWait(); + return res[0]; + } + }); + view.getEngine().setPromptHandler(new Callback() { + @Override + public String call(PromptData prompt) { + final Stage dialogStage = new Stage(); + dialogStage.initModality(Modality.WINDOW_MODAL); + dialogStage.initOwner(owner); + ResourceBundle r = ResourceBundle.getBundle("org/netbeans/html/boot/fx/Bundle"); // NOI18N + dialogStage.setTitle(r.getString("PromptTitle")); // NOI18N + final Button ok = new Button(r.getString("PromptOKButton")); // NOI18N + final Button cancel = new Button(r.getString("PromptCancelButton")); // NOI18N + final Text text = new Text(prompt.getMessage()); + final TextField line = new TextField(); + if (prompt.getDefaultValue() != null) { + line.setText(prompt.getDefaultValue()); + } + final Insets ins = new Insets(10); + final VBox box = new VBox(); + box.setAlignment(Pos.CENTER); + box.setSpacing(10); + box.setPadding(ins); + final HBox buttons = new HBox(10); + buttons.getChildren().addAll(ok, cancel); + buttons.setAlignment(Pos.CENTER); + buttons.setPadding(ins); + box.getChildren().addAll(text, line, buttons); + dialogStage.setScene(new Scene(box)); + ok.setCancelButton(false); + + final boolean[] res = new boolean[1]; + ok.setOnAction(new CloseDialogHandler(dialogStage, res)); + cancel.setCancelButton(true); + cancel.setOnAction(new CloseDialogHandler(dialogStage, null)); + dialogStage.centerOnScreen(); + dialogStage.showAndWait(); + return res[0] ? line.getText() : null; + } + }); + } + static void waitFinished() { for (;;) { try { diff -r 2ea65c6d3a8b -r c535c36881af boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersOnResourceTest.java --- a/boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersOnResourceTest.java Sun Oct 04 14:55:01 2015 +0200 +++ b/boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersOnResourceTest.java Sun Oct 11 07:24:32 2015 +0200 @@ -71,7 +71,15 @@ new Thread("initFX") { @Override public void run() { - App.launch(App.class); + if (Platform.isFxApplicationThread()) { + new App().start(new Stage()); + } else { + try { + App.launch(App.class); + } catch (IllegalStateException ex) { + Platform.runLater(this); + } + } } }.start(); App.CDL.await(); @@ -182,7 +190,7 @@ } @Override - public void start(Stage stage) throws Exception { + public void start(Stage stage) { pane= new BorderPane(); Scene scene = new Scene(pane, 800, 600); stage.setScene(scene); diff -r 2ea65c6d3a8b -r c535c36881af boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersTest.java --- a/boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersTest.java Sun Oct 04 14:55:01 2015 +0200 +++ b/boot-fx/src/test/java/net/java/html/boot/fx/FXBrowsersTest.java Sun Oct 11 07:24:32 2015 +0200 @@ -68,7 +68,15 @@ new Thread("initFX") { @Override public void run() { - App.launch(App.class); + if (Platform.isFxApplicationThread()) { + new App().start(new Stage()); + } else { + try { + App.launch(App.class); + } catch (IllegalStateException ex) { + Platform.runLater(this); + } + } } }.start(); App.CDL.await(); @@ -122,7 +130,7 @@ @Override public void run() { assertTrue(Platform.isFxApplicationThread()); - three[0] = App.getV1().getEngine().executeScript("window.cnt"); + three[0] = App.getV1().getEngine().executeScript("window.cntBrwsr"); finish.countDown(); } }); @@ -173,8 +181,8 @@ private static native Object window(); @JavaScriptBody(args = {}, body = "" - + "if (window.cnt) return ++window.cnt;" - + "return window.cnt = 1;" + + "if (window.cntBrwsr) return ++window.cntBrwsr;" + + "return window.cntBrwsr = 1;" ) private static native int increment(); } @@ -198,7 +206,7 @@ } @Override - public void start(Stage stage) throws Exception { + public void start(Stage stage) { pane= new BorderPane(); Scene scene = new Scene(pane, 800, 600); stage.setScene(scene);