jrubyfx 1.1.0-java → 2.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2663b39ced8255fd70b6666efcf58ad87133d4a385f5f01dc8fd6d9797ebf298
4
+ data.tar.gz: ec875fdd53ca592f9023004b83595d902d8dd74a680a2b3830df71a744369b4c
5
+ SHA512:
6
+ metadata.gz: dee292568c4247cff866bccffab39a1f2ee1928c95c776649540a459a3edb5f3d4b90ae49a17b50906f38e96a24f4ca0d0ecf3235d3d6c1ce702c606fefb2170
7
+ data.tar.gz: f3e259057d479843db42ed9e9582a2e3acbd64fa214221a639dbc6d965fa86f456e3e4b96e0e734971a1c4989829d335600457ec9be61b7dd373675535d61c6b
data/README.md CHANGED
@@ -1,24 +1,34 @@
1
1
  JRubyFX
2
2
  =======
3
- JRubyFX is a pure ruby wrapper for JavaFX 2.2+ with FXML support
3
+ JRubyFX is a pure ruby wrapper for JavaFX 2.2+ with FXML support. Currently supported: Java 8+, JRuby 9.3+.
4
4
 
5
5
  Status
6
6
  ------
7
- JRubyFX master should be usable in its current form and able to run simple FXML apps if used properly (see Issues).
8
- FXML syntax in master/1.0 is very different from 0.9 series. Please see the [JRubyFX github wiki](https://github.com/jruby/jrubyfx/wiki/) for more details.
7
+ JRubyFX master should be usable in its current form and able to run most FXML apps.
8
+ As of JRubyFX 2.0, the Java FXML Loader is used. This requires JRuby 9.3+.
9
+ Please see the [JRubyFX github wiki](https://github.com/jruby/jrubyfx/wiki/) for upgrading from 1.x.
9
10
 
10
11
  Install
11
12
  -----
13
+
14
+ For JRuby 9.3.4+:
15
+
12
16
  ```text
13
17
  gem install jrubyfx
14
18
  ```
19
+ For older JRuby versions:
20
+
21
+ ```text
22
+ gem install jrubyfx -v 1.2
23
+ ```
24
+
25
+ If you are using Java 9+, additionally append the contents of `module-opens.txt` to `bin/.jruby.java_opts` in your jruby install. If you fail to do this, you may get inscruitable "method X not found, did you mean X?" errors.
15
26
 
16
27
  Manual Build and Install
17
28
  -----
18
- Build is done using rake/gem/bundler/rdoc. You need JRuby >1.7.4 (in 1.9 mode), Java >1.6 with JavaFX 2.2, but Java 7 is recommended. Building native application packages requires JDK 8.
29
+ Build is done using rake/gem/bundler/rdoc. You need JRuby >= 9.3.4.0, Java >= 8 with JavaFX 11 modules installed (only required for `reflect` task). Building native application packages requires JDK 8+.
19
30
 
20
31
  ```text
21
- gem install jrubyfx-fxmlloader
22
32
  rake install
23
33
  ```
24
34
  Once the gem is installed, just run a ruby file that uses it normally.
@@ -26,7 +36,11 @@ Once the gem is installed, just run a ruby file that uses it normally.
26
36
  **NOTE:** If you don't have JRuby installed as the `ruby` command, use `jruby -S rake` instead of `rake`. If
27
37
  you are using RVM, this does not apply to you (though make sure you `rvm use jruby`).
28
38
 
29
- **If you are reporting bugs or encountering fxml issues:** please install [master jrubyfx-fxmlloader](https://github.com/byteit101/JRubyFX-FXMLLoader/) instead of from rubygems
39
+ **If you are reporting bugs or encountering fxml issues:** please ensure you are using JRubyFX 2.0. Prior version relied on a ported fxml parser and had many known issues.
40
+
41
+ Updating the Imports
42
+ --------------
43
+ JRubyFX currently uses the 11-based classes for the default imports (part_imports.rb). In the future, this list may change. See `gen_tree.rb` for a script to help automate finding the classes to import.
30
44
 
31
45
  Creating a Jar
32
46
  --------------
@@ -94,16 +108,13 @@ If you want rdoc, run `rake rdoc`. Please note that there are lots of generated
94
108
 
95
109
  Issues
96
110
  ------
97
- * Use JRubyFX-FxmlLoader's FxmlLoader instead of javafx.fxml.FXMLLoader for maximum Ruby support.
98
- * FXML support in master for very complex documents is untested. Report bugs against JRubyFX-FxmlLoader with the FXML file if it fails.
99
- * You must use the provided JavaFXImpl::Launcher to launch the app (aka: call _yourFXApplicationClass_.launch())
100
111
  * Errors loading JavaFX are bugs. Please report if you encounter this issue, tell us your platform, OS, and version of JRuby
101
112
  * Jarify command needs the `jar` executable in your path.
102
113
  * Any other difficulties are bugs. Please report them
103
114
 
104
115
  Contact
105
116
  -------
106
- Find us in #jruby on freenode.
117
+ Find us in #jruby on matrix.
107
118
 
108
119
  License
109
120
  -------
@@ -27,7 +27,7 @@ class JRubyFX::Application < Java.javafx.application.Application
27
27
  # and, if jruby changes, false negatives. If you are using this, it might be a
28
28
  # very bad idea... (though it is handy)
29
29
  def self.in_jar?()
30
- $LOAD_PATH.inject(false) { |res,i| res || i.include?(".jar!/META-INF/jruby.home/lib/ruby/")}
30
+ $LOAD_PATH.inject(false) { |res,i| res || i.include?("/META-INF/jruby.home/lib/ruby/")}
31
31
  end
32
32
 
33
33
  ##
@@ -36,7 +36,7 @@ class JRubyFX::Application < Java.javafx.application.Application
36
36
  #
37
37
  # When called on a subclass, this is effectively our main method.
38
38
  def self.launch(*args)
39
- #call our custom launcher to avoid a java shim
40
- JavaFXImpl::Launcher.launch_app(self, *args)
39
+ # Note: object args are no longer allowed
40
+ Java.javafx.application.Application.launch(self.become_java!, args.map(&:to_s).to_java(:string))
41
41
  end
42
42
  end
@@ -35,6 +35,8 @@ class CompilerApp < JRubyFX::Application
35
35
  loader.load(jruby_ext: {jit: 0, dont_load: true, jit_opts: {force: true}})
36
36
  end
37
37
  puts "done"
38
+ rescue java.lang.Throwable, Exception => e
39
+ $JRUBYFX_AOT_ERROR = e
38
40
  ensure
39
41
  Platform.exit
40
42
  end
@@ -15,28 +15,39 @@ See the License for the specific language governing permissions and
15
15
  limitations under the License.
16
16
  =end
17
17
 
18
- require 'jrubyfx-fxmlloader'
18
+ require 'jrubyfx/utils/string_utils'
19
+ require 'jrubyfx/fxml_helper'
20
+ require 'jruby/core_ext'
19
21
 
20
22
  # Special methods for fxml loading
21
23
  module Kernel
22
24
  @@jrubyfx_res_dir = {}
23
- def fxml_root(value=nil, jar_value=nil)
25
+ @@jrubyfx_fxml_res_cl = nil
26
+ def fxml_root(value=nil, jar_value=nil, get_resources: nil, fxml_class_loader: nil)
27
+ @@jrubyfx_fxml_res_cl = get_resources if get_resources
28
+ @@jrubyfx_fxml_main_cl = fxml_class_loader if fxml_class_loader
24
29
  if value or jar_value
25
- @@jrubyfx_fxml_dir = JRubyFX::Application.in_jar? ? jar_value : File.expand_path(value)
30
+ @@jrubyfx_fxml_dir = (JRubyFX::Application.in_jar? and jar_value) ? jar_value : File.expand_path(value)
26
31
  else
27
32
  @@jrubyfx_fxml_dir
28
33
  end
29
34
  end
30
35
  def resource_root(res_name, value=nil, jar_value=nil)
31
36
  if value or jar_value
32
- @@jrubyfx_res_dir[res_name.to_sym] = JRubyFX::Application.in_jar? ? jar_value : File.expand_path(value)
37
+ @@jrubyfx_res_dir[res_name.to_sym] = (JRubyFX::Application.in_jar? and jar_value) ? jar_value : File.expand_path(value)
33
38
  else
34
39
  @@jrubyfx_res_dir[res_name.to_sym]
35
40
  end
36
41
  end
42
+ def get_fxml_resource_class_loader
43
+ @@jrubyfx_fxml_res_cl || JRuby.runtime.jruby_class_loader.method("get_resource")
44
+ end
45
+ def get_fxml_classes_class_loader
46
+ @@jrubyfx_fxml_main_cl ||= JRubyFX::PolyglotClassLoader.new
47
+ end
37
48
  def resource_url(type, relative_path)
38
49
  if JRubyFX::Application.in_jar?
39
- JRuby.runtime.jruby_class_loader.get_resource("#{resource_root(type)}/#{relative_path}");
50
+ get_fxml_resource_class_loader.call("#{resource_root(type)}/#{relative_path}")
40
51
  else
41
52
  java.net.URL.new("file:" + File.join(resource_root(type), relative_path))
42
53
  end
@@ -64,8 +75,12 @@ module JRubyFX::Controller
64
75
 
65
76
  def self.included(base)
66
77
  base.extend(ClassMethods)
67
- base.extend(JRubyFX::FXMLClassUtils)
78
+ base.extend(JRubyFX::FXMLClassUtils) if defined? JRubyFX::FXMLClassUtils
68
79
  base.extend(JRubyFX::FXImports)
80
+ base.configure_java_class ctor_name: "java_ctor" do
81
+ dispatch :initialize, :fx_initialize # we want to load our code before calling user code
82
+ # un-exclude "initialize"
83
+ end
69
84
  # register ourselves as a control. overridable with custom_fxml_control
70
85
  register_type base if base.is_a? Class
71
86
  end
@@ -102,10 +117,20 @@ module JRubyFX::Controller
102
117
  def load_into(stage, settings={})
103
118
  # Inherit from default settings
104
119
  settings = DEFAULT_SETTINGS.merge({root_dir: (self.instance_variable_get("@fxml_root_dir") || fxml_root),
120
+ get_resources: get_fxml_resource_class_loader,
121
+ fxml_class_loader: get_fxml_classes_class_loader,
105
122
  filename: self.instance_variable_get("@filename")}).merge settings
106
-
107
- # Custom controls don't always need to be pure java, but oh well...
108
- become_java!
123
+
124
+ raise "JRubyFX 1.x style class loader argument passed into 'load_into'. Replace 'class_loader' with either 'get_resources' (likely) or 'fxml_class_loader' (less likely)" if settings.has_key? :class_loader
125
+
126
+ unless @built
127
+ ## Use the temporary loader to reformat AController
128
+ JRubyFX::FxmlHelper.transform self, Controller.get_fxml_location(settings[:root_dir], settings[:filename], settings[:get_resources])
129
+
130
+ # Custom controls don't always need to be pure java, but oh well...
131
+ become_java!
132
+ @built = true
133
+ end
109
134
 
110
135
  # like new, without initialize
111
136
  ctrl = allocate
@@ -114,7 +139,7 @@ module JRubyFX::Controller
114
139
  ctrl.stage = stage
115
140
 
116
141
  # load the FXML file
117
- root = Controller.get_fxml_loader(settings[:filename], ctrl, settings[:root_dir]).load
142
+ root = Controller.get_fxml_loader(settings[:filename], ctrl, settings[:root_dir], settings[:get_resources], settings[:fxml_class_loader]).load
118
143
 
119
144
  # Unless the FXML root node is a scene, wrap that node in a scene
120
145
  if root.is_a? Scene
@@ -136,14 +161,24 @@ module JRubyFX::Controller
136
161
  if @preparsed && @preparsed.length > 0
137
162
  return @preparsed.pop.finish_initialization(*args, &block)
138
163
  end
164
+
165
+ settings = DEFAULT_SETTINGS.merge({root_dir: @fxml_root_dir || fxml_root, get_resources: get_fxml_resource_class_loader,
166
+ fxml_class_loader: get_fxml_classes_class_loader, filename: @filename})
167
+
139
168
  # Custom controls don't always need to be pure java, but oh well...
140
- become_java! if @filename
169
+ if @filename && !@built
170
+ @built = true # TODO: move later if no new :bake call
171
+ ## Use the temporary loader to reformat AController
172
+ JRubyFX::FxmlHelper.transform self, Controller.get_fxml_location(settings[:root_dir], settings[:filename], settings[:get_resources])
173
+
174
+ # Custom controls don't always need to be pure java, but oh well...
175
+ become_java!
176
+ end
141
177
 
142
178
  # like new, without initialize
143
179
  ctrl = allocate
144
180
 
145
- ctrl.initialize_controller(DEFAULT_SETTINGS.merge({root_dir: @fxml_root_dir || fxml_root,
146
- filename: @filename}),
181
+ ctrl.initialize_controller(settings,
147
182
  *args, &block) if @filename
148
183
 
149
184
  # return the controller
@@ -220,17 +255,22 @@ module JRubyFX::Controller
220
255
  end
221
256
  end
222
257
  end
258
+
259
+ # java initialize is redirected to here
260
+ def fx_initialize()
261
+ # Do nothing, as we already control initialization
262
+ end
223
263
 
224
264
  #default java ctor, override for arguments
225
- def java_ctor(ctor, initialize_arguments)
226
- ctor.call
265
+ def java_ctor(*initialize_arguments)
266
+ super()
227
267
  end
228
268
 
229
269
  # Initialize all controllers
230
270
  def initialize_controller(options={}, *args, &block)
231
-
271
+
232
272
  # JRuby complains loudly (probably broken behavior) if we don't call the ctor
233
- java_ctor self.class.superclass.instance_method(:initialize).bind(self), args
273
+ __jallocate!() # TODO: args? TODO: non-java controllers?*args) # TODO: remove
234
274
 
235
275
  # load the FXML file with the current control as the root
236
276
  load_fxml options[:filename], options[:root_dir]
@@ -242,14 +282,14 @@ module JRubyFX::Controller
242
282
  def pre_initialize_controller(options={})
243
283
 
244
284
  # JRuby complains loudly (probably broken behavior) if we don't call the ctor
245
- java_ctor self.class.superclass.instance_method(:initialize).bind(self), [] #TODO: do we need to call this now with []?
285
+ java_ctor self.class.instance_method(:__jallocate!).bind(self), [] #TODO: do we need to call this now with []?
246
286
 
247
287
  # load the FXML file with the current control as the root
248
288
  load_fxml options[:filename], options[:root_dir]
249
289
  end
250
290
 
251
291
  def load_fxml(filename, root_dir=nil)
252
- fx = Controller.get_fxml_loader(filename, self, root_dir || @fxml_root_dir || fxml_root)
292
+ fx = Controller.get_fxml_loader(filename, self, root_dir || @fxml_root_dir || fxml_root, get_fxml_resource_class_loader, get_fxml_classes_class_loader)
253
293
  fx.root = self
254
294
  fx.load
255
295
  end
@@ -261,7 +301,7 @@ module JRubyFX::Controller
261
301
  self.scene = self unless @scene
262
302
 
263
303
  # Everything is ready, call initialize
264
- if private_methods.include? :initialize
304
+ if private_methods.include? :initialize or methods.include? :initialize
265
305
  self.send :initialize, *args, &block
266
306
  end
267
307
 
@@ -294,10 +334,14 @@ module JRubyFX::Controller
294
334
  def self.load_fxml_only(filename, stage, settings={})
295
335
  # Inherit from default settings
296
336
  settings = DEFAULT_SETTINGS.merge({root_dir: fxml_root,
337
+ get_resources: get_fxml_resource_class_loader,
338
+ fxml_class_loader: get_fxml_classes_class_loader,
297
339
  filename: filename}).merge settings
298
-
340
+
341
+ raise "JRubyFX 1.x style class loader argument passed into 'load_fxml_only'. Replace 'class_loader' with either 'get_resources' (likely) or 'fxml_class_loader' (less likely)" if settings.has_key? :class_loader
342
+
299
343
  # load the FXML file
300
- root = Controller.get_fxml_loader(settings[:filename], nil, settings[:root_dir]).load
344
+ root = Controller.get_fxml_loader(settings[:filename], nil, settings[:root_dir], settings[:get_resources], settings[:fxml_class_loader]).load
301
345
 
302
346
  # TODO: de-duplicate this code
303
347
 
@@ -330,20 +374,33 @@ module JRubyFX::Controller
330
374
  # === Equivalent Java
331
375
  # Parent root = FXMLLoader.load(getClass().getResource("Demo.fxml"));
332
376
  #
333
- def self.get_fxml_loader(filename, controller = nil, root_dir = nil)
334
- fx = FxmlLoader.new
335
- fx.location =
336
- if JRubyFX::Application.in_jar?
337
- # If we are in a jar file, use the class loader to get the file from the jar (like java)
338
- # TODO: should just be able to use URLs
339
- JRuby.runtime.jruby_class_loader.get_resource File.join(root_dir, filename)
340
- else
341
- root_dir ||= fxml_root
342
- # If we are in the normal filesystem, create a file url path relative to relative_to or this file
343
- URL.new "file:#{File.join root_dir, filename}"
344
- end
377
+ def self.get_fxml_loader(filename, controller = nil, root_dir = nil, get_resources = JRuby.runtime.jruby_class_loader.method("get_resource"), fxml_class_loader=nil)
378
+ fx = javafx.fxml.FXMLLoader.new(get_fxml_location(root_dir, filename, get_resources))
379
+ fx.class_loader = fxml_class_loader unless fxml_class_loader.nil?
345
380
  # we must set this here for JFX to call our events
346
381
  fx.controller = controller
347
382
  fx
348
383
  end
384
+
385
+ def self.get_fxml_location(root_dir, filename, get_resources)
386
+ if JRubyFX::Application.in_jar? and filename.match(/^[^.\/]/)
387
+ # If we are in a jar file, use the class loader to get the file from the jar (like java)
388
+ # TODO: should just be able to use URLs
389
+
390
+ # According to how class loader works, the correct path for a file inside a jar is NOT "/folder/file.fxml"
391
+ # but "folder/file.fxml" (without starting "/" or ".", which would both make the path to be seen as a filesystem
392
+ # reference) so we assume that if root_dir is set to "" or to any other path not starting with "." or "/" then
393
+ # we want to point to a folder inside the jar, otherwise to a filesystem's one. According to this we format and
394
+ # feed the right path to the class loader.
395
+
396
+ location = get_resources.call(File.join(root_dir, filename))
397
+
398
+ # fall back if not found
399
+ return location if location
400
+ end
401
+
402
+ root_dir ||= fxml_root
403
+ # If we are in the normal filesystem, create a file url path relative to relative_to or this file
404
+ URL.new "file:#{File.join root_dir, filename}"
405
+ end
349
406
  end
@@ -16,6 +16,9 @@
16
16
  "Java::JavafxSceneControl::TreeItem":
17
17
  method_missing: "Java::JavafxSceneControl::TreeItem"
18
18
  add: get_children
19
+ "Java::JavafxSceneControl::TreeTableView":
20
+ method_missing: "Java::JavafxSceneControl::TreeItem"
21
+ add: get_children
19
22
  "Java::JavafxSceneControl::TableView":
20
23
  method_missing: "Java::JavafxSceneControl::TableColumn"
21
24
  add: get_columns
@@ -39,6 +42,8 @@
39
42
  "Java::JavafxAnimation::Timeline":
40
43
  method_missing: "Java::JavafxAnimation::KeyFrame"
41
44
  add: key_frames
45
+ "Java::JavafxSceneLayout::BackgroundFill":
46
+ new_converter: [[color, none, none]]
42
47
  "Java::JavafxSceneShape::Path":
43
48
  add: elements
44
49
  rotate: []
@@ -51,7 +56,10 @@
51
56
  logical_children: panes
52
57
  "Java::JavafxSceneShape::Circle":
53
58
  new_converter: [[], [none], [none, color], [none, none, none], [none, none, none, color]]
59
+ "Java::JavafxSceneShape::Rectangle":
60
+ new_converter: [[], [none, none], [none, none, none, none], [none, none, color]]
54
61
  "Java::JavafxScenePaint::Stop":
55
62
  new_converter: [[none, color]]
56
63
  "Java::JavafxSceneShape::Shape":
57
- getter_setter: fill
64
+ getter_setter: fill
65
+
@@ -131,6 +131,24 @@ module Java::javafx::collections::ObservableMap
131
131
  # stores the listeners.
132
132
  end
133
133
 
134
+ module Java::javafx::beans::binding::NumberExpression
135
+ def - x
136
+ subtract x
137
+ end
138
+ def / x
139
+ divide x
140
+ end
141
+ def * x
142
+ multiply x
143
+ end
144
+ def + x
145
+ add x
146
+ end
147
+ def -@ x
148
+ negate x
149
+ end
150
+ end
151
+
134
152
  class Class
135
153
  def property_writer(*symbol_names)
136
154
  symbol_names.each do |symbol_name|
@@ -147,8 +165,8 @@ class Class
147
165
  end
148
166
  end
149
167
  def property_accessor(*symbol_names)
150
- property_reader *symbol_names
151
- property_writer *symbol_names
168
+ property_reader(*symbol_names)
169
+ property_writer(*symbol_names)
152
170
  symbol_names.each do |symbol_name|
153
171
  send(:define_method, symbol_name.id2name + "_property") do
154
172
  instance_variable_get("@#{symbol_name}")