How to use JavaFX WebView in DesktopApp with local files?
Asked Answered
R

1

6

My webview works like charm when I use it within eclipse but as soon as I pack the application into a jar file it throws the following error:

This page contains the following errors:
error on line 33 at column 26: StartTag: invalid element name
Below is a rendering of the page up to the first error.

This is the HTML-File

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="EN">
    <head>
    <style>
        html,body {
            height: 99%;
            width: 99%;
        }
        #map {
            width: 100%;
            height: 100%;
            border: 1px solid black;
        }   
    </style>
    <script src='http://openlayers.org/api/OpenLayers.js'></script>
    </head>
    <body>
        <div id='map'></div>
        <script type="text/javascript">
            var map = new OpenLayers.Map("map",{projection:"EPSG:3857"});
            var toMercator = OpenLayers.Projection.transforms['EPSG:4326']['EPSG:3857'];
            var center = toMercator({x:-0.05,y:51.5});
            var osm = new OpenLayers.Layer.OSM();
            map.addLayer(osm);

            map.zoomToMaxExtent();  

            function addPoints(lon,lat,merkm){
                var features = [];

                for(var i = 0; i < lon.length; i++) {
                    var center = toMercator({x:lon[i],y:lat[i]});
                    features[i] = new OpenLayers.Feature.Vector(
                            toMercator(new OpenLayers.Geometry.Point(
                                lon[i],
                                lat[i])), 
                            {
                                infoitems : merkm[i]
                            }, {
                                fillColor : '#008040',
                                fillOpacity : 0.8,                    
                                strokeColor : "#ee9900",
                                strokeOpacity : 1,
                                strokeWidth : 1,
                                pointRadius : 8
                            });
                }

                // create the layer with listeners to create and destroy popups
                var vector = new OpenLayers.Layer.Vector("Points",{
                    eventListeners:{
                        'featureselected':function(evt){
                            var feature = evt.feature;
                            var popup = new OpenLayers.Popup.FramedCloud("popup",
                                OpenLayers.LonLat.fromString(feature.geometry.toShortString()),
                                null,
                                "<div style='font-size:.8em'>"+feature.attributes.infoitems+"</div>",
                                null,
                                true
                            );
                            feature.popup = popup;
                            map.addPopup(popup);
                        },
                        'featureunselected':function(evt){
                            var feature = evt.feature;
                            map.removePopup(feature.popup);
                            feature.popup.destroy();
                            feature.popup = null;
                        }
                    }
                });
                vector.addFeatures(features);

                var line = new OpenLayers.Control.DrawFeature(vector,
                        OpenLayers.Handler.Path);


                // create the select feature control
                var selector = new OpenLayers.Control.SelectFeature(vector,{
                    hover:true,
                    autoActivate:true
                }); 
               // map.destroy();
               // map = new OpenLayers.Map("map",{projection:"EPSG:3857"});

              //  var osm = new OpenLayers.Layer.OSM();
                map.addLayer(vector);
                map.addControl(selector);
                map.addControl(line);
                map.setCenter(new OpenLayers.LonLat(center.x,center.y), 13);


            }
            function pageOnLoad(){
                alert();
            }
        </script>
    </body>
</html>

This is how I load the WebView:

WebView browser = new WebView(); 
        final WebEngine webEngine = browser.getEngine();

        String mapfolder = "mapview";
        File map = new File(new File("."), "/mapview/mapview.html");


        final URL mapUrl = MapTab.class.getResource("mapview.html");

        webEngine.getLoadWorker().stateProperty().addListener(
                new ChangeListener<State>() {
                    public void changed(ObservableValue ov, State oldState, State newState) {
                        if (newState == State.SUCCEEDED) {
                            webEngine.executeScript("addPoints("+arg0+","+arg1+","+arg2+")");
                        }
                    }
                });
        webEngine.javaScriptEnabledProperty().set(true);
        webEngine.load(mapUrl.toExternalForm());
        this.setContent(browser);

I dont now where the problem is, tried many differant things like differant file locations, script locations and so on.

Anybody an idea?

Remunerative answered 24/9, 2012 at 21:47 Comment(0)
C
6

