Skip to content
Tobias Soloschenko edited this page Jun 6, 2017 · 20 revisions

Html5 Project

About

The wicket-html5 module contains classes that give wicket support for using exciting new Html5 features like FileApi, Geolocation, (<video>, <audio> only in 6.x and previous since in 7.0.0 it is integrated into wicket core).

Maven snippet

Add this to your pom.xml:

<dependency>
	<groupId>org.wicketstuff</groupId>
	<artifactId>wicketstuff-html5</artifactId>
	<version>[some-version]</version>
</dependency>

Fileapi package

This package contains support for the Html5 FileApi.

Brief info about Html5 FileApi

Gives limited access for javascript to read information (name, file size, type, last modified date) about the files choosen for a file upload field. Currently it is implemented in Chrome, Firefox and Opera but not in Internet Explorer.

FileFieldSizeCheckBehavior

This behavior can be added to FileUploadField-s to provide a convenient and fast size checking for users using FileApi supporting browsers. Using this has the benefit that the user does not have to upload the whole file data to receive an error about it exceeding the size limit. By default an ajax call is triggered when the user changes the value of the upload field (selects/deselects files). For browsers not implementing the FileApi this behavior does not change or break anything (so it is safe for IE users).

Usage is very simple (similar to an AjaxButton), just add it to the field and specify what should happen when validation passes or fails:

final FileUploadField uploadField = new FileUploadField("file");

// add our FileApi based size check, errors are reported trough a
// feedback panel
uploadField.add(new FileFieldSizeCheckBehavior() {
	private static final long serialVersionUID = 7228537141239670625L;

	@Override
	protected void onSubmit(AjaxRequestTarget target, FileList fileList) {
		target.add(feedback);
	}

	@Override
	protected void onError(AjaxRequestTarget target, FileList fileList) {
		target.add(feedback);
	}
});

If you want to do something different than check for size you can subclass FileFieldChangeBehavior.

Geolocation package

This package contains support for the HTML5 GeoLocation API.

Brief info about HTML5 GeoLocation API

The GeoLocation API tries to determine the position of the hosting device. E.g via GPS if a signal is availbale (on smartphones) or via network signals like the IP adress. Therefore no guarantee is given that the location is accurate.

AjaxGeolocationBehavior

