j4rs/
jfx.rs

1// Copyright 2020 astonbitecode
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use std::convert::TryFrom;
15use std::env;
16use std::path::PathBuf;
17
18use crate::api::instance::{Instance, InstanceReceiver};
19use crate::api::{
20    self, CLASS_J4RS_EVENT_HANDLER, CLASS_J4RS_FXML_LOADER, CLASS_NATIVE_CALLBACK_TO_RUST_CHANNEL_SUPPORT,
21};
22use crate::errors;
23use crate::errors::{opt_to_res, J4RsError};
24use crate::{InvocationArg, Jvm, MavenArtifact};
25
26/// Provides JavaFx support.
27pub trait JavaFxSupport {
28    /// Triggers the start of a JavaFX application.
29    /// When the JavaFX application starts, the `InstanceReceiver` channel will receive an Instance of `javafx.stage.Stage`.
30    ///
31    /// The UI may start being built using the provided `Stage`
32    fn start_javafx_app(&self) -> errors::Result<InstanceReceiver>;
33    /// Deploys the required dependencies to run a JavaFX application in order to be able to be used by j4rs.
34    fn deploy_javafx_dependencies(&self) -> errors::Result<()>;
35    /// Creates an instance receiver that will be receiving `Instance`s of events.
36    /// The fx_event_type argument is the type of the event that we want to handle and receive Instances for.
37    ///
38    /// For example, to create an `InstanceReceiver` for a 'javafx.scene.control.Button',
39    /// you need to call the method by using the button as the _instance_ argument
40    /// `FxEventType::ActionEvent_Action` as the fx_event_type argument
41    fn get_javafx_event_receiver(
42        &self,
43        instance: &Instance,
44        fx_event_type: FxEventType,
45    ) -> errors::Result<InstanceReceiver>;
46    /// Creates an instance receiver that will be receiving `Instance`s of events for onclose requests of a `Stage`.
47    ///
48    /// The instance passed as argument needs to be of class `javafx.stage.Stage`.
49    fn on_close_event_receiver(&self, stage: &Instance) -> errors::Result<InstanceReceiver>;
50    /// Loads a FXML and returns a Result of a FxController for it.
51    fn load_fxml(&self, path: &PathBuf, stage: &Instance) -> errors::Result<FxController>;
52}
53
54impl JavaFxSupport for Jvm {
55    /// Triggers the start of a JavaFX application.
56    /// When the JavaFX application starts, the `InstanceReceiver` channel will receive an Instance of `javafx.stage.Stage`.
57    ///
58    /// The UI may start being built using the provided `Stage`
59    fn start_javafx_app(&self) -> errors::Result<InstanceReceiver> {
60        let fx_callback = self.create_instance(
61            "org.astonbitecode.j4rs.api.jfx.FxApplicationStartCallback",
62            InvocationArg::empty(),
63        )?;
64
65        self.invoke_to_channel(&fx_callback, "setCallbackToApplicationAndLaunch", InvocationArg::empty())
66    }
67
68    /// Creates an instance receiver that will be receiving `Instance`s of events.
69    /// The fx_event_type argument is the type of the event that we want to handle and receive Instances for.
70    ///
71    /// For example, to create an `InstanceReceiver` for a 'javafx.scene.control.Button',
72    /// you need to call the method by using the button as the _instance_ argument
73    /// `FxEventType::ActionEvent_Action` as the fx_event_type argument
74    fn get_javafx_event_receiver(
75        &self,
76        instance: &Instance,
77        fx_event_type: FxEventType,
78    ) -> errors::Result<InstanceReceiver> {
79        let j4rs_event_handler = self.create_instance(CLASS_J4RS_EVENT_HANDLER, InvocationArg::empty())?;
80        let btn_action_channel = self.init_callback_channel(&j4rs_event_handler)?;
81
82        let (event_class, field) = fx_event_type_to_event_class_and_field(fx_event_type);
83        let event_type_instance = self.static_class_field(&event_class, &field)?;
84
85        self.invoke(
86            instance,
87            "addEventHandler",
88            &[
89                InvocationArg::try_from(event_type_instance)?,
90                InvocationArg::try_from(j4rs_event_handler)?,
91            ],
92        )?;
93        Ok(btn_action_channel)
94    }
95
96    /// Creates an instance receiver that will be receiving `Instance`s of events for onclose requests of a `Stage`.
97    ///
98    /// The instance passed as argument needs to be of class `javafx.stage.Stage`.
99    fn on_close_event_receiver(&self, stage: &Instance) -> errors::Result<InstanceReceiver> {
100        let j4rs_event_handler = self.create_instance(CLASS_J4RS_EVENT_HANDLER, InvocationArg::empty())?;
101        let action_channel = self.init_callback_channel(&j4rs_event_handler)?;
102        self.invoke(
103            stage,
104            "setOnCloseRequest",
105            &[InvocationArg::try_from(j4rs_event_handler)?],
106        )?;
107        Ok(action_channel)
108    }
109
110    /// Deploys the required dependencies to run a JavaFX application in order to be able to be used by j4rs.
111    fn deploy_javafx_dependencies(&self) -> errors::Result<()> {
112        let target_os_res = env::var("CARGO_CFG_TARGET_OS");
113        if target_os_res.is_ok() {
114            let target_os = target_os_res.as_ref().map(|x| &**x).unwrap_or("unknown");
115            if target_os == "android" {
116                return Ok(());
117            }
118
119            let classifier = if target_os == "windows" {
120                "win"
121            } else if target_os == "macos" {
122                "mac"
123            } else {
124                target_os
125            };
126
127            println!("cargo:warning=javafx dependencies deployment...");
128            maven(&format!("org.openjfx:javafx-base:{}", api::java_fx_version()), self);
129            maven(
130                &format!("org.openjfx:javafx-base:{}:{}", api::java_fx_version(), classifier),
131                self,
132            );
133            maven(&format!("org.openjfx:javafx-controls:{}", api::java_fx_version()), self);
134            maven(
135                &format!("org.openjfx:javafx-controls:{}:{}", api::java_fx_version(), classifier),
136                self,
137            );
138            maven(&format!("org.openjfx:javafx-fxml:{}", api::java_fx_version()), self);
139            maven(
140                &format!("org.openjfx:javafx-fxml:{}:{}", api::java_fx_version(), classifier),
141                self,
142            );
143            maven(&format!("org.openjfx:javafx-graphics:{}", api::java_fx_version()), self);
144            maven(
145                &format!("org.openjfx:javafx-graphics:{}:{}", api::java_fx_version(), classifier),
146                self,
147            );
148            maven(&format!("org.openjfx:javafx-media:{}", api::java_fx_version()), self);
149            maven(
150                &format!("org.openjfx:javafx-media:{}:{}", api::java_fx_version(), classifier),
151                self,
152            );
153            maven(&format!("io.github.astonbitecode:j4rs-javafx:{}", api::j4rs_version()), self);
154            println!("cargo:warning=javafx dependencies deployment completed...");
155
156            Ok(())
157        } else {
158            Err(J4RsError::GeneralError("deploy_javafx_dependencies can be used only during build time. It should be called by a build script.".to_string()))
159        }
160    }
161
162    fn load_fxml(&self, path: &PathBuf, stage: &Instance) -> errors::Result<FxController> {
163        let cloned = self.clone_instance(stage)?;
164        let path_str = opt_to_res(path.to_str())?;
165        let controller = self.invoke_static(
166            CLASS_J4RS_FXML_LOADER,
167            "loadFxml",
168            &[InvocationArg::try_from(cloned)?, InvocationArg::try_from(path_str)?],
169        )?;
170        Ok(FxController::new(controller))
171    }
172}
173
174fn maven(s: &str, jvm: &Jvm) {
175    let artifact = MavenArtifact::from(s);
176    let _ = jvm.deploy_artifact(&artifact).map_err(|error| {
177        println!(
178            "cargo:warning=Could not download Maven artifact {}: {:?}",
179            s, error
180        );
181    });
182}
183
184pub struct FxController {
185    controller: Instance,
186}
187
188impl FxController {
189    fn new(controller: Instance) -> FxController {
190        FxController { controller }
191    }
192
193    /// Creates an InstanceReceiver that will receive an Event once the Controller in initialized by the JavaFX framework.
194    ///
195    /// JavaFX FXMLLoader will automatically do the call after the root element of the controller has been completely processed.
196    pub fn on_initialized_callback(&self, jvm: &Jvm) -> errors::Result<InstanceReceiver> {
197        let channel_support =
198            jvm.create_instance(CLASS_NATIVE_CALLBACK_TO_RUST_CHANNEL_SUPPORT, InvocationArg::empty())?;
199        let instance_receiver = jvm.init_callback_channel(&channel_support);
200        jvm.invoke(
201            &self.controller,
202            "addControllerInitializedCallback",
203            &[InvocationArg::try_from(channel_support)?],
204        )?;
205        instance_receiver
206    }
207
208    /// Returns an InstanceReceiver that receives events of etype fx_event_type from the JavaFX node with the specified node_id (id attribute of the fxml element).
209    pub fn get_event_receiver_for_node(
210        &self,
211        node_id: &str,
212        fx_event_type: FxEventType,
213        jvm: &Jvm,
214    ) -> errors::Result<InstanceReceiver> {
215        let j4rs_event_handler = jvm.create_instance(CLASS_J4RS_EVENT_HANDLER, InvocationArg::empty())?;
216        let event_channel = jvm.init_callback_channel(&j4rs_event_handler)?;
217        let (event_class, field) = fx_event_type_to_event_class_and_field(fx_event_type);
218        let event_type_instance = jvm.static_class_field(&event_class, &field)?;
219        jvm.invoke(
220            &self.controller,
221            "addEventHandler",
222            &[
223                InvocationArg::try_from(node_id)?,
224                InvocationArg::try_from(j4rs_event_handler)?,
225                InvocationArg::try_from(event_type_instance)?,
226            ],
227        )?;
228        Ok(event_channel)
229    }
230}
231
232#[allow(non_camel_case_types)]
233/// Types of FX events.
234pub enum FxEventType {
235    DirectEvent_Any,
236    DirectEvent_Direct,
237    RedirectedEvent_Any,
238    RedirectedEvent_Redirected,
239    FocusUngrabEvent_Any,
240    FocusUngrabEvent_FocusUngrub,
241    WorkerStateEvent_Any,
242    WorkerStateEvent_WorkerStateCancelled,
243    WorkerStateEvent_WorkerStateFailed,
244    WorkerStateEvent_WorkerStateReady,
245    WorkerStateEvent_WorkerStateRunning,
246    WorkerStateEvent_WorkerStateScheduled,
247    WorkerStateEvent_WorkerStateSucceeded,
248    ActionEvent_Any,
249    ActionEvent_Action,
250    CheckboxTreeItem_TreeModificationEvent_Any,
251    DialogEvent_Any,
252    DialogEvent_DialogCloseRequest,
253    DialogEvent_DialogHidden,
254    DialogEvent_DialogHiding,
255    DialogEvent_DialogShowing,
256    DialogEvent_DialogShown,
257    Listview_EditEvent_Any,
258    ScrollToEvent_Any,
259    SortEvent_Any,
260    TableColumn_CellEditEvent_Any,
261    TreeItem_TreeModificationEvent_Any,
262    TreeTableView_EditEvent_Any,
263    TreeView_EditEvent_Any,
264    ContextMenuEvent_Any,
265    ContextMenuEvent_ContextMenuRequested,
266    DragEvent_Any,
267    DragEvent_DragDone,
268    DragEvent_DragDropped,
269    DragEvent_DragEntered,
270    DragEvent_DragEnteredTarget,
271    DragEvent_DragExited,
272    DragEvent_DragExitedTarget,
273    DragEvent_DragOver,
274    GestureEvent_Any,
275    InputEvent_Any,
276    InputMethodEvent_Any,
277    InputMethodEvent_InputMethodTextChanged,
278    KeyEvent_Any,
279    KeyEvent_KeyPressed,
280    KeyEvent_KeyReleased,
281    KeyEvent_KeyTyped,
282    MouseDragEvent_Any,
283    MouseDragEvent_DragDetected,
284    MouseDragEvent_MouseClicked,
285    MouseDragEvent_MouseDragEntered,
286    MouseDragEvent_MouseDragEnteredTarget,
287    MouseDragEvent_MouseDragExited,
288    MouseDragEvent_MouseDragExitedTarget,
289    MouseDragEvent_MouseDragOver,
290    MouseDragEvent_MouseDragReleased,
291    MouseDragEvent_MouseDragged,
292    MouseDragEvent_MouseEntered,
293    MouseDragEvent_MouseEnteredTarget,
294    MouseDragEvent_MouseExited,
295    MouseDragEvent_MouseExitedTarget,
296    MouseDragEvent_MouseMoved,
297    MouseDragEvent_MousePressed,
298    MouseDragEvent_MouseReleased,
299    MouseEvent_Any,
300    MouseEvent_DragDetected,
301    MouseEvent_MouseClicked,
302    MouseEvent_MouseDragged,
303    MouseEvent_MouseEntered,
304    MouseEvent_MouseEnteredTarget,
305    MouseEvent_MouseExited,
306    MouseEvent_MouseExitedTarget,
307    MouseEvent_MouseMoved,
308    MouseEvent_MousePressed,
309    MouseEvent_MouseReleased,
310    RotateEvent_Any,
311    RotateEvent_Rotate,
312    RotateEvent_RotationFinished,
313    RotateEvent_RotationStarted,
314    ScrollEvent_Any,
315    ScrollEvent_Scroll,
316    ScrollEvent_ScrollFinished,
317    ScrollEvent_ScrollStarted,
318    SwipeEvent_Any,
319    SwipeEvent_SwipeDown,
320    SwipeEvent_SwipeLeft,
321    SwipeEvent_SwipeRight,
322    SwipeEvent_SwipeUp,
323    TouchEvent_Any,
324    TouchEvent_TouchMoved,
325    TouchEvent_TouchPressed,
326    TouchEvent_TouchReleased,
327    TouchEvent_TouchStationary,
328    ZoomEvent_Any,
329    ZoomEvent_Zoom,
330    ZoomEvent_ZoomFinished,
331    ZoomEvent_ZoomStarted,
332    MediaMediaErrorEvent_Any,
333    MediaMediaErrorEvent_MediaError,
334    MediaMediaMarkerEvent_Action,
335    MediaMediaMarkerEvent_Any,
336    TransformChangedEvent_Any,
337    TransformChangedEvent_TransformChanged,
338    WindowEvent_Any,
339    WindowEvent_WindowCloseRequest,
340    WindowEvent_WindowHidden,
341    WindowEvent_WindowHiding,
342    WindowEvent_WindowShowing,
343    WindowEvent_WindowShown,
344}
345
346fn fx_event_type_to_event_class_and_field(event_type: FxEventType) -> (String, String) {
347    let (class, field) = match event_type {
348        FxEventType::DirectEvent_Any => ("com.sun.javafx.event.DirectEvent", "ANY"),
349        FxEventType::DirectEvent_Direct => ("com.sun.javafx.event.DirectEvent", "DIRECT"),
350        FxEventType::RedirectedEvent_Any => ("com.sun.javafx.event.RedirectedEvent", "ANY"),
351        FxEventType::RedirectedEvent_Redirected => {
352            ("com.sun.javafx.event.RedirectedEvent", "REDIRECTED")
353        }
354        FxEventType::FocusUngrabEvent_Any => ("com.sun.javafx.stage.FocusUngrabEvent", "ANY"),
355        FxEventType::FocusUngrabEvent_FocusUngrub => {
356            ("com.sun.javafx.stage.FocusUngrabEvent", "FOCUS_UNGRUB")
357        }
358        FxEventType::WorkerStateEvent_Any => ("javafx.concurrent.WorkerStateEvent", "ANY"),
359        FxEventType::WorkerStateEvent_WorkerStateCancelled => (
360            "javafx.concurrent.WorkerStateEvent",
361            "WORKER_STATE_CANCELLED",
362        ),
363        FxEventType::WorkerStateEvent_WorkerStateFailed => {
364            ("javafx.concurrent.WorkerStateEvent", "WORKER_STATE_FAILED")
365        }
366        FxEventType::WorkerStateEvent_WorkerStateReady => {
367            ("javafx.concurrent.WorkerStateEvent", "WORKER_STATE_READY")
368        }
369        FxEventType::WorkerStateEvent_WorkerStateRunning => {
370            ("javafx.concurrent.WorkerStateEvent", "WORKER_STATE_RUNNING")
371        }
372        FxEventType::WorkerStateEvent_WorkerStateSucceeded => (
373            "javafx.concurrent.WorkerStateEvent",
374            "WORKER_STATE_SUCCEEDED",
375        ),
376        FxEventType::WorkerStateEvent_WorkerStateScheduled => (
377            "javafx.concurrent.WorkerStateEvent",
378            "WORKER_STATE_SCHEDULED",
379        ),
380        FxEventType::ActionEvent_Action => ("javafx.event.ActionEvent", "ACTION"),
381        FxEventType::ActionEvent_Any => ("javafx.event.ActionEvent", "ANY"),
382        FxEventType::CheckboxTreeItem_TreeModificationEvent_Any => (
383            "javafx.scene.control.CheckBoxTreeItem.TreeModificationEvent",
384            "ANY",
385        ),
386        FxEventType::DialogEvent_Any => ("javafx.scene.control.DialogEvent", "ANY"),
387        FxEventType::DialogEvent_DialogCloseRequest => {
388            ("javafx.scene.control.DialogEvent", "DIALOG_CLOSE_REQUEST")
389        }
390        FxEventType::DialogEvent_DialogHidden => {
391            ("javafx.scene.control.DialogEvent", "DIALOG_HIDDEN")
392        }
393        FxEventType::DialogEvent_DialogHiding => {
394            ("javafx.scene.control.DialogEvent", "DIALOG_HIDING")
395        }
396        FxEventType::DialogEvent_DialogShowing => {
397            ("javafx.scene.control.DialogEvent", "DIALOG_SHOWING")
398        }
399        FxEventType::DialogEvent_DialogShown => {
400            ("javafx.scene.control.DialogEvent", "DIALOG_SHOWN")
401        }
402        FxEventType::Listview_EditEvent_Any => ("javafx.scene.control.ListView.EditEvent", "ANY"),
403        FxEventType::ScrollToEvent_Any => ("javafx.scene.control.ScrollToEvent", "ANY"),
404        FxEventType::SortEvent_Any => ("javafx.scene.control.SortEvent", "ANY"),
405        FxEventType::TableColumn_CellEditEvent_Any => {
406            ("javafx.scene.control.TableColumn.CellEditEvent", "ANY")
407        }
408        FxEventType::TreeItem_TreeModificationEvent_Any => {
409            ("javafx.scene.control.TreeItem.TreeModificationEvent", "ANY")
410        }
411        FxEventType::TreeTableView_EditEvent_Any => {
412            ("javafx.scene.control.TreeTableView.EditEvent", "ANY")
413        }
414        FxEventType::TreeView_EditEvent_Any => ("javafx.scene.control.TreeView.EditEvent", "ANY"),
415        FxEventType::ContextMenuEvent_Any => ("javafx.scene.input.ContextMenuEvent", "ANY"),
416        FxEventType::ContextMenuEvent_ContextMenuRequested => (
417            "javafx.scene.input.ContextMenuEvent",
418            "CONTEXT_MENU_REQUESTED",
419        ),
420        FxEventType::DragEvent_Any => ("javafx.scene.input.DragEvent", "ANY"),
421        FxEventType::DragEvent_DragDone => ("javafx.scene.input.DragEvent", "DRAG_DONE"),
422        FxEventType::DragEvent_DragDropped => ("javafx.scene.input.DragEvent", "DRAG_DROPPED"),
423        FxEventType::DragEvent_DragEntered => ("javafx.scene.input.DragEvent", "DRAG_ENTERED"),
424        FxEventType::DragEvent_DragEnteredTarget => {
425            ("javafx.scene.input.DragEvent", "DRAG_ENTERED_TARGET")
426        }
427        FxEventType::DragEvent_DragExited => ("javafx.scene.input.DragEvent", "DRAG_EXITED"),
428        FxEventType::DragEvent_DragExitedTarget => {
429            ("javafx.scene.input.DragEvent", "DRAG_EXITED_TARGET")
430        }
431        FxEventType::DragEvent_DragOver => ("javafx.scene.input.DragEvent", "DRAG_OVER"),
432        FxEventType::GestureEvent_Any => ("javafx.scene.input.GestureEvent", "ANY"),
433        FxEventType::InputEvent_Any => ("javafx.scene.input.InputEvent", "ANY"),
434        FxEventType::InputMethodEvent_Any => ("javafx.scene.input.InputMethodEvent", "ANY"),
435        FxEventType::InputMethodEvent_InputMethodTextChanged => (
436            "javafx.scene.input.InputMethodEvent",
437            "INPUT_METHOD_TEXT_CHANGED",
438        ),
439        FxEventType::KeyEvent_Any => ("javafx.scene.input.KeyEvent", "ANY"),
440        FxEventType::KeyEvent_KeyPressed => ("javafx.scene.input.KeyEvent", "KEY_PRESSED"),
441        FxEventType::KeyEvent_KeyReleased => ("javafx.scene.input.KeyEvent", "KEY_RELEASED"),
442        FxEventType::KeyEvent_KeyTyped => ("javafx.scene.input.KeyEvent", "KEY_TYPED"),
443        FxEventType::MouseDragEvent_Any => ("javafx.scene.input.MouseDragEvent", "ANY"),
444        FxEventType::MouseDragEvent_DragDetected => {
445            ("javafx.scene.input.MouseDragEvent", "DRAG_DETECTED")
446        }
447        FxEventType::MouseDragEvent_MouseClicked => {
448            ("javafx.scene.input.MouseDragEvent", "MOUSE_CLICKED")
449        }
450        FxEventType::MouseDragEvent_MouseDragEntered => {
451            ("javafx.scene.input.MouseDragEvent", "MOUSE_DRAG_ENTERED")
452        }
453        FxEventType::MouseDragEvent_MouseDragEnteredTarget => (
454            "javafx.scene.input.MouseDragEvent",
455            "MOUSE_DRAG_ENTERED_TARGET",
456        ),
457        FxEventType::MouseDragEvent_MouseDragExited => {
458            ("javafx.scene.input.MouseDragEvent", "MOUSE_DRAG_EXITED")
459        }
460        FxEventType::MouseDragEvent_MouseDragExitedTarget => (
461            "javafx.scene.input.MouseDragEvent",
462            "MOUSE_DRAG_EXITED_TARGET",
463        ),
464        FxEventType::MouseDragEvent_MouseDragged => {
465            ("javafx.scene.input.MouseDragEvent", "MOUSE_DRAGGED")
466        }
467        FxEventType::MouseDragEvent_MouseDragOver => {
468            ("javafx.scene.input.MouseDragEvent", "MOUSE_DRAG_OVER")
469        }
470        FxEventType::MouseDragEvent_MouseDragReleased => {
471            ("javafx.scene.input.MouseDragEvent", "MOUSE_DRAG_RELEASED")
472        }
473        FxEventType::MouseDragEvent_MouseEntered => {
474            ("javafx.scene.input.MouseDragEvent", "MOUSE_ENTERED")
475        }
476        FxEventType::MouseDragEvent_MouseEnteredTarget => {
477            ("javafx.scene.input.MouseDragEvent", "MOUSE_ENTERED_TARGET")
478        }
479        FxEventType::MouseDragEvent_MouseExited => {
480            ("javafx.scene.input.MouseDragEvent", "MOUSE_EXITED")
481        }
482        FxEventType::MouseDragEvent_MouseExitedTarget => {
483            ("javafx.scene.input.MouseDragEvent", "MOUSE_EXITED_TARGET")
484        }
485        FxEventType::MouseDragEvent_MouseMoved => {
486            ("javafx.scene.input.MouseDragEvent", "MOUSE_MOVED")
487        }
488        FxEventType::MouseDragEvent_MousePressed => {
489            ("javafx.scene.input.MouseDragEvent", "MOUSE_PRESSED")
490        }
491        FxEventType::MouseDragEvent_MouseReleased => {
492            ("javafx.scene.input.MouseDragEvent", "MOUSE_RELEASED")
493        }
494        FxEventType::MouseEvent_Any => ("javafx.scene.input.MouseEvent", "ANY"),
495        FxEventType::MouseEvent_DragDetected => ("javafx.scene.input.MouseEvent", "DRAG_DETECTED"),
496        FxEventType::MouseEvent_MouseClicked => ("javafx.scene.input.MouseEvent", "MOUSE_CLICKED"),
497        FxEventType::MouseEvent_MouseDragged => ("javafx.scene.input.MouseEvent", "MOUSE_DRAGGED"),
498        FxEventType::MouseEvent_MouseEntered => ("javafx.scene.input.MouseEvent", "MOUSE_ENTERED"),
499        FxEventType::MouseEvent_MouseEnteredTarget => {
500            ("javafx.scene.input.MouseEvent", "MOUSE_ENTERED_TARGET")
501        }
502        FxEventType::MouseEvent_MouseExited => ("javafx.scene.input.MouseEvent", "MOUSE_EXITED"),
503        FxEventType::MouseEvent_MouseExitedTarget => {
504            ("javafx.scene.input.MouseEvent", "MOUSE_EXITED_TARGET")
505        }
506        FxEventType::MouseEvent_MouseMoved => ("javafx.scene.input.MouseEvent", "MOUSE_MOVED"),
507        FxEventType::MouseEvent_MousePressed => ("javafx.scene.input.MouseEvent", "MOUSE_PRESSED"),
508        FxEventType::MouseEvent_MouseReleased => {
509            ("javafx.scene.input.MouseEvent", "MOUSE_RELEASED")
510        }
511        FxEventType::RotateEvent_Any => ("javafx.scene.input.RotateEvent", "ANY"),
512        FxEventType::RotateEvent_Rotate => ("javafx.scene.input.RotateEvent", "ROTATE"),
513        FxEventType::RotateEvent_RotationFinished => {
514            ("javafx.scene.input.RotateEvent", "ROTATION_FINISHED")
515        }
516        FxEventType::RotateEvent_RotationStarted => {
517            ("javafx.scene.input.RotateEvent", "ROTATION_STARTED")
518        }
519        FxEventType::ScrollEvent_Any => ("javafx.scene.input.ScrollEvent", "ANY"),
520        FxEventType::ScrollEvent_Scroll => ("javafx.scene.input.ScrollEvent", "SCROLL"),
521        FxEventType::ScrollEvent_ScrollFinished => {
522            ("javafx.scene.input.ScrollEvent", "SCROLL_FINISHED")
523        }
524        FxEventType::ScrollEvent_ScrollStarted => {
525            ("javafx.scene.input.ScrollEvent", "SCROLL_STARTED")
526        }
527        FxEventType::SwipeEvent_Any => ("javafx.scene.input.SwipeEvent", "ANY"),
528        FxEventType::SwipeEvent_SwipeDown => ("javafx.scene.input.SwipeEvent", "SWIPE_DOWN"),
529        FxEventType::SwipeEvent_SwipeLeft => ("javafx.scene.input.SwipeEvent", "SWIPE_LEFT"),
530        FxEventType::SwipeEvent_SwipeRight => ("javafx.scene.input.SwipeEvent", "SWIPE_RIGHT"),
531        FxEventType::SwipeEvent_SwipeUp => ("javafx.scene.input.SwipeEvent", "SWIPE_UP"),
532        FxEventType::TouchEvent_Any => ("javafx.scene.input.TouchEvent", "ANY"),
533        FxEventType::TouchEvent_TouchMoved => ("javafx.scene.input.TouchEvent", "TOUCH_MOVED"),
534        FxEventType::TouchEvent_TouchPressed => ("javafx.scene.input.TouchEvent", "TOUCH_PRESSED"),
535        FxEventType::TouchEvent_TouchReleased => {
536            ("javafx.scene.input.TouchEvent", "TOUCH_RELEASED")
537        }
538        FxEventType::TouchEvent_TouchStationary => {
539            ("javafx.scene.input.TouchEvent", "TOUCH_STATIONARY")
540        }
541        FxEventType::ZoomEvent_Any => ("javafx.scene.input.ZoomEvent", "ANY"),
542        FxEventType::ZoomEvent_Zoom => ("javafx.scene.input.ZoomEvent", "ZOOM"),
543        FxEventType::ZoomEvent_ZoomFinished => ("javafx.scene.input.ZoomEvent", "ZOOM_FINISHED"),
544        FxEventType::ZoomEvent_ZoomStarted => ("javafx.scene.input.ZoomEvent", "ZOOM_STARTED"),
545        FxEventType::MediaMediaErrorEvent_Any => ("javafx.scene.media.MediaErrorEvent", "ANY"),
546        FxEventType::MediaMediaErrorEvent_MediaError => {
547            ("javafx.scene.media.MediaErrorEvent", "MEDIA_ERROR")
548        }
549        FxEventType::MediaMediaMarkerEvent_Action => {
550            ("javafx.scene.media.MediaMarkerEvent", "ACTION")
551        }
552        FxEventType::MediaMediaMarkerEvent_Any => ("javafx.scene.media.MediaMarkerEvent", "ANY"),
553        FxEventType::TransformChangedEvent_Any => {
554            ("javafx.scene.transform.TransformChangedEvent", "ANY")
555        }
556        FxEventType::TransformChangedEvent_TransformChanged => (
557            "javafx.scene.transform.TransformChangedEvent",
558            "TRANSFORM_CHANGED",
559        ),
560        FxEventType::WindowEvent_Any => ("javafx.stage.WindowEvent", "ANY"),
561        FxEventType::WindowEvent_WindowCloseRequest => {
562            ("javafx.stage.WindowEvent", "WINDOW_CLOSE_REQUEST")
563        }
564        FxEventType::WindowEvent_WindowHidden => ("javafx.stage.WindowEvent", "WINDOW_HIDDEN"),
565        FxEventType::WindowEvent_WindowHiding => ("javafx.stage.WindowEvent", "WINDOW_HIDING"),
566        FxEventType::WindowEvent_WindowShowing => ("javafx.stage.WindowEvent", "WINDOW_SHOWING"),
567        FxEventType::WindowEvent_WindowShown => ("javafx.stage.WindowEvent", "WINDOW_SHOWN"),
568    };
569    (class.to_string(), field.to_string())
570}
571
572#[cfg(test)]
573mod api_unit_tests {
574    use super::*;
575    use crate::lib_unit_tests::create_tests_jvm;
576
577    #[test]
578    #[should_panic]
579    fn test_deploy_javafx_dependencies() {
580        let jvm: Jvm = create_tests_jvm().unwrap();
581        jvm.deploy_javafx_dependencies().unwrap();
582    }
583}