I don't think you can use the File protocol in combination with the getResource protocol when you are loading something out of a jar. I also don't think the jar protocol will understand file type specifiers like . and ...

If the map html is on the local filesystem outside the jar, load the map html off the file system with the file:// protocol.

If the map html is packaged in your jar under /mapview/mapview.html as I expect it is, load it out of the jar with:

webEngine.load(MapTab.class.getResource("/mapview/mapview.html").toExternalForm());

I think the error you are getting is because you are setting an xhtml doctype, which means it passes through very strict type checking compared to a straight html doctype which is more permissive. Your sample document is not a compliant xhtml document.

I relaxed the doctype of the html document, refactored it a little bit so I could understand it created a simple loader app and was able to load up a map.

/mapview/mapview.html

<!doctype html>  
<html lang="en">  
  <head>
  <style>
    html,body {
      height: 99%;
      width: 99%;
    }
    #map {
      width: 100%;
      height: 100%;
      border: 1px solid black;
    }   
  </style>
  <script language="javascript" src="http://openlayers.org/api/OpenLayers.js"></script>   
  <script language="javascript" type="text/javascript">
    function doload() {
      var map = new OpenLayers.Map("map",{projection:"EPSG:3857"});
      var toMercator = OpenLayers.Projection.transforms['EPSG:4326']['EPSG:3857'];
      var center = toMercator({x:-0.05,y:51.5});
      var osm = new OpenLayers.Layer.OSM();
      map.addLayer(osm);

      map.zoomToMaxExtent();  
    }  
    function addPoints(lon,lat,merkm){
      var features = [];

      for(var i = 0; i < lon.length; i++) {
          var center = toMercator({x:lon[i],y:lat[i]});
          features[i] = new OpenLayers.Feature.Vector(
                  toMercator(new OpenLayers.Geometry.Point(
                      lon[i],
                      lat[i])), 
                  {
                      infoitems : merkm[i]
                  }, {
                      fillColor : '#008040',
                      fillOpacity : 0.8,                    
                      strokeColor : "#ee9900",
                      strokeOpacity : 1,
                      strokeWidth : 1,
                      pointRadius : 8
                  });
      }

      // create the layer with listeners to create and destroy popups
      var vector = new OpenLayers.Layer.Vector("Points",{
          eventListeners:{
              'featureselected':function(evt){
                  var feature = evt.feature;
                  var popup = new OpenLayers.Popup.FramedCloud("popup",
                      OpenLayers.LonLat.fromString(feature.geometry.toShortString()),
                      null,
                      "<div style='font-size:.8em'>"+feature.attributes.infoitems+"</div>",
                      null,
                      true
                  );
                  feature.popup = popup;
                  map.addPopup(popup);
              },
              'featureunselected':function(evt){
                  var feature = evt.feature;
                  map.removePopup(feature.popup);
                  feature.popup.destroy();
                  feature.popup = null;
              }
          }
      });
      vector.addFeatures(features);

      var line = new OpenLayers.Control.DrawFeature(vector,
              OpenLayers.Handler.Path);

      // create the select feature control
      var selector = new OpenLayers.Control.SelectFeature(vector,{
          hover:true,
          autoActivate:true
      }); 
     // map.destroy();
     // map = new OpenLayers.Map("map",{projection:"EPSG:3857"});

    //  var osm = new OpenLayers.Layer.OSM();
      map.addLayer(vector);
      map.addControl(selector);
      map.addControl(line);
      map.setCenter(new OpenLayers.LonLat(center.x,center.y), 13);
    }
    function pageOnLoad(){
      alert();
    }
  </script>    
  </head>
  <body onload="doload()">
    <div id="map"></div>
  </body>
</html>

/javafxsamples/MapViewer.java

package javafxsamples;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class MapViewer extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) {
    WebView webview = new WebView();
    webview.getEngine().load(
      MapViewer.class.getResource("/mapview/mapview.html").toExternalForm()            
    );
    stage.setScene(new Scene(webview));
    stage.show();
  }
}

Sample program output

Composure answered 24/9, 2012 at 23:15 Comment(1)
Thank you! It really was just the html-part which made the App glitch, wondered where it came from. Damn copy/past-errors!Remunerative

© 2022 - 2024 — McMap. All rights reserved.