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.
- checksums.yaml +7 -0
- data/LICENSE +202 -0
- data/README.md +121 -0
- data/bin/jrubyfx-compile +32 -0
- data/bin/jrubyfx-generator +98 -0
- data/bin/jrubyfx-jarify +115 -0
- data/lib/jrubyfx.rb +41 -0
- data/lib/jrubyfx/application.rb +42 -0
- data/lib/jrubyfx/compiler_app.rb +51 -0
- data/lib/jrubyfx/controller.rb +375 -0
- data/lib/jrubyfx/core_ext/border_pane.rb +30 -0
- data/lib/jrubyfx/core_ext/column_constraints.rb +43 -0
- data/lib/jrubyfx/core_ext/drag_event.rb +32 -0
- data/lib/jrubyfx/core_ext/duration.rb +30 -0
- data/lib/jrubyfx/core_ext/effects.rb +32 -0
- data/lib/jrubyfx/core_ext/exts.yml +57 -0
- data/lib/jrubyfx/core_ext/file_chooser.rb +63 -0
- data/lib/jrubyfx/core_ext/geometry.rb +27 -0
- data/lib/jrubyfx/core_ext/grid_pane.rb +30 -0
- data/lib/jrubyfx/core_ext/image_view.rb +25 -0
- data/lib/jrubyfx/core_ext/media_player.rb +25 -0
- data/lib/jrubyfx/core_ext/observable_value.rb +158 -0
- data/lib/jrubyfx/core_ext/pagination.rb +28 -0
- data/lib/jrubyfx/core_ext/path.rb +37 -0
- data/lib/jrubyfx/core_ext/precompiled.rb +1883 -0
- data/lib/jrubyfx/core_ext/progress_indicator.rb +41 -0
- data/lib/jrubyfx/core_ext/radial_gradient.rb +37 -0
- data/lib/jrubyfx/core_ext/region.rb +42 -0
- data/lib/jrubyfx/core_ext/rotate.rb +39 -0
- data/lib/jrubyfx/core_ext/stage.rb +89 -0
- data/lib/jrubyfx/core_ext/table_view.rb +31 -0
- data/lib/jrubyfx/core_ext/timeline.rb +56 -0
- data/lib/jrubyfx/core_ext/transition.rb +26 -0
- data/lib/jrubyfx/core_ext/tree_view.rb +40 -0
- data/lib/jrubyfx/core_ext/xy_chart.rb +53 -0
- data/lib/jrubyfx/dsl.rb +330 -0
- data/lib/jrubyfx/dsl_control.rb +28 -0
- data/lib/jrubyfx/dsl_map.rb +273 -0
- data/lib/jrubyfx/imports.rb +324 -0
- data/lib/jrubyfx/java_fx_impl.rb +144 -0
- data/lib/jrubyfx/module.rb +178 -0
- data/lib/jrubyfx/part_imports.rb +141 -0
- data/lib/jrubyfx/utils.rb +86 -0
- data/lib/jrubyfx/utils/__ignore_java_stupid_rdoc.rb +30 -0
- data/lib/jrubyfx/utils/common_converters.rb +223 -0
- data/lib/jrubyfx/utils/common_utils.rb +72 -0
- data/lib/jrubyfx/utils/string_utils.rb +48 -0
- data/lib/jrubyfx/version.rb +4 -0
- data/lib/jrubyfx_tasks.rb +183 -0
- metadata +145 -0
data/bin/jrubyfx-jarify
ADDED
@@ -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
|
data/lib/jrubyfx.rb
ADDED
@@ -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
|