Руководство JavaFX WebView и WebEngine
1. JavaFX WebView
JavaFX WebView это минибраузер, так же называется встроенным браузером (embedded browser) в приложение JavaFX. Этот браузер основан на WebKit, браузерный движок (browser engine) с открытым исходным кодом, поддерживает CSS, JavaScript, DOM и HTML5.
JavaFX WebView позволяет вам выполнять следующие задачи в приложении JavaFX:
- Изображает содержание HTML от локальных и удаленных URL
- Собирает историю веб
- Выполняет команды Javascript
- Выполняет вызовы от Javascript до JavaFX
- Управляет поп ап окна в веб
- Применяет эффекты для встроенного браузера
В настоящей версии (JavaFX 2.3) компонент WebView поддерживает следующие свойства HTML5:
- Canvas
- Media Playback
- Form controls (except for <input type="color"> )
- Editable content
- History maintenance
- Support for the <meter> and <progress> tags.
- Support for the <details> and <summary> tags.
- DOM
- SVG
- Support for domain names written in national languages
Следующее изображение является структурой встренного браузера в JavaFX:
WebEngine
Класс WebEngine предоставляет основную функцию веб страницы. Он поддерживает в интерктивности пользователя, как навигация ссылок и submit form HTML, несмотря на то что он не интерактирует напрямую с пользователем. Класс WebEngine обрабатывает веб страницу одновременно. Он поддерживает основные веб ствойства загрузки содержания HTML и доступ в DOM так же выполняет команды JavaScript.
WebView
Класс WebView расширен из класса Node, он оборачивает объект WebEngine и отображает содержание Html. Вы можете получить объект WebEngine из WebView используя метод getEngine().
// Create a WebView
WebView browser = new WebView();
// Get WebEngine via WebView
WebEngine webEngine = browser.getEngine();
// Load page
webEngine.load("http://eclipse.com");
2. Пример с WebView
Загрузить удаленный URL.
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
String url = "https://eclipse.org";
// Load a page from remote url.
webEngine.load(url);
Помимо отображения данных из удаленного URL, вы так же можете отобразить содержание статистического HTML.
// A HTML text
String html = "<html><h1>Hello</h1><h2>Hello</h2></html>";
// Load content.
webEngine.loadContent(html);
// Or
webEngine.loadContent(html,"text/html");
Или загрузить содержание html из локального файла.
File file = new File("C:/test/a.html");
URL url= file.toURI().toURL();
// file:/C:/test/a.html
webEngine.load(url.toString());
Посмотрим полный пример с WebView. Заметьте, что WebView по умолчанию установил ScrollPane, полосы прокрутки (scroll) появятся когда содержание веб больше, чем регион отображения.
WebViewDemo.java
package org.o7planning.javafx.webview;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewDemo extends Application {
@Override
public void start(final Stage stage) {
Button buttonURL = new Button("Load Page https://eclipse.org");
Button buttonHtmlString = new Button("Load HTML String");
Button buttonHtmlFile = new Button("Load File C:/test/a.html");
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
buttonURL.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String url = "https://eclipse.org";
// Load a page from remote url.
webEngine.load(url);
}
});
buttonHtmlString.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String html = "<html><h1>Hello</h1><h2>Hello</h2></html>";
// Load HTML String
webEngine.loadContent(html);
}
});
buttonHtmlFile.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
try {
File file = new File("C:/test/a.html");
URL url = file.toURI().toURL();
// file:/C:/test/a.html
System.out.println("Local URL: " + url.toString());
webEngine.load(url.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
});
VBox root = new VBox();
root.setPadding(new Insets(5));
root.setSpacing(5);
root.getChildren().addAll(buttonURL, buttonHtmlString, buttonHtmlFile, browser);
Scene scene = new Scene(root);
stage.setTitle("JavaFX WebView (o7planning.org)");
stage.setScene(scene);
stage.setWidth(450);
stage.setHeight(300);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
3. Пример WebView с ProgressBar
Чтобы загрузить вебсайт на браузер требуется определенное время. Иногда вам нужно использовать ProgressBar чтобы отобразить процент загружения вебсайта.
WebViewWithProgressDemo.java
package org.o7planning.javafx.webview;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewWithProgressDemo extends Application {
@Override
public void start(final Stage stage) {
TextField addressBar = new TextField();
addressBar.setText("https://eclipse.org");
Button goButton = new Button("Go!");
Label stateLabel = new Label();
stateLabel.setTextFill(Color.RED);
ProgressBar progressBar = new ProgressBar();
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
// A Worker load the page
Worker<Void> worker = webEngine.getLoadWorker();
// Listening to the status of worker
worker.stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
stateLabel.setText("Loading state: " + newValue.toString());
if (newValue == Worker.State.SUCCEEDED) {
stage.setTitle(webEngine.getLocation());
stateLabel.setText("Finish!");
}
}
});
// Bind the progress property of ProgressBar
// with progress property of Worker
progressBar.progressProperty().bind(worker.progressProperty());
goButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String url = addressBar.getText();
// Load the page.
webEngine.load(url);
}
});
//
VBox root = new VBox();
root.getChildren().addAll(addressBar, goButton, stateLabel, progressBar, browser);
Scene scene = new Scene(root);
stage.setTitle("JavaFX WebView (o7planning.org)");
stage.setScene(scene);
stage.setWidth(450);
stage.setHeight(300);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
4. Вызов Javascript из JavaFX
После того как WebView загрузил вебсайт, вы можете интерактировать с вебсайтом из JavaFX. В примере ниже пользователь нажимает на Button в приложении JavaFX он вызывает функцию Javascript отображенной страницы на WebView.
// Enable Javascript.
webEngine.setJavaScriptEnabled(true);
// Call a JavaScript function of the current page
webEngine.executeScript("changeBgColor();");A
WebViewExecuteJsDemo.java
package org.o7planning.javafx.webview;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewExecuteJsDemo extends Application {
// A HTML Content with a javascript function.
private static String HTML_STRING = //
"<html>"//
+ "<head> " //
+ " <script language='javascript'> " //
+ " function changeBgColor() { "//
+ " var color= document.getElementById('color').value; "//
+ " document.body.style.backgroundColor= color; " //
+ " } " //
+ " </script> "//
+ "</head> "//
+ "<body> "//
+ " <h2>This is Html content</h2> "//
+ " <b>Enter Color:</b> "//
+ " <input id='color' value='yellow' /> "//
+ " <button onclick='changeBgColor();'>Change Bg Color</button> "//
+ "</body> "//
+ "</html> "//
;
@Override
public void start(final Stage stage) {
Button button = new Button("Execute Javascript (Call from JavaFX)");
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
// Enable Javascript.
webEngine.setJavaScriptEnabled(true);
webEngine.loadContent(HTML_STRING);
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Call a JavaScript function of the current page
webEngine.executeScript("changeBgColor();");
}
});
VBox root = new VBox();
root.setPadding(new Insets(5));
root.setSpacing(5);
root.getChildren().addAll(button, browser);
Scene scene = new Scene(root);
stage.setTitle("JavaFX WebView (o7planning.org)");
stage.setScene(scene);
stage.setWidth(450);
stage.setHeight(300);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Вы так же можете войти в объекты Javascript через объекты Java. Большинство объектов Javascript обернуты netscape.javascript.JSObject. Методы JSObject:
public Object call(String methodName, Object... args);
public Object eval(String s);
public Object getMember(String name);
public void setMember(String name, Object value);
public void removeMember(String name);
public Object getSlot(int index);
public void setSlot(int index, Object value);
Пример:
// Back Browser History
webEngine.executeScript("history.back()");
// Or
// Get the object representing the history of JavaScript objects JSObject.
JSObject history = (JSObject) webEngine.executeScript("history");
// Call 'back' method, without parameter.
history.call("back");
Особенный случай, когда при вызове JavaScript возвращается объект DOM (DOM Node). В данном случае, результат обернут объектом JSObject он выполняет интерфейс org.w3c.dom.Node.
Element p = (Element) ebEngine.executeScript("document.getElementById('para')");
p.setAttribute("style", "font-weight: bold");
5. Создание вызова Upcalls от JavaScript до JavaFX
Выше, вы могли вызвать функцию Javascript страницы отображенной на WebView из JavaFX. В обратном, вы так же можете создать вызовы Upcalls от Javascript до JavaFX.
Со стороны JavaFX, вам нужно создать объект интерфейса (лобого класса) и удостовериться, что он знаком для JavaScript через вызов JSObject.setMember(). После выполнения этого, вы можете вызвать методы public или поля public объекта Java от Javascript.
// A Bridge class and must a public class
public class Bridge {
public void showTime() {
System.out.println("Show Time");
label.setText("Now is: " + df.format(new Date()));
}
}
// Get window object of page.
JSObject jsobj = (JSObject) webEngine.executeScript("window");
// Set member cho đối tượng 'window'
jsobj.setMember("myJavaMember", new Bridge());
В странице HTML:
<!-- In HTML -->
<button onclick='myJavaMember.showTime();'>Call To JavaFX</button>
Смотреть полный пример:
WebViewUpCallsDemo.java
package org.o7planning.javafx.webview;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class WebViewUpCallsDemo extends Application {
private DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
private Label label;
// A Bridge class and must a public class
public class Bridge {
public void showTime() {
System.out.println("Show Time");
label.setText("Now is: " + df.format(new Date()));
}
}
// A HTML Content with a javascript function.
private static String HTML_STRING = //
"<html>"//
+ "<head> " //
+ " <script language='javascript'> " //
+ " function callToJavaFX() { "//
+ " myJavaMember.showTime(); " //
+ " } " //
+ " </script> "//
+ "</head> "//
+ "<body> "//
+ " <h2>This is Html content</h2> "//
+ " <button onclick='callToJavaFX();'>Call To JavaFX</button> "//
+ "</body> "//
+ "</html> "//
;
@Override
public void start(final Stage stage) {
label = new Label("-");
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
// Enable Javascript.
webEngine.setJavaScriptEnabled(true);
// A Worker load the page
Worker<Void> worker = webEngine.getLoadWorker();
// Listening to the status of worker
worker.stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> observable, //
State oldValue, State newValue) {
// When load successed.
if (newValue == Worker.State.SUCCEEDED) {
// Get window object of page.
JSObject jsobj = (JSObject) webEngine.executeScript("window");
// Set member for 'window' object.
// In Javascript access: window.myJavaMember....
jsobj.setMember("myJavaMember", new Bridge());
}
}
});
// Load HTML content.
// Tải nội dung HTML
webEngine.loadContent(HTML_STRING);
VBox root = new VBox();
root.setPadding(new Insets(5));
root.setSpacing(5);
root.getChildren().addAll(label, browser);
Scene scene = new Scene(root);
stage.setTitle("JavaFX WebView (o7planning.org)");
stage.setScene(scene);
stage.setWidth(450);
stage.setHeight(300);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Руководства JavaFX
- Откройте новое окно (window) в JavaFX
- Руководство JavaFX ChoiceDialog
- Руководство JavaFX Alert Dialog
- Руководство JavaFX TextInputDialog
- Установите e(fx)clipse для Eclipse (JavaFX Tooling)
- Установите JavaFX Scene Builder для Eclipse
- Руководство JavaFX для начинающих - Hello JavaFX
- Руководство JavaFX FlowPane Layout
- Руководство JavaFX TilePane Layout
- Руководство JavaFX HBox, VBox Layout
- Руководство JavaFX BorderPane Layout
- Руководство JavaFX AnchorPane Layout
- Руководство JavaFX TitledPane
- Руководство JavaFX Accordion
- Руководство JavaFX ListView
- Руководство JavaFX Group
- Руководство JavaFX ComboBox
- Руководство JavaFX Transformations
- Эффекты (effects) в JavaFX
- Руководство JavaFX GridPane Layout
- Руководство JavaFX StackPane Layout
- Руководство JavaFX ScrollPane
- Руководство JavaFX WebView и WebEngine
- Руководство JavaFX HTMLEditor
- Руководство JavaFX TableView
- Руководство JavaFX TreeView
- Руководство JavaFX TreeTableView
- Руководство JavaFX Menu
- Руководство JavaFX ContextMenu
- Руководство JavaFX Image и ImageView
- Руководство JavaFX Label
- Руководство JavaFX Hyperlink
- Руководство JavaFX Button
- Руководство JavaFX ToggleButton
- Руководство JavaFX RadioButton
- Руководство JavaFX MenuButton и SplitMenuButton
- Руководство JavaFX TextField
- Руководство JavaFX PasswordField
- Руководство JavaFX TextArea
- Руководство JavaFX Slider
- Руководство JavaFX Spinner
- Руководство JavaFX ProgressBar и ProgressIndicator
- Руководство JavaFX ChoiceBox
- Руководство JavaFX Tooltip
- Руководство JavaFX DatePicker
- Руководство JavaFX ColorPicker
- Руководство JavaFX FileChooser и DirectoryChooser
- Руководство JavaFX PieChart
- Руководство JavaFX AreaChart и StackedAreaChart
- Руководство JavaFX BarChart и StackedBarChart
- Руководство JavaFX Line
- Руководство JavaFX Rectangle и Ellipse
Show More