Adding HTML Content to JavaFX Applications
Beta Draft: 2013-09-17
7 Managing Web Pop-Up Windows
This chapter explains how to work with pop-up windows in the browser created by using the WebView component and how to implement this functionality in the WebViewSample application.
When you need to open a new browser window in your application, the instances of the PopupFeatures class are passed into pop-up handlers registered on a WebEngine object by using the setCreatePopupHandler method.
Using Pop-Up Windows to Set
In the WebViewSample application, you can set an alternative WebView object for the documents that will be opened in a separate window. Figure 7-1 shows a context menu a user can open by right-clicking any link.
To specify a new browser window for the target document, use the PopupFeatures instance as shown in the modified application code in Example 7-1.
Example 7-1 Processing a Command of a Pop-Up Window
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.PopupFeatures;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;
import netscape.javascript.JSObject;
public class WebViewSample extends Application {
private Scene scene;
@Override
public void start(Stage stage) {
// create scene
stage.setTitle("Web View");
scene = new Scene(new Browser(), 900, 600, Color.web("#666970"));
stage.setScene(scene);
// apply CSS style
scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
// show stage
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class Browser extends Region {
private HBox toolBar;
final private static String[] imageFiles = new String[]{
"product.png",
"blog.png",
"documentation.png",
"partners.png",
"help.png"
};
final private static String[] captions = new String[]{
"Products",
"Blogs",
"Documentation",
"Partners",
"Help"
};
final private static String[] urls = new String[]{
"http://www.oracle.com/products/index.html",
"http://blogs.oracle.com/",
"http://docs.oracle.com/javase/index.html",
"http://www.oracle.com/partners/index.html",
WebViewSample.class.getResource("help.html").toExternalForm()
};
final ImageView selectedImage = new ImageView();
final Hyperlink[] hpls = new Hyperlink[captions.length];
final Image[] images = new Image[imageFiles.length];
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
final Button showPrevDoc = new Button("Toggle Previous Docs");
final WebView smallView = new WebView();
private boolean needDocumentationButton = false;
public Browser() {
//apply the styles
getStyleClass().add("browser");
for (int i = 0; i < captions.length; i++) {
// create hyperlinks
Hyperlink hpl = hpls[i] = new Hyperlink(captions[i]);
Image image = images[i] =
new Image(getClass().getResourceAsStream(imageFiles[i]));
hpl.setGraphic(new ImageView(image));
final String url = urls[i];
final boolean addButton = (hpl.getText().equals("Documentation"));
// process event
hpl.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
needDocumentationButton = addButton;
webEngine.load(url);
}
});
}
// create the toolbar
toolBar = new HBox();
toolBar.setAlignment(Pos.CENTER);
toolBar.getStyleClass().add("browser-toolbar");
toolBar.getChildren().addAll(hpls);
toolBar.getChildren().add(createSpacer());
//set action for the button
showPrevDoc.setOnAction(new EventHandler() {
@Override
public void handle(Event t) {
webEngine.executeScript("toggleDisplay('PrevRel')");
}
});
smallView.setPrefSize(120, 80);
//handle popup windows
webEngine.setCreatePopupHandler(
new Callback<PopupFeatures, WebEngine>() {
@Override public WebEngine call(PopupFeatures config) {
smallView.setFontScale(0.8);
if (!toolBar.getChildren().contains(smallView)) {
toolBar.getChildren().add(smallView);
}
return smallView.getEngine();
}
}
);
// process page loading
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov,
State oldState, State newState) {
toolBar.getChildren().remove(showPrevDoc);
if (newState == State.SUCCEEDED) {
JSObject win =
(JSObject) webEngine.executeScript("window");
win.setMember("app", new JavaApp());
if (needDocumentationButton) {
toolBar.getChildren().add(showPrevDoc);
}
}
}
}
);
// load the home page
webEngine.load("http://www.oracle.com/products/index.html");
//add components
getChildren().add(toolBar);
getChildren().add(browser);
}
// JavaScript interface object
public class JavaApp {
public void exit() {
Platform.exit();
}
}
private Node createSpacer() {
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
@Override
protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
double tbHeight = toolBar.prefHeight(w);
layoutInArea(browser,0,0,w,h-tbHeight,0,HPos.CENTER, VPos.CENTER);
layoutInArea(toolBar,0,h-tbHeight,w,tbHeight,0,HPos.CENTER,VPos.CENTER);
}
@Override
protected double computePrefWidth(double height) {
return 900;
}
@Override
protected double computePrefHeight(double width) {
return 600;
}
}
When a user selects the Open Link in New Window option from the pop-up menu, the smallView browser is added to the application toolbar. This behavior is defined by the setCreatePopupHandler method, which returns the web engine of an alternative browser to notify the application where to render the target page. The result of compiling and running the modified application is shown in Figure 7-2.
Note that context menus are enabled by default for all WebView objects. To disable a context menu for a particular WebView instance, pass the false value to the setContextMenuEnabled method: browser.setContextMenuEnabled(false);.
Alla is a technical writer for Oracle. She lives in St. Petersburg, Russia, and develops tutorials and technical articles for Java and JavaFX technologies. Prior to her assignment at Oracle, she worked as a technical writer in different IT companies. 


