jrubyfx 1.1.0-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
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}")