javafx
WebView und WebEngine
Suche…
Bemerkungen
Das WebView
ist der JavaFX-Knoten, der in den JavaFX-Komponentenbaum integriert ist. Es verwaltet eine WebEngine
und zeigt deren Inhalt an.
Die WebEngine
ist die zugrunde liegende Browser Engine, die im Wesentlichen die gesamte Arbeit erledigt.
Eine Seite laden
WebView wv = new WebView();
WebEngine we = wv.getEngine();
we.load("https://stackoverflow.com");
WebView
ist die UI-Shell um die WebEngine
herum. Nahezu alle Steuerelemente für die Interaktion mit einer Seite ohne Benutzeroberfläche werden über die WebEngine
Klasse ausgeführt.
Rufen Sie den Seitenverlauf einer WebView ab
WebHistory history = webView.getEngine().getHistory();
Die Geschichte ist im Wesentlichen eine Liste von Einträgen. Jeder Eintrag stellt eine besuchte Seite dar und bietet Zugriff auf relevante Seiteninformationen wie URL, Titel und Datum, an dem die Seite zuletzt besucht wurde.
Die Liste kann mit der Methode getEntries()
abgerufen werden. Der Verlauf und die entsprechende Liste der Einträge ändern sich, wenn WebEngine
im Web navigiert. Die Liste kann je nach Browseraktionen erweitert oder verkleinert werden. Diese Änderungen können von der ObservableList-API, die die Liste verfügbar macht, überwacht werden.
Der Index des Verlaufseintrags, der der aktuell besuchten Seite zugeordnet ist, wird durch currentIndexProperty()
. Der aktuelle Index kann verwendet werden, um mithilfe der go(int)
-Methode zu einem Eintrag im Verlauf zu navigieren. maxSizeProperty()
legt die maximale Verlaufsgröße fest, maxSizeProperty()
die Größe der Verlaufsliste
Im Folgenden finden Sie ein Beispiel für das Abrufen und Verarbeiten der Liste der Webprotokollelemente .
Eine ComboBox
(ComboBox) dient zum Speichern der Verlaufselemente. Durch Verwendung eines ListChangeListener
für das WebHistory
die ComboBox
auf das aktuelle WebHistory
aktualisiert. In der ComboBox
befindet sich ein EventHandler
der auf die ausgewählte Seite umleitet.
final WebHistory history = webEngine.getHistory();
comboBox.setItems(history.getEntries());
comboBox.setPrefWidth(60);
comboBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent ev) {
int offset =
comboBox.getSelectionModel().getSelectedIndex()
- history.getCurrentIndex();
history.go(offset);
}
});
history.currentIndexProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
// update currently selected combobox item
comboBox.getSelectionModel().select(newValue.intValue());
}
});
// set converter for value shown in the combobox:
// display the urls
comboBox.setConverter(new StringConverter<WebHistory.Entry>() {
@Override
public String toString(WebHistory.Entry object) {
return object == null ? null : object.getUrl();
}
@Override
public WebHistory.Entry fromString(String string) {
throw new UnsupportedOperationException();
}
});
Senden Sie Javascript-Alarme von der angezeigten Webseite an das Java-Anwendungsprotokoll.
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
WebView webView = new WebView();
webEngine = webView.getEngine();
webEngine.setOnAlert(event -> logger.warning(() -> "JS alert: " + event.getData()));
Kommunikation zwischen Java-App und Javascript auf der Webseite
Wenn Sie ein WebView verwenden, um Ihre eigene benutzerdefinierte Webseite anzuzeigen, und diese Webseite Javascript enthält, kann es erforderlich sein, eine bidirektionale Kommunikation zwischen dem Java-Programm und dem Javascript auf der Webseite herzustellen.
Dieses Beispiel zeigt, wie Sie eine solche Kommunikation einrichten.
Die Webseite muss ein Eingabefeld und eine Schaltfläche anzeigen. Wenn Sie auf die Schaltfläche klicken, wird der Wert aus dem Eingabefeld an die Java-Anwendung gesendet, die ihn verarbeitet. Nach der Verarbeitung wird ein Ergebnis an das Javascript gesendet, das wiederum das Ergebnis auf der Webseite anzeigt.
Das grundlegende Prinzip ist, dass für die Kommunikation von Javascript nach Java ein Objekt in Java erstellt wird, das in die Webseite eingefügt wird. Für die andere Richtung wird ein Objekt in Javascript erstellt und von der Webseite extrahiert.
Der folgende Code zeigt den Java-Teil. Ich habe alles in einer Datei gespeichert:
package com.sothawo.test;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
import java.io.File;
import java.net.URL;
/**
* @author P.J. Meisch ([email protected]).
*/
public class WebViewApplication extends Application {
/** for communication to the Javascript engine. */
private JSObject javascriptConnector;
/** for communication from the Javascript engine. */
private JavaConnector javaConnector = new JavaConnector();;
@Override
public void start(Stage primaryStage) throws Exception {
URL url = new File("./js-sample.html").toURI().toURL();
WebView webView = new WebView();
final WebEngine webEngine = webView.getEngine();
// set up the listener
webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (Worker.State.SUCCEEDED == newValue) {
// set an interface object named 'javaConnector' in the web engine's page
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("javaConnector", javaConnector);
// get the Javascript connector object.
javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");
}
});
Scene scene = new Scene(webView, 300, 150);
primaryStage.setScene(scene);
primaryStage.show();
// now load the page
webEngine.load(url.toString());
}
public class JavaConnector {
/**
* called when the JS side wants a String to be converted.
*
* @param value
* the String to convert
*/
public void toLowerCase(String value) {
if (null != value) {
javascriptConnector.call("showResult", value.toLowerCase());
}
}
}
}
Wenn die Seite geladen wurde, wird ein JavaConnector
Objekt (das von der inneren Klasse definiert und als Feld erstellt wird) durch folgende Aufrufe in die Webseite gesetzt:
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("javaConnector", javaConnector);
Das javascriptConnector
Objekt wird von der Webseite mit abgerufen
javascriptConnector = (JSObject) webEngine.executeScript("getJsConnector()");
Wenn die toLowerCase(String)
-Methode aus dem JavaConnector
aufgerufen wird, wird der übergebene Wert konvertiert und dann über das javascriptConnector
Objekt zurückgesendet.
Und das ist der HTML- und Javascript-Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<main>
<div><input id="input" type="text"></div>
<button onclick="sendToJava();">to lower case</button>
<div id="result"></div>
</main>
<script type="text/javascript">
function sendToJava () {
var s = document.getElementById('input').value;
javaConnector.toLowerCase(s);
};
var jsConnector = {
showResult: function (result) {
document.getElementById('result').innerHTML = result;
}
};
function getJsConnector() {
return jsConnector;
};
</script>
</body>
</html>
Die sendToJava
Funktion ruft die Methode des JavaConnector
die durch den Java-Code festgelegt wurde:
function sendToJava () {
var s = document.getElementById('input').value;
javaConnector.toLowerCase(s);
};
und die Funktion, die vom Java-Code aufgerufen wird, um den javascriptConnector
abzurufen, gibt nur das jsConnector
Objekt zurück:
var jsConnector = {
showResult: function (result) {
document.getElementById('result').innerHTML = result;
}
};
function getJsConnector() {
return jsConnector;
};
Der Argumenttyp der Aufrufe zwischen Java und Javascript ist nicht auf Strings beschränkt. Weitere Informationen zu den möglichen Typen und Konvertierungen finden Sie im JSObject-API-Dokument .