Reputation: 7226
I am using WebView
in fullscreen to display content that has a fixed size of 1024x768
, therefore I need to scale it so that it stretches from top to bottom of the screen. To accomplish that, I have put the following code in my controller's initialize()
:
this.wv.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
public void changed(ObservableValue<? extends State> ov, State oldState, State newState)
{
if (newState == State.SUCCEEDED)
{
wv.requestFocus();
wv.getEngine().setUserStyleSheetLocation(getClass().getResource("/css/user.css").toExternalForm());
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
Element maincontainer = (Element) wv.getEngine().executeScript("document.getElementById('pbody')");
maincontainer.setAttribute("style", String.format("-webkit-transform: scale(%.5f)", (primaryScreenBounds.getHeight() / 768.0)));
}
else if (newState == State.FAILED)
{
//.
}
}
});
The CSS in user.css
loads fine and for reference here is the code:
body {
overflow-x: hidden;
background-color: #ccc;
}
#pbody {
margin: 0 auto;
-webkit-transform-origin: top center;
}
In the HTML the body tag definitely has an id:
<body id="pbody">
The problem is that for some reason the #pbody
is not being found by the javascript bit, therefore generating the following error:
java.lang.NullPointerException
at com.mediacitizens.companyapp.presentation.desktop.SlideshowController$1.changed(SlideshowController.java:165)
at com.mediacitizens.companyapp.presentation.desktop.SlideshowController$1.changed(SlideshowController.java:1)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:196)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:195)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:161)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:130)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:163)
at javafx.scene.web.WebEngine$LoadWorker.updateState(WebEngine.java:975)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1086)
at javafx.scene.web.WebEngine$LoadWorker.access$600(WebEngine.java:968)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:955)
at com.sun.webpane.platform.WebPage.fireLoadEvent(WebPage.java:2372)
at com.sun.webpane.platform.WebPage.fwkFireLoadEvent(WebPage.java:2220)
at com.sun.webpane.webkit.network.URLLoader.twkDidFinishLoading(Native Method)
at com.sun.webpane.webkit.network.URLLoader.access$1300(URLLoader.java:42)
at com.sun.webpane.webkit.network.URLLoader$6.run(URLLoader.java:657)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
at java.lang.Thread.run(Thread.java:722)
The SlideshowController.java:165
being the line:
maincontainer.setAttribute("style", String.format("-webkit-transform: scale(%.5f)", (primaryScreenBounds.getHeight() / 768.0)));
I cannot understand the reason behind this behavior.
Update: I tried waiting for the document to load but it doesnt work either, first I put this manually in the content:
<script>
function scaleBody(scale)
{
alert(3);
document.getElementById('pbody').style.webkitTransform = "scale("+scale+")";
}
</script>
and then, using the state change listener:
double scale = Screen.getPrimary().getVisualBounds().getHeight() / 768.0;
wv.getEngine().executeScript(String.format("alert(1); window.onload = function(){ alert(2); scaleBody(%.5f); }", scale));
Only alert(1)
actually fires and no errors are generated...
...still dont know how to execute js in JavaFX.
Upvotes: 3
Views: 2504
Reputation: 49185
You need to provide more details like what kind of html content are you trying to load. Here is my test code that works fine as expected:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker.State;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Screen;
import javafx.stage.Stage;
import org.w3c.dom.Element;
public class WVTest extends Application {
private WebView wv;
@Override
public void start(Stage primaryStage) {
wv = new WebView();
wv.getEngine().load(this.getClass().getResource("index.html").toExternalForm());
// wv.getEngine().load("http://www.oracle.com/products/index.html");
wv.getEngine().getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
wv.requestFocus();
wv.getEngine().setUserStyleSheetLocation(getClass().getResource("style.css").toExternalForm());
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
Element maincontainer = (Element) wv.getEngine().executeScript("document.getElementById('pbody')");
System.out.println("maincontainer = " + maincontainer);
maincontainer.setAttribute("style", String.format("-webkit-transform: scale(%.5f)", (primaryScreenBounds.getHeight() / 768.0)));
}
}
});
VBox root = new VBox();
root.getChildren().addAll(wv);
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add(this.getClass().getResource("style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
with style.css
body {
overflow-x: hidden;
background-color: #ccc;
}
#pbody {
margin: 0 auto;
-webkit-transform-origin: top center;
}
and index.html
<html>
<head>
<title>Test</title>
</head>
<body id="pbody">
Test<br/>
Test<br/>
Test<br/>
Test<br/>
</body>
</html>
The line
System.out.println("maincontainer = " + maincontainer);
prints
maincontainer = [object HTMLBodyElement]
Alternatively open the html content you load in a regular web browser then press F12 (firebug or similar tool) and on JS console, type document.getElementById('pbody')
.
Upvotes: 2