Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JavaFX WebView in DesktopApp with local files?

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?

like image 243
user1641778 Avatar asked Sep 24 '12 21:09

user1641778


1 Answers

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

like image 200
jewelsea Avatar answered Sep 30 '22 18:09

jewelsea