Usage is very simple, just add it to a WebMarkupContainer and specify what should happen when you received a location (or no location can't be received):

        final WebMarkupContainer geoLocator = new WebMarkupContainer("geolocator");

        AjaxGeolocationBehavior geolocationBehaviour = new AjaxGeolocationBehavior()
        {

            private static final long serialVersionUID = 1L;

            // onGeoAvailable is abstract so you have to implement it
            @Override
            protected void onGeoAvailable(AjaxRequestTarget target, String latitude,
                    String longitude)
            {
                // permission to locate user was granted
                // you can do now whatever you want with the longitude and latitude values.
                String result = "We received a location. Latitude: "+ latitude+" Longitude: " + longitude +"\n";
            }

            // the onNotAvailable-method is available since version 6.0.0-beta3
            // you don't need to implement this method if you don't want to react on failure
            @Override
            protected void onNotAvailable(AjaxRequestTarget target, String errorCode, String errorMessage)
            {
                // if the location is not available, show the reason why
                String result = "An error occured. Error code: "+ errorCode + " Error message:" + errorMessage;
            }
        };
        // if the user does not react on the request to share his location with
        // us within 5 seconds we want the onNotAvailable-method to get triggered
        // this method is also available only since version 6.0.0-beta3
        geolocationBehaviour.setTimeout(5000);

        geoLocator.add(geolocationBehaviour);


        add(geoLocator);
    <wicket:extend>
                <span wicket:id="geolocator"></span>
    </wicket:extend>

New methods in version 6.0.0-beta3

Since 6.0.0-beta3 you can react on the event that no location can be obtained. The new methods are onNotAvailable and setTimeout. If the user is ignoring the request for sharing his location or postpones his decision (in Firefox the "Not now" option) no callback method is called. This is intended by design (see https://bugzilla.mozilla.org/show_bug.cgi?id=650247 ). For those cases we can set a timeout. After the specified amount of time the onNotAvailable method is called.

The specification (http://dev.w3.org/geo/api/spec-source.html#position_error_interface) defines also a timeout attribute: "The length of time specified by the timeout property has elapsed before the implementation could successfully acquire a new Position object."

So it applies only for the case the user grants permission to share his location and is NOT the timeout which is set in the setTimeout-method!

It MIGHT happen that the determination of the location takes a bit longer, even though the user granted permission to share his location. In this case first the method onNotAvailable will be called and as soon as the location could be obtained the method onGeoAvailable will be called. So don't set the timeout too low.

If onNotAvailable is called you can determine the cause via the errorCode parameter:

  • "1" indicates a "permission denied"
  • "2" indicates that the position could not be determined
  • "3" indicates a timeout

The errorMessage parameter is mainly for debugging purposes since it does not have to contain a meaningful message which can be directly delegated to the user.

HTML5 Shapes (Wicketstuff 7.0.0-M5 / 6.19.0)

The shapes are currently not working within in FF and IE, but all other browser are supporting shapes. They are used to let inline elements like text move along them - for example around one side of a background picture.

Java:

	add(new ShapeBuilder("shapeleft").shape(new Circle("30%"))
		.transition(new Circle("50%"))
		.useWidth("500px")
		.useHeight("500px"));
	add(new ShapeBuilder("shaperight").shape(new Circle("30%"))
		.transition(new Circle("50%"))
		.useWidth("500px")
		.useHeight("500px")
		.orientation(Orientation.right));

HTML:

	<div>
		<div wicket:id="shapeleft"></div>
		<div wicket:id="shaperight"></div>
		... some text...
	</div>

Further information:

WebVTT API (Wicketstuff 7.0.0-M6)

The WebVTT API is used to generate dynamically internationalized subtitles in Wicket videos. So you only have to record a video once and apply subtitles for each language. Note if you want to use cue-spans that closes in the middle set it as text (with #setString(String)) Example: <v fred>Hi everyone</v> <b>HIII</b>

Styling Examples:

::cue(.red){ color: red; }
::cue(.blue){ color: blue; }
::cue(.green){ color: green; }
::cue(.yellow){ color: yellow; }
::cue(.background-red){ background-color: red; }
::cue(.background-blue){ background-color: blue; }
::cue(.background-green){ background-color: green; }
::cue(.background-yellow){ background-color: yellow; }
<c.red.background-yellow>Red text with a yellow background.</c>
final WebVtt webVtt = new WebVtt();

webVtt.addCue(new VttCue("1", new VttTime().setS(1), 
new VttTime().setS(5), getString("first")));

webVtt.addCue(new VttCue("2", new VttTime().setS(6), 
new VttTime().setS(10), getString("second")));

Video video = new Video("video", 
"http://media.w3.org/2010/05/video/movie_300.mp4");
Track track = new Track("track", new VttResourceReference("VTT")
{

	private static final long serialVersionUID = -8739122871674506741L;

	@Override
	public WebVtt getWebVtt()
	{
		return webVtt;
	}
});
track.setDefaultTrack(true);
track.setKind(Kind.SUBTITLES);
video.add(track);
add(video);

WebRTC API (Wicketstuff 7.0.0-M6)

In order to use the integration of WebRTC you have to process the following steps which are required for the data transfer / the communication layer. There are two servers required to communicate. The first is the STUN / TURN server so that the clients can communicate even if they are behind a NAT. The second is a signal server which provides a websocket layer so that the client can update data of other clients. For default the public google STUN server is used stun.l.google.com:19302.

Installing the Signal Server:

  • Download and install nodejs (http://nodejs.org)
  • Copy the "server.js" and the "dev_config.json" file to the directory where you want the signal server to be started from - you can download the files from sources (jar) or starting wicketstuff-html5-examples and download it from the WebRTC demo page
  • Install socket.io / node-uuid / getconfig / fs - "npm install [email protected] [email protected] [email protected] [email protected]" (run this command in the same directory which contains the "server.js" and the "dev_config.json")
  • Start the signal server with "node server.js"
  • The listening port is 8000

Installing STUN server:

Wicket Java Integration:

  • Use the WebRTC class to display the video conference
  • Override getLocalVideo and put in the local video instantiation
  • getRoomName() is used to configure the room name people are able to join to and - this name can be dynamically provided from the wicket application
  • Use getSocketIOUrl() to configure the url to the signal server (Example:http://192.168.2.110:8000)

Java:

	final Video video = new Video("video");
	video.setControls(false);
	this.add(video);
	
	WebRTC webrtc = new WebRTC("webrtc")
	{
		private static final long serialVersionUID = 1L;
	
		@Override
		public Video getLocalVideo()
		{
			return video;
		}
	
		@Override
		public String getRoomName()
		{
			return "roomname";
		}
	
		@Override
		public String getSocketIOUrl()
		{
			return "http://192.168.2.110:8000";
		}

		// can be overridden to provide an error page
		@Override
		public Class<? extends Page> getErrorPage()
		{
			return super.getErrorPage();
		}

		// can be overridden to provide a dummy 
		// picture if no video is available		
		@Override
		protected ResourceReference getNoVideoResourceReference()
		{
			return super.getNoVideoResourceReference();
		}
	};
	webrtc.setVolumeBars(false);
	webrtc.setDebug(false);
	webrtc.setFramesPerSeconds(10);
	webrtc.setMaxWidth(320);
	webrtc.setMaxHeight(240);
	this.add(webrtc);

HTML:

	<div class="videocontainer">
		<video wicket:id="video" />
	</div>
	<div wicket:id="webrtc"></div>

To change the look and positions of the videos you can do this via CSS. The classes are:

  • videocontainer - the container which holds the video and the volume bar
  • video - the video element in the videocontainer
  • volumebar - the volume bar

Further information:

Special thanks to:

  • Jörn Zaefferer who helped me out with NodeJS. :-)

InlineImage (Wicketstuff 7.0.0-M6 / 6.20.0)

The inline image allows you to render the image content as base64 encoded content into the html page. (Example: src="data:image/jpeg;base64,......") The benefit is for example, that you could create HTML EMails without external image resources.

Java:

add(new InlineImage("inlineimage", 
new PackageResourceReference(this.getClass(), "test.png")));

HTML:

<img wicket:id="inlineimage" />

Further information:

Further reading

For more info see the javadoc of the classes. For a complete example see the wicketstuff-html5-examples web application.

Important

Classes Html5Video / Html5Audio / Html5Media / MediaSource have been removed since wicketstuff-html5 < 7.0.0-M6, because of integration into the wicket core. For further information see http://ci.apache.org/projects/wicket/guide/7.x

Clone this wiki locally