Adding HTML Content to JavaFX Applications
Beta Draft: 2013-09-17
8 Managing Web History
This chapter introduces the WebHistory
class and teaches how to obtain and show the URLs of visited pages.
You can obtain the list of visited pages by using the WebHistory
class. It represents a session history associated with a WebEngine
object. Use the WebEngine.getHistory()
method to get the WebHistory
instance for a particular web engine, as shown in the following line: WebHistory history = webEngine.getHistory();
.
The history is basically a list of entries. Each entry represents a visited page and it provides access to relevant page info, such as URL, title, and the date the page was last visited. The list can be obtained by using the getEntries()
method.
The history list changes as users navigate through the web. Use the ObservableList
API to process the changes.
Obtaining the List of Visited Pages
You typically use a standard or custom UI control to display the history list. Example 8-1 shows how to obtain a history items and present them in the ComboBox
control.
Example 8-1 Obtaining and Processing the List of Web History Items
final WebHistory history = webEngine.getHistory(); history.getEntries().addListener(new ListChangeListener<WebHistory.Entry>() { @Override public void onChanged(Change<? extends Entry> c) { c.next(); for (Entry e : c.getRemoved()) { comboBox.getItems().remove(e.getUrl()); } for (Entry e : c.getAddedSubList()) { comboBox.getItems().add(e.getUrl()); } } } ); comboBox.setPrefWidth(60); comboBox.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent ev) { int offset = comboBox.getSelectionModel().getSelectedIndex() - history.getCurrentIndex(); history.go(offset); } });
The ListChangeListener
object tracks the changes of history entries and adds the corresponding URLs to the combo box.
When users select any item in the combo box, the web engine is navigated to the URL defined by the history entry item, which position in the list is defined by the offset
value. A negative offset
value specifies the position preceding the current entry, and a positive offset
value specifies the position following the current entry.
Example 8-2 shows the complete code of the modified application.
Example 8-2 WebViewSample with the History Combo Box
import javafx.application.Application; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener.Change; 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.ComboBox; 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.WebHistory; import javafx.scene.web.WebHistory.Entry; 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(); final ComboBox comboBox = new ComboBox(); 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); } }); } comboBox.setPrefWidth(60); // create the toolbar toolBar = new HBox(); toolBar.setAlignment(Pos.CENTER); toolBar.getStyleClass().add("browser-toolbar"); toolBar.getChildren().add(comboBox); 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 history final WebHistory history = webEngine.getHistory(); history.getEntries().addListener(new ListChangeListener<WebHistory.Entry>(){ @Override public void onChanged(Change<? extends Entry> c) { c.next(); for (Entry e : c.getRemoved()) { comboBox.getItems().remove(e.getUrl()); } for (Entry e : c.getAddedSubList()) { comboBox.getItems().add(e.getUrl()); } } }); //set the behavior for the history combobox comboBox.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent ev) { int offset = comboBox.getSelectionModel().getSelectedIndex() - history.getCurrentIndex(); history.go(offset); } }); // 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 you compile and run the application, it produces the window shown in Figure 8-1.
Figure 8-1 Selecting URL from the History Combo Box
Description of "Figure 8-1 Selecting URL from the History Combo Box"