source: trunk/src/org/expeditee/items/widgets/JfxBrowser.java@ 537

Last change on this file since 537 was 537, checked in by ngw8, 11 years ago

JfxBrowser: URI is remembered between closing and reopening Expeditee (by saving to the widget args)

  • Property svn:executable set to *
File size: 7.0 KB
Line 
1package org.expeditee.items.widgets;
2
3import java.awt.Color;
4import java.awt.Component;
5import java.awt.FlowLayout;
6import java.awt.event.ComponentEvent;
7import java.awt.event.ComponentListener;
8import java.io.File;
9import java.io.IOException;
10import java.lang.reflect.Constructor;
11import java.lang.reflect.InvocationTargetException;
12import java.lang.reflect.Method;
13import java.net.MalformedURLException;
14import java.net.URL;
15import java.net.URLClassLoader;
16
17import javax.swing.JPanel;
18
19import org.expeditee.items.Text;
20
21/**
22 * Web browser using a JavaFX WebView.
23 *
24 * @author ngw8
25 * @author jts21
26 */
27public class JfxBrowser extends DataFrameWidget {
28 private WebBrowserPanel _browser;
29
30 static Class JFXPanel;
31
32 static Class Platform;
33 static Method PlatformRunLater;
34
35 static Class Group;
36 static Method GroupGetChildren;
37
38 static Class Scene;
39 static Constructor SceneConstructor;
40
41 static Class WebView;
42 static Method JFXPanelSetScene;
43 static Method WebViewSetPrefSize;
44 static Method WebViewGetEngine;
45
46 static Class WebEngine;
47 static Method WebEngineLoad;
48 static Method WebEngineGetLocation;
49
50 static {
51 String javaLibDir = System.getProperty("java.home") + File.separator + "lib" + File.separator;
52 try {
53 ClassLoader classLoader = ClassLoader.getSystemClassLoader();
54
55
56 File jar = new File(javaLibDir + "jfxrt.jar");
57
58 Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
59 addURL.setAccessible(true);
60 addURL.invoke(classLoader, jar.toURI().toURL());
61
62 JFXPanel = Class.forName("javafx.embed.swing.JFXPanel", false, classLoader);
63
64 Platform = classLoader.loadClass("javafx.application.Platform");
65 PlatformRunLater = Platform.getMethod("runLater", Runnable.class);
66
67 // Setting JFX to not exit when all panels are hidden, otherwise moving, resizing and changing frames will
68 // cause JFX to exit, preventing JFX elements from displaying at all
69 Platform.getMethod("setImplicitExit", boolean.class).invoke(null, false);
70
71 Group = classLoader.loadClass("javafx.scene.Group");
72 GroupGetChildren = Group.getMethod("getChildren");
73
74 Scene = classLoader.loadClass("javafx.scene.Scene");
75 SceneConstructor = Scene.getConstructor(classLoader.loadClass("javafx.scene.Parent"));
76
77 WebView = classLoader.loadClass("javafx.scene.web.WebView");
78 JFXPanelSetScene = JFXPanel.getMethod("setScene", Scene);
79 WebViewSetPrefSize = WebView.getMethod("setPrefSize", double.class, double.class);
80 WebViewGetEngine = WebView.getMethod("getEngine");
81
82 WebEngine = classLoader.loadClass("javafx.scene.web.WebEngine");
83 WebEngineLoad = WebEngine.getMethod("load", String.class);
84 WebEngineGetLocation = WebEngine.getMethod("getLocation");
85
86
87 } catch (MalformedURLException e) {
88 e.printStackTrace();
89 } catch (ClassNotFoundException e) {
90 e.printStackTrace();
91 } catch (NoSuchMethodException e) {
92 e.printStackTrace();
93 } catch (SecurityException e) {
94 e.printStackTrace();
95 } catch (IllegalAccessException e) {
96 e.printStackTrace();
97 } catch (IllegalArgumentException e) {
98 e.printStackTrace();
99 } catch (InvocationTargetException e) {
100 e.printStackTrace();
101 } catch (IOException e) {
102 e.printStackTrace();
103 }
104 }
105
106 private static class WebBrowserPanel extends JPanel implements ComponentListener {
107
108 private static final long serialVersionUID = 1L;
109
110 Object webview;
111 Object jfxPanel;
112
113 /**
114 * @return A JPanel that either contains a JavaFX Webview or an empty
115 * panel if the JFX panel can't be initialized
116 */
117 public WebBrowserPanel(final String url) {
118 this.addComponentListener(this);
119 try {
120 jfxPanel = JFXPanel.newInstance();
121
122 this.add((Component) jfxPanel);
123
124 // Removing the gap between the top of the panel and the JFXPanel
125 ((FlowLayout) this.getLayout()).setVgap(0);
126
127 // Setting bg color to be the same as bg color of widgets when they're being dragged/resized
128 this.setBackground(new Color(100, 100, 100));
129
130 PlatformRunLater.invoke(null, new Runnable() {
131 @Override
132 public void run() {
133 initFx(url);
134 }
135 });
136 } catch (IllegalAccessException e) {
137 e.printStackTrace();
138 } catch (IllegalArgumentException e) {
139 e.printStackTrace();
140 } catch (InvocationTargetException e) {
141 e.printStackTrace();
142 } catch (InstantiationException e) {
143 e.printStackTrace();
144 }
145 }
146
147 /**
148 * Sets up the browser frame. JFX requires this to be run on a new thread.
149 *
150 * @param url
151 * The URL to be loaded when the browser is created
152 */
153 private void initFx(String url) {
154 try {
155 this.webview = WebView.newInstance();
156 WebViewSetPrefSize.invoke(this.webview, this.getWidth(), this.getHeight());
157
158 Object scene = SceneConstructor.newInstance(this.webview);
159
160 JFXPanelSetScene.invoke(jfxPanel, scene);
161
162 WebEngineLoad.invoke(WebViewGetEngine.invoke(this.webview), url);
163 } catch (IllegalAccessException e) {
164 e.printStackTrace();
165 } catch (IllegalArgumentException e) {
166 e.printStackTrace();
167 } catch (InvocationTargetException e) {
168 e.printStackTrace();
169 } catch (InstantiationException e) {
170 e.printStackTrace();
171 } catch (SecurityException e) {
172 e.printStackTrace();
173 }
174 }
175
176 @Override
177 public void componentHidden(ComponentEvent e) {
178 }
179
180 @Override
181 public void componentMoved(ComponentEvent e) {
182 }
183
184 @Override
185 public void componentResized(ComponentEvent e) {
186 // Webview is initialized in a 'run later' thread, so must check that it has actually been created before
187 // trying to resize
188 if (webview != null) {
189 try {
190 WebViewSetPrefSize.invoke(this.webview, this.getWidth(), this.getHeight());
191 } catch (IllegalAccessException e1) {
192 e1.printStackTrace();
193 } catch (IllegalArgumentException e1) {
194 e1.printStackTrace();
195 } catch (InvocationTargetException e1) {
196 e1.printStackTrace();
197 } catch (SecurityException e1) {
198 e1.printStackTrace();
199 }
200 }
201 }
202
203 @Override
204 public void componentShown(ComponentEvent e) {
205 }
206 }
207
208 public JfxBrowser(Text source, String[] args) {
209 // Initial page is either the page stored in the arguments (if there is one stored) or Google
210 super(source, new WebBrowserPanel((args != null && args.length > 0) ? args[0] : "http://google.com"), -1, 500, -1, -1, 300, -1);
211
212 _browser = (WebBrowserPanel) _swingComponent;
213 }
214
215 public void navigate(final String url) {
216 try {
217 WebEngineLoad.invoke(WebViewGetEngine.invoke(this._browser.webview), url);
218 } catch (IllegalAccessException e) {
219 e.printStackTrace();
220 } catch (IllegalArgumentException e) {
221 e.printStackTrace();
222 } catch (InvocationTargetException e) {
223 e.printStackTrace();
224 }
225 }
226
227 @Override
228 protected String[] getArgs() {
229 String[] r = null;
230 if (this._browser.webview != null) {
231 try {
232 r = new String[] { (String) WebEngineGetLocation.invoke(WebViewGetEngine.invoke(this._browser.webview)) };
233 } catch (IllegalAccessException e) {
234 e.printStackTrace();
235 } catch (IllegalArgumentException e) {
236 e.printStackTrace();
237 } catch (InvocationTargetException e) {
238 e.printStackTrace();
239 } catch (SecurityException e) {
240 e.printStackTrace();
241 }
242 }
243 return r;
244 }
245}
Note: See TracBrowser for help on using the repository browser.