Setting custom CSS rules using JavaScript in JavaFX WebView

I am using WebView

full screen to display fixed size content 1024x768

, so I need to scale it so that it stretches from top to bottom. To do this, I have installed the following code in my controller 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 user.css

loads fine and here is the code for reference:

body {
    overflow-x: hidden;
    background-color: #ccc;
}

#pbody {
    margin: 0 auto;
    -webkit-transform-origin: top center;
}

      

In HTML, the body tag definitely has an id:

<body id="pbody">

      

The problem is the #pbody

javascript bit not found for some reason , so the following error occurs:

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)

      

SlideshowController.java:165

is the line:

maincontainer.setAttribute("style", String.format("-webkit-transform: scale(%.5f)", (primaryScreenBounds.getHeight() / 768.0)));

      

I cannot understand the reason for this behavior.


Refresh . I tried to wait for the document to load, but it doesn't work either. I first posted this manually in the content:

<script>
function scaleBody(scale)
{
    alert(3);
    document.getElementById('pbody').style.webkitTransform = "scale("+scale+")";
}
</script>

      

and then using a 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)

works and no errors are generated ...

... don't know yet how to execute js in JavaFX.

+3


source to share


1 answer


You need to provide more details about what html content you are 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>

      



Line

System.out.println("maincontainer = " + maincontainer);

      

prints

maincontainer = [HTMLBodyElement object]

Alternatively open the html content you load in a normal web browser, then press F12 (firebug or similar tool) and in the JS console, enter document.getElementById('pbody')

.

+2


source







All Articles