<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Steve On Java &#187; JavaFX Mobile</title>
	<atom:link href="http://steveonjava.com/tag/javafx-mobile/feed/" rel="self" type="application/rss+xml" />
	<link>http://steveonjava.com</link>
	<description>Hacking Java, JavaFX, and Flash with Agility</description>
	<lastBuildDate>Thu, 01 Dec 2011 01:36:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Launching Hyperlinks from JavaFX (including Mobile)</title>
		<link>http://javafx.steveonjava.com/launching-hyperlinks-from-javafx-including-mobile/</link>
		<comments>http://javafx.steveonjava.com/launching-hyperlinks-from-javafx-including-mobile/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 19:52:27 +0000</pubDate>
		<dc:creator>steveonjava</dc:creator>
				<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[JavaFX Mobile]]></category>
		<category><![CDATA[JFXtras]]></category>
		<category><![CDATA[hyperlinks]]></category>

		<guid isPermaLink="false">http://steveonjava.com/?p=814</guid>
		<description><![CDATA[Creating hyperlinks in JavaFX should be in the category of things that are trivially easy, but is complicated by various factors, such as deployment mode and Java version. First I will go into detail on all the different permutations of how you can launch links in a browser and under what circumstances each will work. [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-right: 0.75em;; margin-top: 4px; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fjavafx.steveonjava.com%252Flaunching-hyperlinks-from-javafx-including-mobile%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2Fbc4SAe%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Launching%20Hyperlinks%20from%20JavaFX%20%28including%20Mobile%29%22%20%7D);"></div>
<!--S-ButtonZ 1.1.5 Start--><div style="float: left; width: 42px; padding-right: 10px; margin: 0 10px 0 0;">
		<script type="text/javascript">
		<!--
		var dzone_url = "http://javafx.steveonjava.com/launching-hyperlinks-from-javafx-including-mobile/";
		var dzone_title = "Launching Hyperlinks from JavaFX (including Mobile)";
		var dzone_style = "1";
		var dzone_blurb = "";
		//-->
		</script>
		<script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script></div><!--S-ButtonZ 1.1.5 End--><p><a href="http://steveonjava.com/wp-content/uploads/2010/02/image_gallery.jpg"><img class="size-full wp-image-831 alignright" title="link" src="http://steveonjava.com/wp-content/uploads/2010/02/image_gallery.jpg" alt="" width="260" height="215" /></a>Creating hyperlinks in JavaFX should be in the category of things that are trivially easy, but is complicated by various factors, such as deployment mode and Java version.  First I will go into detail on all the different permutations of how you can launch links in a browser and under what circumstances each will work. Next I will give you a nice packaged solution that you can use as a library (if you are impatient, just skip to <a href="#out">The Easy Way Out</a> now).  Finally, I will show how you can do the same thing for <a href="#mobile">JavaFX Mobile applications</a>.</p>
<h2>A Tale of 3 APIs</h2>
<p>There are 3 different ways that you can launch hyperlinks in Java/JavaFX. It helps to have an internet connection such as <a href="http://www.o2.co.uk/">broadband</a> to be able to launch this. Unfortunately, none of them work in all circumstances, so you need to know when to call each.  Here is a quick reference table:</p>

<table id="wp-table-reloaded-id-3-no-1" class="wp-table-reloaded wp-table-reloaded-id-3">
<thead>
	<tr class="row-1 odd">
		<th class="column-1"></th><th class="column-2">AppletStageExtension</th><th class="column-3">Web Start BasicService</th><th class="column-4">Desktop.browse</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">Works in Applet</td><td class="column-2">Yes</td><td class="column-3">Yes</td><td class="column-4">Yes</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">Works in Web Start</td><td class="column-2">No</td><td class="column-3">Yes</td><td class="column-4">Yes</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">Works in Application</td><td class="column-2">No</td><td class="column-3">No</td><td class="column-4">Yes</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">Works on Java 1.5</td><td class="column-2">Yes</td><td class="column-3">Yes</td><td class="column-4">No</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">Can Set Target</td><td class="column-2">Yes</td><td class="column-3">No</td><td class="column-4">No</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">Default Target</td><td class="column-2">_self</td><td class="column-3">_blank</td><td class="column-4">_self</td>
	</tr>
</tbody>
</table>

<h3>AppletStageExtension</h3>
<p>The first option is to use the JavaFX AppletStageExtension.  This is only available if you are running as an Applet, but also gives you the most control over how the hyperlink is launched.  In addition to a URL you can also specify a target, which can be any of the standard HTML targets including the following (excerpted from the <a href="http://java.sun.com/javafx/1.2/docs/api/javafx.stage/javafx.stage.AppletStageExtension.html">AppletStageExtension javadocs</a>):</p>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Target Argument</th><th class="column-2">Description</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"_self"</td><td class="column-2">Show in the window and frame that contain the applet.</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"_parent"</td><td class="column-2">Show in the applet’s parent frame. If the applet’s frame has no parent frame, acts the same as “_self”.</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">"_top"</td><td class="column-2">Show in the top-level frame of the applet’s window. If the applet’s frame is the top-level frame, acts the same as “_self”.</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">"_blank"</td><td class="column-2">Show in a new, unnamed top-level window.</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">name</td><td class="column-2">Show in the frame or window named name. If a target named name  does not already exist, a new top-level window with the specified name is created, and the document is shown there.</td>
	</tr>
</tbody>
</table>

<h3>Web Start BasicService</h3>
<p>The second option is to use the Web Start BasicService.  This works from both JavaFX Applets and Web Start applications, but does not let you specify the HTML target.  It is effectively the same as using the AppletStageExtension with a target of &#8220;_blank&#8221;.</p>
<p>Here is a small code excerpt showing how you would call the Web Start BasicService from your JavaFX code:</p>
<pre class="brush: javafx; title: ; notranslate">
def basicService = ServiceManager.lookup(&quot;javax.jnlp.BasicService&quot;) as BasicService;
basicService.showDocument(new URL(url));
</pre>
<h3>Desktop.browse</h3>
<p>The third option is to use the new Desktop class introduced in Java 1.6.  This works from Applet, Web Start applications, and Standard Execution (within a desktop Frame).  Unfortunately, it did not exist in Java 1.5, so it won&#8217;t work from JavaFX without a little hacking.</p>
<p>The quick and dirty hack is to modify your JavaFX distribution to include the rt.jar from Java 1.6 as explained in this <a href="http://steveonjava.com/2009/01/02/hacking-javafx-10-to-use-java-16-features/">earlier post</a>.  The only problem with this is you also have to get all the other developers on your project to do the same (and redo this on every upgrade).</p>
<p>The friendlier approach is to use reflection to check and see if the Desktop class is available, and then invoke the methods dynamically.  There is quite a bit more boilerplate code, but it will allow you to compile with a plain vanilla JavaFX installation, and also handle the odd case where someone is trying to run JavaFX under 1.5.  (Which is unsupported on Windows/Unix, and is now even supported on 32-bit Mac systems with the release of Snow Leopard!).</p>
<p>Since the code is easier to follow without reflection, I will show that first:</p>
<pre class="brush: javafx; title: ; notranslate">
Desktop.getDesktop().browse(new URI(url));
</pre>
<p>And here is the munged version with reflection:</p>
<pre class="brush: javafx; title: ; notranslate">
try {
    def desktopClazz = Class.forName(&quot;java.awt.Desktop&quot;);
    def desktop = desktopClazz.getMethod(&quot;getDesktop&quot;).invoke(null);
    def browseMethod = desktopClazz.getMethod(&quot;browse&quot;, [URI.class] as java.lang.Class[]);
    browseMethod.invoke(desktop, new URI(url));
} catch (e) {
    println(&quot;Upgrade to Java 6 or later to launch hyperlinks: {url}&quot;);
}
</pre>
<h2><a name="out">The Easy Way Out</a></h2>
<p>When things are easy to do, they will get done right.  To make sure that JavaFX applications do not fall prey to broken and inconsistent linking, I put together a library for <a href="http://jfxtras.org/">JFXtras</a> that takes care of all the plumbing for you.</p>
<p>There is a new JFXtras class called BrowserUtil that has a very simple API:</p>
<pre class="brush: javafx; title: ; notranslate">
BrowserUtil.browse(url);
</pre>
<p>or</p>
<pre class="brush: javafx; title: ; notranslate">
BrowserUtil.browse(url, target);
</pre>
<p>It is that simple&#8230;  Conversion of string URLs to URL or URI objects, selection of the correct API based on your deployment mode, and failover modes based on the Java version are all included.</p>
<p>In addition, I created an extended Hyperlink called the XHyperlink.  This behaves identically to the built-in control, with the addition of simple configuration of URL navigation (this is what hyperlinks are designed for, right?)  The usage of the XHyperlink class is as follows:</p>
<pre class="brush: javafx; title: ; notranslate">
XHyperlink {
    text: &quot;Oracle's Homepage&quot;, url: &quot;http://oracle.com/&quot;}
}
</pre>
<p>All of this functionality will be included in the JFXtras 0.6 release.  If you need it now, you can build off the head of our <a href="http://code.google.com/p/jfxtras/source/browse/">repo</a>.  Otherwise we are working on a release, which I will announce on this blog shortly which you can <a href="http://twitter.com/steveonjava">follow</a>.</p>
<h2><a name="mobile">What about JavaFX mobile?</a></h2>
<p>None of these desktop techniques actually work on a mobile device, so this is not a 100% solution yet.</p>
<p>Fortunately, there is also a solution for JavaFX Mobile if you are willing to delve in to the Java ME APIs.  To do this you first need to get a handle to the MIDlet like this:</p>
<pre class="brush: javafx; title: ; notranslate">
def midlet = com.sun.javafx.runtime.adapter.MIDletAdapter.getMidlet();
</pre>
<p>And then you can call platformRequest to launch a browser on the mobile device:</p>
<pre class="brush: javafx; title: ; notranslate">
midlet.platformRequest(url);
</pre>
<p class="note">Note: This requires use of private APIs, so this may not work in future JavaFX releases.</p>
<p>It is not possible to merge this in with the desktop solution, because the JavaFX Mobile libraries do not exist on the desktop platform (and vice versa), but it is relatively easy to use this technique yourself by copying and pasting the above code sample into a helper function in your application.</p>
<div class="plus-one-wrap"><g:plusone href="http://javafx.steveonjava.com/launching-hyperlinks-from-javafx-including-mobile/"></g:plusone></div><div style="clear:both;">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://javafx.steveonjava.com/launching-hyperlinks-from-javafx-including-mobile/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

