1+ package com .openfin .desktop .demo ;
2+
3+ import com .openfin .desktop .*;
4+ import com .openfin .desktop .Window ;
5+ import com .sun .javafx .tk .TKStage ;
6+ import javafx .application .Application ;
7+ import javafx .application .Platform ;
8+ import javafx .collections .ObservableList ;
9+ import javafx .event .ActionEvent ;
10+ import javafx .event .EventHandler ;
11+ import javafx .scene .Group ;
12+ import javafx .scene .Scene ;
13+ import javafx .scene .control .Button ;
14+ import javafx .scene .layout .AnchorPane ;
15+ import javafx .scene .layout .StackPane ;
16+ import javafx .stage .Stage ;
17+ import org .slf4j .Logger ;
18+ import org .slf4j .LoggerFactory ;
19+
20+ import java .lang .reflect .Method ;
21+
22+ /**
23+ * Java example to embed HTML5 window in JavaFX window
24+ *
25+ * Created by wche on 3/13/15.
26+ *
27+ */
28+
29+ public class FxDemo extends Application implements DesktopStateListener {
30+ private final static Logger logger = LoggerFactory .getLogger (FxDemo .class .getName ());
31+
32+ private DesktopConnection desktopConnection ;
33+ private Button btnStart , btnStop ;
34+ private StackPane embedPane ;
35+
36+ protected String openfin_app_url = "https://cdn.openfin.co/examples/junit/SimpleDockingExample.html" ; // source is in release/SimpleDockingExample.html
37+ protected String startupUuid = "OpenFinHelloWorld" ;
38+ private long stageHWndId ;
39+ private com .openfin .desktop .Application startupHtml5app ;
40+
41+ @ Override
42+ public void start (Stage stage ) {
43+ btnStart = new Button ();
44+ btnStart .setText ("Launch OpenFin" );
45+ btnStart .setLayoutX (10 );
46+ btnStart .setLayoutY (10 );
47+ btnStart .setOnAction (new EventHandler <ActionEvent >() {
48+ @ Override
49+ public void handle (ActionEvent event ) {
50+ launchOpenFin ();
51+ }
52+ });
53+ btnStop = new Button ();
54+ btnStop .setText ("Shut down OpenFin" );
55+ btnStop .setLayoutX (200 );
56+ btnStop .setLayoutY (10 );
57+ btnStop .setDisable (true );
58+ btnStop .setOnAction (new EventHandler <ActionEvent >() {
59+ @ Override
60+ public void handle (ActionEvent event ) {
61+ shutDown ();
62+ }
63+ });
64+
65+ AnchorPane anchorPane = new AnchorPane ();
66+ anchorPane .getChildren ().add (btnStart );
67+ anchorPane .getChildren ().add (btnStop );
68+
69+ //Creating a Group object
70+ Group root = new Group ();
71+
72+ //Retrieving the observable list object
73+ ObservableList list = root .getChildren ();
74+
75+
76+ embedPane = new StackPane ();
77+ embedPane .setLayoutX (10 );
78+ embedPane .setLayoutY (50 );
79+ AnchorPane .setTopAnchor (embedPane , 50.0 );
80+ AnchorPane .setBottomAnchor (embedPane , 0.0 );
81+ AnchorPane .setLeftAnchor (embedPane , 0.0 );
82+ AnchorPane .setRightAnchor (embedPane , 0.0 );
83+ anchorPane .getChildren ().add (embedPane );
84+ embedPane .widthProperty ().addListener (observable -> {
85+ onEmbedComponentSizeChange ();
86+ });
87+ embedPane .heightProperty ().addListener (observable -> {
88+ onEmbedComponentSizeChange ();
89+ });
90+
91+ //Creating a scene object
92+ Scene scene = new Scene (anchorPane , 800 , 800 );
93+
94+ //Setting title to the Stage
95+ stage .setTitle ("FX Demo" );
96+
97+ //Adding scene to the stage
98+ stage .setScene (scene );
99+
100+ //Displaying the contents of the stage
101+ stage .show ();
102+
103+ this .stageHWndId = getWindowHandle (stage );
104+ }
105+
106+ private void launchOpenFin () {
107+ RuntimeConfiguration cfg = new RuntimeConfiguration ();
108+ cfg .setRuntimeVersion ("stable" );
109+ cfg .setAdditionalRuntimeArguments (" --v=1 " );
110+ try {
111+ desktopConnection = new DesktopConnection ("JavaFxDemo" );
112+ desktopConnection .connect (cfg , this , 60 );
113+ } catch (Exception e ) {
114+ e .printStackTrace ();
115+ }
116+ }
117+
118+ private void launchHtmlApp () {
119+ // launch 5 instances of same example app
120+ int width = 500 , height =500 ;
121+ try {
122+ String url = java .lang .System .getProperty ("com.openfin.demo.embed.URL" );
123+ if (url != null ) {
124+ openfin_app_url = url ;
125+ }
126+ ApplicationOptions options = new ApplicationOptions (startupUuid , startupUuid , openfin_app_url );
127+ options .setApplicationIcon ("http://openfin.github.io/snap-and-dock/openfin.ico" );
128+ WindowOptions mainWindowOptions = new WindowOptions ();
129+ mainWindowOptions .setAutoShow (false );
130+ mainWindowOptions .setDefaultHeight (height );
131+ mainWindowOptions .setDefaultLeft (10 );
132+ mainWindowOptions .setDefaultTop (50 );
133+ mainWindowOptions .setDefaultWidth (width );
134+ mainWindowOptions .setShowTaskbarIcon (true );
135+ mainWindowOptions .setSaveWindowState (false ); // set to false so all windows start at same initial positions for each run
136+ mainWindowOptions .setFrame (false );
137+ mainWindowOptions .setContextMenu (true );
138+ mainWindowOptions .setResizeRegionSize (0 );
139+ options .setMainWindowOptions (mainWindowOptions );
140+ DemoUtils .runApplication (options , this .desktopConnection , new AckListener () {
141+ @ Override
142+ public void onSuccess (Ack ack ) {
143+ com .openfin .desktop .Application app = (com .openfin .desktop .Application ) ack .getSource ();
144+ try {
145+ Thread .sleep (1000 );
146+ embedStartupApp ();
147+ } catch (Exception ex ) {
148+ ex .printStackTrace ();
149+ }
150+ }
151+ @ Override
152+ public void onError (Ack ack ) {
153+ logger .error (String .format ("Error launching %s %s" , options .getUUID (), ack .getReason ()));
154+ }
155+ });
156+ } catch (Exception e ) {
157+ logger .error ("Error launching app" , e );
158+ }
159+ }
160+
161+ private void embedStartupApp () {
162+ try {
163+ if (startupHtml5app == null ) {
164+ startupHtml5app = com .openfin .desktop .Application .wrap (this .startupUuid , this .desktopConnection );
165+ }
166+
167+ Window html5Wnd = startupHtml5app .getWindow ();
168+ html5Wnd .embedInto (stageHWndId , (int )this .embedPane .getLayoutX (), (int )this .embedPane .getLayoutY (),
169+ (int )this .embedPane .getWidth (), (int )this .embedPane .getHeight (), new AckListener () {
170+ @ Override
171+ public void onSuccess (Ack ack ) {
172+ if (ack .isSuccessful ()) {
173+ } else {
174+ logger .error ("embedding failed: " + ack .getJsonObject ().toString ());
175+ }
176+ }
177+ @ Override
178+ public void onError (Ack ack ) {
179+ }
180+ });
181+ } catch (Exception e ) {
182+ e .printStackTrace ();
183+ }
184+ }
185+
186+ private void onEmbedComponentSizeChange () {
187+ logger .info (String .format ("%f %f " , this .embedPane .getLayoutX (), this .embedPane .getLayoutY ()));
188+ if (startupHtml5app != null ) {
189+ startupHtml5app .getWindow ().embedComponentSizeChange ((int )this .embedPane .getLayoutX (), (int )this .embedPane .getLayoutY (),
190+ (int )this .embedPane .getWidth (), (int )this .embedPane .getHeight ());
191+ }
192+ }
193+
194+ private void shutDown () {
195+ try {
196+ this .desktopConnection .exit ();
197+ Platform .exit ();
198+ } catch (Exception e ) {
199+ e .printStackTrace ();
200+ }
201+ }
202+
203+ private long getWindowHandle (Stage stage ) {
204+ long handle = -1 ;
205+ try {
206+ TKStage tkStage = stage .impl_getPeer ();
207+ Method getPlatformWindow = tkStage .getClass ().getDeclaredMethod ("getPlatformWindow" );
208+ getPlatformWindow .setAccessible (true );
209+ Object platformWindow = getPlatformWindow .invoke (tkStage );
210+ Method getNativeHandle = platformWindow .getClass ().getMethod ( "getNativeHandle" );
211+ getNativeHandle .setAccessible (true );
212+ Object nativeHandle = getNativeHandle .invoke (platformWindow );
213+ handle = (Long ) nativeHandle ;
214+ } catch (Throwable e ) {
215+ logger .error ("Error getting Window Pointer" , e );
216+ }
217+ logger .info (String .format ("Stage hwnd %d" , handle ));
218+ return handle ;
219+ }
220+
221+ @ Override
222+ public void onReady () {
223+ logger .info ("Connected to OpenFin Runtime" );
224+ btnStart .setDisable (true );
225+ btnStop .setDisable (false );
226+ launchHtmlApp ();
227+ }
228+
229+ @ Override
230+ public void onClose () {
231+ logger .info ("Disconnected from OpenFin Runtime" );
232+ btnStart .setDisable (false );
233+ btnStop .setDisable (true );
234+ }
235+
236+ @ Override
237+ public void onError (String s ) {
238+ }
239+
240+ @ Override
241+ public void onMessage (String s ) {
242+ }
243+
244+ @ Override
245+ public void onOutgoingMessage (String s ) {
246+ }
247+
248+ public static void main (String args []) {
249+ launch (args );
250+ }
251+
252+ }
0 commit comments