Index: /trunk/src/org/expeditee/items/widgets/JfxBrowser.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/JfxBrowser.java	(revision 517)
+++ /trunk/src/org/expeditee/items/widgets/JfxBrowser.java	(revision 517)
@@ -0,0 +1,239 @@
+package org.expeditee.items.widgets;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+import org.expeditee.items.Text;
+
+/**
+ * Web browser using a JavaFX WebView.
+ * 
+ * @author ngw8
+ * @author jts21
+ * 
+ */
+public class JfxBrowser extends DataFrameWidget {
+
+	private WebBrowserPanel _browser;
+
+	static Class JFXPanel;
+
+	static Class Platform;
+	static Method PlatformRunLater;
+
+	static Class Group;
+	static Method GroupGetChildren;
+
+	static Class Scene;
+	static Constructor SceneConstructor;
+
+	static Class WebView;
+	static Method JFXPanelSetScene;
+	static Method WebViewSetPrefSize;
+	static Method WebViewGetEngine;
+	
+	static Class WebEngine;
+	static Method WebEngineLoad;
+
+	static {
+		String javaLibDir = System.getProperty("java.home") + File.separator + "lib" + File.separator;
+
+		try {
+
+			ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+
+			File jar = new File(javaLibDir + "jfxrt.jar");
+
+			Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+			addURL.setAccessible(true);
+			addURL.invoke(classLoader, jar.toURI().toURL());
+
+			
+			JFXPanel = Class.forName("javafx.embed.swing.JFXPanel", false, classLoader);
+
+			Platform = classLoader.loadClass("javafx.application.Platform");
+			PlatformRunLater = Platform.getMethod("runLater", Runnable.class);
+
+			Group = classLoader.loadClass("javafx.scene.Group");
+			GroupGetChildren = Group.getMethod("getChildren");
+
+			Scene = classLoader.loadClass("javafx.scene.Scene");
+			SceneConstructor = Scene.getConstructor(classLoader.loadClass("javafx.scene.Parent"));
+
+			WebView = classLoader.loadClass("javafx.scene.web.WebView");
+			JFXPanelSetScene = JFXPanel.getMethod("setScene", Scene);
+			WebViewSetPrefSize = WebView.getMethod("setPrefSize", double.class, double.class);
+			WebViewGetEngine = WebView.getMethod("getEngine");
+			
+			WebEngine = classLoader.loadClass("javafx.scene.web.WebEngine");
+			WebEngineLoad = WebEngine.getMethod("load", String.class);
+
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		} catch (ClassNotFoundException e) {
+			e.printStackTrace();
+		} catch (NoSuchMethodException e) {
+			e.printStackTrace();
+		} catch (SecurityException e) {
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private static class WebBrowserPanel extends JPanel implements ComponentListener {
+		
+		private static final long serialVersionUID = 1L;
+
+		Object webview;
+		Object jfxPanel;
+		
+		/**
+		 * @return A JPanel that either contains a JavaFX Webview or an empty
+		 *         panel if the JFX panel can't be initialized
+		 */
+		public WebBrowserPanel(final String url) {
+			this.addComponentListener(this);
+			try {
+				jfxPanel = JFXPanel.newInstance();
+
+				this.add((Component) jfxPanel);
+
+				((FlowLayout) this.getLayout()).setVgap(0);
+				this.setBackground(Color.cyan);
+				this.setBorder(new EmptyBorder(0, 0, 0, 0));
+
+				PlatformRunLater.invoke(null, new Runnable() {
+					@Override
+					public void run() {
+						initFx(url);
+					}
+				});
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (InvocationTargetException e) {
+				e.printStackTrace();
+			} catch (InstantiationException e) {
+				e.printStackTrace();
+			}
+		}
+
+		/**
+		 * Sets up the browser frame. JFX requires it to be run on a new thread.
+		 * 
+		 * @param url
+		 *            The URL to be loaded when the browser is created
+		 */
+		private void initFx(String url) {
+			try {
+				Object group = Group.newInstance();
+				Object scene = SceneConstructor.newInstance(group);
+
+				JFXPanelSetScene.invoke(jfxPanel, scene);
+
+				this.webview = WebView.newInstance();
+
+				WebViewSetPrefSize.invoke(this.webview, this.getWidth(), this.getHeight());
+
+				((List) GroupGetChildren.invoke(group)).add(this.webview);
+
+				WebEngineLoad.invoke(WebViewGetEngine.invoke(this.webview), url);
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (InvocationTargetException e) {
+				e.printStackTrace();
+			} catch (InstantiationException e) {
+				e.printStackTrace();
+			}
+		}
+
+		@Override
+		public void componentHidden(ComponentEvent e) {
+		}
+
+		@Override
+		public void componentMoved(ComponentEvent e) {
+		}
+
+		@Override
+		public void componentResized(ComponentEvent e) {
+			if (webview != null) {
+				try {
+					WebViewSetPrefSize.invoke(this.webview, this.getWidth(), this.getHeight());
+				} catch (IllegalAccessException e1) {
+					e1.printStackTrace();
+				} catch (IllegalArgumentException e1) {
+					e1.printStackTrace();
+				} catch (InvocationTargetException e1) {
+					e1.printStackTrace();
+				}
+			}
+			
+		}
+
+		@Override
+		public void componentShown(ComponentEvent e) {
+		}
+
+
+	}
+
+	public JfxBrowser(Text source, String[] args) {
+		super(source, new WebBrowserPanel("http://waikato.ac.nz"), 100, 500, -1, 100, 300, -1);
+
+		_browser = (WebBrowserPanel) _swingComponent;
+	}
+
+	@Override
+	protected String[] getArgs() {
+		return null;
+	}
+
+	public void navigate(String url) {
+		try {
+			WebEngineLoad.invoke(WebViewGetEngine.invoke(this._browser.webview), url);
+		} catch (IllegalAccessException e) {
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void setSourceData(List<String> data) {
+		super.setSourceData(data);
+		if (data != null && data.size() > 0) {
+			navigate(data.get(0));
+		}
+	}
+	
+	@Override
+	protected List<String> getData() {
+		return _textRepresentation.getData();
+	}
+	
+}
