jrubyfx-openjfx.patch 1.2.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +202 -0
  3. data/README.md +121 -0
  4. data/bin/jrubyfx-compile +32 -0
  5. data/bin/jrubyfx-generator +98 -0
  6. data/bin/jrubyfx-jarify +115 -0
  7. data/lib/jrubyfx.rb +41 -0
  8. data/lib/jrubyfx/application.rb +42 -0
  9. data/lib/jrubyfx/compiler_app.rb +51 -0
  10. data/lib/jrubyfx/controller.rb +375 -0
  11. data/lib/jrubyfx/core_ext/border_pane.rb +30 -0
  12. data/lib/jrubyfx/core_ext/column_constraints.rb +43 -0
  13. data/lib/jrubyfx/core_ext/drag_event.rb +32 -0
  14. data/lib/jrubyfx/core_ext/duration.rb +30 -0
  15. data/lib/jrubyfx/core_ext/effects.rb +32 -0
  16. data/lib/jrubyfx/core_ext/exts.yml +57 -0
  17. data/lib/jrubyfx/core_ext/file_chooser.rb +63 -0
  18. data/lib/jrubyfx/core_ext/geometry.rb +27 -0
  19. data/lib/jrubyfx/core_ext/grid_pane.rb +30 -0
  20. data/lib/jrubyfx/core_ext/image_view.rb +25 -0
  21. data/lib/jrubyfx/core_ext/media_player.rb +25 -0
  22. data/lib/jrubyfx/core_ext/observable_value.rb +158 -0
  23. data/lib/jrubyfx/core_ext/pagination.rb +28 -0
  24. data/lib/jrubyfx/core_ext/path.rb +37 -0
  25. data/lib/jrubyfx/core_ext/precompiled.rb +1883 -0
  26. data/lib/jrubyfx/core_ext/progress_indicator.rb +41 -0
  27. data/lib/jrubyfx/core_ext/radial_gradient.rb +37 -0
  28. data/lib/jrubyfx/core_ext/region.rb +42 -0
  29. data/lib/jrubyfx/core_ext/rotate.rb +39 -0
  30. data/lib/jrubyfx/core_ext/stage.rb +89 -0
  31. data/lib/jrubyfx/core_ext/table_view.rb +31 -0
  32. data/lib/jrubyfx/core_ext/timeline.rb +56 -0
  33. data/lib/jrubyfx/core_ext/transition.rb +26 -0
  34. data/lib/jrubyfx/core_ext/tree_view.rb +40 -0
  35. data/lib/jrubyfx/core_ext/xy_chart.rb +53 -0
  36. data/lib/jrubyfx/dsl.rb +330 -0
  37. data/lib/jrubyfx/dsl_control.rb +28 -0
  38. data/lib/jrubyfx/dsl_map.rb +273 -0
  39. data/lib/jrubyfx/imports.rb +324 -0
  40. data/lib/jrubyfx/java_fx_impl.rb +144 -0
  41. data/lib/jrubyfx/module.rb +178 -0
  42. data/lib/jrubyfx/part_imports.rb +141 -0
  43. data/lib/jrubyfx/utils.rb +86 -0
  44. data/lib/jrubyfx/utils/__ignore_java_stupid_rdoc.rb +30 -0
  45. data/lib/jrubyfx/utils/common_converters.rb +223 -0
  46. data/lib/jrubyfx/utils/common_utils.rb +72 -0
  47. data/lib/jrubyfx/utils/string_utils.rb +48 -0
  48. data/lib/jrubyfx/version.rb +4 -0
  49. data/lib/jrubyfx_tasks.rb +183 -0
  50. metadata +145 -0
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env jruby
2
+ =begin
3
+ JRubyFX - Write JavaFX and FXML in Ruby
4
+ Copyright (C) 2013 The JRubyFX Team
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ require 'jrubyfx_tasks'
20
+
21
+ def usage
22
+ puts "#{$0} {options} project-folder [output.jar]"
23
+ puts <<THEOPTIONS
24
+ project-folder should contain rb files and supporting files
25
+
26
+ -m|--main FILE ruby script to launch when the jar is executed.
27
+ Defaults to jar-bootstrap.rb or main.rb
28
+ -j|--include-jars Include jars in the jar. (off by default to prevent including
29
+ the jar you are building)
30
+ --native Create native application packages and installers. (Requires JDK8)
31
+ -v|--verbose Turns on the native packagers verbose mode. Useful for
32
+ customizing icons, licenses, etc.
33
+ --name STRING Name for your native package.
34
+ THEOPTIONS
35
+ exit -1
36
+ end
37
+
38
+ if ARGV.length < 1
39
+ usage
40
+ end
41
+
42
+ main = ["jar-bootstrap.rb", "main.rb"]
43
+ include_jars = false
44
+ native_bundle = false
45
+ app_name = ""
46
+ verbose = false
47
+ nargs = []
48
+ default_on_next = on_next = ->(arg){true}
49
+
50
+ # split the args manually
51
+ ARGV.each do |arg|
52
+ # some args have multiple parts. this is a cheap way to do that (lambdas)
53
+ next unless on_next.call(arg)
54
+ case arg
55
+ when "-m", "--main"
56
+ on_next = ->(arg){
57
+ main = [arg]
58
+ on_next = default_on_next
59
+ false
60
+ }
61
+ next
62
+ when "-j", "--include-jars"
63
+ include_jars = true
64
+ next
65
+ when "--native"
66
+ native_bundle = true
67
+ next
68
+ when "--name"
69
+ on_next = ->(arg){
70
+ app_name = [arg]
71
+ on_next = default_on_next
72
+ false
73
+ }
74
+ next
75
+ when "-v", "--verbose"
76
+ verbose = true
77
+ when "-h", "--help"
78
+ usage
79
+ exit 0
80
+ when /^-/
81
+ puts "ERROR! Unrecognized option '#{arg}'!"
82
+ exit -2
83
+ end
84
+ # no flag? must be positional arg
85
+ nargs << arg
86
+ end
87
+ # set jar default if none passed in
88
+ if nargs.length <= 1
89
+ nargs << File.basename(nargs[0]) + ".jar"
90
+ end
91
+ # set positional args
92
+ project_folder, output_jar = nargs
93
+
94
+ # Download the current running JRuby version
95
+ JRubyFX::Tasks::download_jruby(JRUBY_VERSION)
96
+
97
+ # set the main script to the first (must be passed in), or tries to find
98
+ # a file that does exists. Silently fails if it fails.
99
+ main_script = main[0]
100
+ if main.length > 1
101
+ main.each do |scrpt|
102
+ ps = project_folder + "/" + scrpt
103
+ if File.exists? ps
104
+ main_script = ps
105
+ break
106
+ end
107
+ end
108
+ end
109
+
110
+ # Jarify!
111
+ JRubyFX::Tasks::jarify_jrubyfx(project_folder + "/*", main_script, nil, output_jar, :file_filter => ->(filename){!filename.end_with?(".jar") or include_jars})
112
+
113
+ if native_bundle
114
+ JRubyFX::Tasks::native_bundles(Dir.pwd, output_jar, verbose, app_name[0])
115
+ end
@@ -0,0 +1,41 @@
1
+ =begin
2
+ JRubyFX - Write JavaFX and FXML in Ruby
3
+ Copyright (C) 2013 The JRubyFX Team
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ =end
17
+
18
+ if RUBY_VERSION.include? "1.8" or !JRUBY_VERSION
19
+ puts "JRubyFX requires JRuby to be in 1.9 mode"
20
+ exit -2
21
+ end
22
+ if Gem::Version.new(JRUBY_VERSION) < Gem::Version.new("1.7.4")
23
+ puts "Warning: JRuby 1.7.3 and prior have bugs that can cause strange errors. Do not submit any bug reports. Please use JRuby 1.7.4 or later."
24
+ end
25
+
26
+ require 'java' # for java_import
27
+ require 'jruby/core_ext' # for the become_java!
28
+
29
+ unless File.size? "#{File.dirname(__FILE__)}/jrubyfx/imports.rb"
30
+ puts "Please run `rake reflect` to generate the imports"
31
+ exit -1
32
+ end
33
+ # JRubyFX includes
34
+ require_relative 'jrubyfx/imports'
35
+ require_relative 'jrubyfx/module'
36
+ require_relative 'jrubyfx/dsl'
37
+ require_relative 'jrubyfx/dsl_control'
38
+ JRubyFX::DSL.load_dsl # load it after we require the dsl package to not loop around
39
+ require_relative 'jrubyfx/application'
40
+ require_relative 'jrubyfx/controller'
41
+ require_relative 'jrubyfx/java_fx_impl'
@@ -0,0 +1,42 @@
1
+ =begin
2
+ JRubyFX - Write JavaFX and FXML in Ruby
3
+ Copyright (C) 2013 The JRubyFX Team
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ =end
17
+
18
+ ##
19
+ # Inherit from this class for FXML Applications. You must use this class for both
20
+ # raw JavaFX and FXML as it contains the launch method.
21
+ class JRubyFX::Application < Java.javafx.application.Application
22
+ include JRubyFX
23
+ include JRubyFX::DSL
24
+
25
+ ##
26
+ # Are we packaged in a jar? This does some comparison, and may get false positives
27
+ # and, if jruby changes, false negatives. If you are using this, it might be a
28
+ # very bad idea... (though it is handy)
29
+ def self.in_jar?()
30
+ $LOAD_PATH.inject(false) { |res,i| res || i.include?("/META-INF/jruby.home/lib/ruby/")}
31
+ end
32
+
33
+ ##
34
+ # call-seq:
35
+ # launch()
36
+ #
37
+ # When called on a subclass, this is effectively our main method.
38
+ def self.launch(*args)
39
+ #call our custom launcher to avoid a java shim
40
+ JavaFXImpl::Launcher.launch_app(self, *args)
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ =begin
2
+ JRubyFX - Write JavaFX and FXML in Ruby
3
+ Copyright (C) 2013 The JRubyFX Team
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ =end
17
+ require 'jrubyfx'
18
+
19
+ # This class is used by the rake task to compile fxml files
20
+ class CompilerApp < JRubyFX::Application
21
+ def start(stage)
22
+ begin
23
+ args = parameters.raw.to_a
24
+ if args.include? "--"
25
+ ar, requires = split(args, "--")
26
+ requires.each {|x| require x}
27
+ ar
28
+ else
29
+ args
30
+ end.each do |arg|
31
+ loader = FxmlLoader.new
32
+ loader.location = URL.new "file:#{arg}"
33
+ loader.controller = Object.new
34
+ puts "Compiling #{arg}..."
35
+ loader.load(jruby_ext: {jit: 0, dont_load: true, jit_opts: {force: true}})
36
+ end
37
+ puts "done"
38
+ rescue java.lang.Throwable, Exception => e
39
+ $JRUBYFX_AOT_ERROR = e
40
+ ensure
41
+ Platform.exit
42
+ end
43
+ end
44
+
45
+ def split(arr, delim)
46
+ index = arr.index(delim)
47
+ first = arr[0...index]
48
+ second = arr[(index+1)..-1]
49
+ return first, second
50
+ end
51
+ end
@@ -0,0 +1,375 @@
1
+ =begin
2
+ JRubyFX - Write JavaFX and FXML in Ruby
3
+ Copyright (C) 2013 The JRubyFX Team
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ =end
17
+
18
+ require 'jrubyfx/utils/string_utils'
19
+ # If fxmlloader is installed, require it here
20
+ begin
21
+ require 'jrubyfx-fxmlloader'
22
+ rescue LoadError
23
+ # no fxmlloader, ignore it
24
+ end
25
+
26
+ # Special methods for fxml loading
27
+ module Kernel
28
+ @@jrubyfx_res_dir = {}
29
+ @@jrubyfx_fxml_res_cl = nil
30
+ def fxml_root(value=nil, jar_value=nil, class_loader = nil)
31
+ @@jrubyfx_fxml_res_cl = class_loader if class_loader
32
+ if value or jar_value
33
+ @@jrubyfx_fxml_dir = (JRubyFX::Application.in_jar? and jar_value) ? jar_value : File.expand_path(value)
34
+ else
35
+ @@jrubyfx_fxml_dir
36
+ end
37
+ end
38
+ def resource_root(res_name, value=nil, jar_value=nil)
39
+ if value or jar_value
40
+ @@jrubyfx_res_dir[res_name.to_sym] = (JRubyFX::Application.in_jar? and jar_value) ? jar_value : File.expand_path(value)
41
+ else
42
+ @@jrubyfx_res_dir[res_name.to_sym]
43
+ end
44
+ end
45
+ def get_fxml_resource_class_loader
46
+ @@jrubyfx_fxml_res_cl || JRuby.runtime.jruby_class_loader.method("get_resource")
47
+ end
48
+ def resource_url(type, relative_path)
49
+ if JRubyFX::Application.in_jar?
50
+ get_fxml_resource_class_loader.call("#{resource_root(type)}/#{relative_path}")
51
+ else
52
+ java.net.URL.new("file:" + File.join(resource_root(type), relative_path))
53
+ end
54
+ end
55
+ end
56
+
57
+ # Inherit from this class for FXML controllers
58
+ module JRubyFX::Controller
59
+ include JRubyFX::DSL
60
+ include JRubyFX::FXImports
61
+
62
+ java_import 'java.net.URL'
63
+
64
+ DEFAULT_SETTINGS = {
65
+ width: -1,
66
+ height: -1,
67
+ fill: :white,
68
+ depth_buffer: false,
69
+ root_dir: nil,
70
+ initialized: nil
71
+ }
72
+
73
+ # Controllers usually need access to the stage.
74
+ attr_writer :stage, :scene
75
+
76
+ def self.included(base)
77
+ base.extend(ClassMethods)
78
+ base.extend(JRubyFX::FXMLClassUtils) if defined? JRubyFX::FXMLClassUtils
79
+ base.extend(JRubyFX::FXImports)
80
+ # register ourselves as a control. overridable with custom_fxml_control
81
+ register_type base if base.is_a? Class
82
+ end
83
+
84
+ # class methods for FXML controllers
85
+ module ClassMethods
86
+ include JRubyFX::DSL
87
+
88
+ #nested including, TODO: don't duplicate this
89
+ def included(base)
90
+ base.extend(JRubyFX::Controller::ClassMethods)
91
+ # register ourselves as a control. overridable with custom_fxml_control
92
+ JRubyFX::DSL::ClassUtils.register_type base if base.is_a? Class
93
+ end
94
+
95
+ # Load given fxml file onto the given stage. `settings` is an optional hash of:
96
+ # * :initialize => [array of arguments to pass to the initialize function]
97
+ # * :width => Default width of the Scene
98
+ # * :height => Default height of the Scene
99
+ # * :fill => Fill color of the Scene's background
100
+ # * :depth_buffer => JavaFX Scene DepthBuffer argument (look it up)
101
+ # * :root_dir => filename search for fxml realtive to this file
102
+ #
103
+ # === Examples
104
+ #
105
+ # controller = MyFXController.new "Demo.fxml", stage
106
+ #
107
+ # === Equivalent Java
108
+ # Parent root = FXMLLoader.load(getClass().getResource("Demo.fxml"));
109
+ # Scene scene = new Scene(root);
110
+ # stage.setScene(scene);
111
+ # controller = root.getController();
112
+
113
+ def load_into(stage, settings={})
114
+ # Inherit from default settings
115
+ settings = DEFAULT_SETTINGS.merge({root_dir: (self.instance_variable_get("@fxml_root_dir") || fxml_root),
116
+ class_loader: (get_fxml_resource_class_loader),
117
+ filename: self.instance_variable_get("@filename")}).merge settings
118
+
119
+ # Custom controls don't always need to be pure java, but oh well...
120
+ become_java!
121
+
122
+ # like new, without initialize
123
+ ctrl = allocate
124
+
125
+ # Set the stage so we can reference it if needed later
126
+ ctrl.stage = stage
127
+
128
+ # load the FXML file
129
+ root = Controller.get_fxml_loader(settings[:filename], ctrl, settings[:root_dir], settings[:class_loader]).load
130
+
131
+ # Unless the FXML root node is a scene, wrap that node in a scene
132
+ if root.is_a? Scene
133
+ scene = root
134
+ else
135
+ scene = Scene.new root, settings[:width], settings[:height], settings[:depth_buffer]
136
+ scene.fill = settings[:fill]
137
+ end
138
+
139
+ # set the controller and stage scene
140
+ ctrl.scene = stage.scene = scene
141
+
142
+ ctrl.finish_initialization *settings[:initialize].to_a
143
+ end
144
+
145
+ # This is the default override for custom controls
146
+ # Normal FXML controllers will use Control#new
147
+ def new(*args, &block)
148
+ if @preparsed && @preparsed.length > 0
149
+ return @preparsed.pop.finish_initialization(*args, &block)
150
+ end
151
+ # Custom controls don't always need to be pure java, but oh well...
152
+ become_java! if @filename
153
+
154
+ # like new, without initialize
155
+ ctrl = allocate
156
+
157
+ ctrl.initialize_controller(DEFAULT_SETTINGS.merge({root_dir: @fxml_root_dir || fxml_root,
158
+ filename: @filename}),
159
+ *args, &block) if @filename
160
+
161
+ # return the controller
162
+ ctrl
163
+ end
164
+
165
+ def preparse_new(num=3)
166
+ become_java! if @filename
167
+ @preparsed ||= []
168
+ num.times do
169
+ ctrl = allocate
170
+ ctrl.pre_initialize_controller(DEFAULT_SETTINGS.merge({root_dir: @fxml_root_dir || fxml_root,
171
+ filename: @filename})) if @filename
172
+ @preparsed << ctrl
173
+ end
174
+ end
175
+
176
+ #decorator to force becoming java class
177
+ def become_java
178
+ @force_java = true
179
+ end
180
+
181
+ # Set the filename of the fxml this control is part of
182
+ def fxml(fxml=nil, name = nil, root_dir = nil)
183
+ @filename = fxml
184
+ # snag the filename from the caller
185
+ @fxml_root_dir = root_dir
186
+ register_type(self, name) if name
187
+ end
188
+
189
+ ##
190
+ # Event Handlers
191
+ ##
192
+
193
+ ##
194
+ # call-seq:
195
+ # on(callback, ...) { |event_info| block } => Method
196
+ #
197
+ # Registers a function of name `name` for a FXML defined event with the body in the block.
198
+ # Note you can also just use normal methods
199
+ #
200
+ # === Examples
201
+ # on :click do
202
+ # puts "button clicked"
203
+ # end
204
+ #
205
+ # on :moved, :pressed do |event|
206
+ # puts "Mouse Moved or Key Pressed"
207
+ # p event
208
+ # end
209
+ #
210
+ # === Equivalent Java
211
+ # @FXML
212
+ # private void click(ActionEvent event) {
213
+ # System.out.println("button clicked");
214
+ # }
215
+ #
216
+ # @FXML
217
+ # private void moved(MouseEvent event) {
218
+ # System.out.println("Mouse Moved or Key Pressed");
219
+ # }
220
+ #
221
+ # @FXML
222
+ # private void keypress(KeyEvent event) {
223
+ # System.out.println("Key Pressed or Key Pressed");
224
+ # }
225
+ #
226
+ def on(names, &block)
227
+ [names].flatten.each do |name|
228
+ class_eval do
229
+ # must define this way so block executes in class scope, not static scope
230
+ define_method name, block
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ #default java ctor, override for arguments
237
+ def java_ctor(ctor, initialize_arguments)
238
+ ctor.call
239
+ end
240
+
241
+ # Initialize all controllers
242
+ def initialize_controller(options={}, *args, &block)
243
+
244
+ # JRuby complains loudly (probably broken behavior) if we don't call the ctor
245
+ java_ctor self.class.superclass.instance_method(:initialize).bind(self), args
246
+
247
+ # load the FXML file with the current control as the root
248
+ load_fxml options[:filename], options[:root_dir]
249
+
250
+ finish_initialization *args, &block
251
+ end
252
+
253
+ # Initialize all controllers
254
+ def pre_initialize_controller(options={})
255
+
256
+ # JRuby complains loudly (probably broken behavior) if we don't call the ctor
257
+ java_ctor self.class.superclass.instance_method(:initialize).bind(self), [] #TODO: do we need to call this now with []?
258
+
259
+ # load the FXML file with the current control as the root
260
+ load_fxml options[:filename], options[:root_dir]
261
+ end
262
+
263
+ def load_fxml(filename, root_dir=nil)
264
+ fx = Controller.get_fxml_loader(filename, self, root_dir || @fxml_root_dir || fxml_root, get_fxml_resource_class_loader)
265
+ fx.root = self
266
+ fx.load
267
+ end
268
+
269
+ def finish_initialization(*args, &block)
270
+ @nodes_by_id = {}
271
+
272
+ # custom controls are their own scene
273
+ self.scene = self unless @scene
274
+
275
+ # Everything is ready, call initialize
276
+ if private_methods.include? :initialize
277
+ self.send :initialize, *args, &block
278
+ end
279
+
280
+ #return ourself
281
+ self
282
+ end
283
+
284
+ ##
285
+ # Node Lookup Methods
286
+ ##
287
+
288
+ # return first matched node or nil
289
+ def find(css_selector)
290
+ @scene.lookup(css_selector)
291
+ end
292
+
293
+ # Return first matched node or throw exception
294
+ def find!(css_selector)
295
+ res = find(css_selector)
296
+ raise "Selector(#{css_selector}) returned no results!" unless res
297
+ res
298
+ end
299
+
300
+ # return an array of matched nodes
301
+ def css(css_selector)
302
+ @scene.get_root.lookup_all(css_selector).to_a
303
+ end
304
+
305
+ # Loads a controller-less file
306
+ def self.load_fxml_only(filename, stage, settings={})
307
+ # Inherit from default settings
308
+ settings = DEFAULT_SETTINGS.merge({root_dir: fxml_root,
309
+ class_loader: get_fxml_resource_class_loader,
310
+ filename: filename}).merge settings
311
+
312
+ # load the FXML file
313
+ root = Controller.get_fxml_loader(settings[:filename], nil, settings[:root_dir], settings[:class_loader]).load
314
+
315
+ # TODO: de-duplicate this code
316
+
317
+ # Unless the FXML root node is a scene, wrap that node in a scene
318
+ if root.is_a? Scene
319
+ scene = root
320
+ else
321
+ scene = Scene.new root, settings[:width], settings[:height], settings[:depth_buffer]
322
+ scene.fill = settings[:fill]
323
+ end
324
+
325
+ # set the controller and stage scene
326
+ stage.scene = scene
327
+ end
328
+
329
+
330
+ ##
331
+ # call-seq:
332
+ # get_fxml_loader(filename) => FXMLLoader
333
+ # get_fxml_loader(filename, controller_instance) => FXMLLoader
334
+ # get_fxml_loader(filename, controller_instance, root_dir) => FXMLLoader
335
+ #
336
+ # Load a FXML file given a filename and a controller and return the loader
337
+ # root_dir is a directory that the file is relative to.
338
+ # === Examples
339
+ # root = JRubyFX::Controller.get_fxml_loader("Demo.fxml").load
340
+ #
341
+ # root = JRubyFX::Controller.get_fxml_loader("Demo.fxml", my_controller).load
342
+ #
343
+ # === Equivalent Java
344
+ # Parent root = FXMLLoader.load(getClass().getResource("Demo.fxml"));
345
+ #
346
+ def self.get_fxml_loader(filename, controller = nil, root_dir = nil, class_loader = JRuby.runtime.jruby_class_loader.method("get_resource"))
347
+ fx = FxmlLoader.new
348
+ fx.location = get_fxml_location(root_dir, filename, class_loader)
349
+ # we must set this here for JFX to call our events
350
+ fx.controller = controller
351
+ fx
352
+ end
353
+
354
+ def self.get_fxml_location(root_dir, filename, class_loader)
355
+ if JRubyFX::Application.in_jar? and filename.match(/^[^.\/]/)
356
+ # If we are in a jar file, use the class loader to get the file from the jar (like java)
357
+ # TODO: should just be able to use URLs
358
+
359
+ # According to how class loader works, the correct path for a file inside a jar is NOT "/folder/file.fxml"
360
+ # but "folder/file.fxml" (without starting "/" or ".", which would both make the path to be seen as a filesystem
361
+ # reference) so we assume that if root_dir is set to "" or to any other path not starting with "." or "/" then
362
+ # we want to point to a folder inside the jar, otherwise to a filesystem's one. According to this we format and
363
+ # feed the right path to the class loader.
364
+
365
+ location = class_loader.call(File.join(root_dir, filename))
366
+
367
+ # fall back if not found
368
+ return location if location
369
+ end
370
+
371
+ root_dir ||= fxml_root
372
+ # If we are in the normal filesystem, create a file url path relative to relative_to or this file
373
+ URL.new "file:#{File.join root_dir, filename}"
374
+ end
375
+ end