jrubyfx-master 1.1.1.brakemanpro1-java
Sign up to get free protection for your applications and to get access to all the features.
- 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/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 +310 -0
- data/lib/jrubyfx/java_fx_impl.rb +137 -0
- data/lib/jrubyfx/module.rb +178 -0
- data/lib/jrubyfx/part_imports.rb +127 -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/utils.rb +76 -0
- data/lib/jrubyfx/version.rb +4 -0
- data/lib/jrubyfx.rb +41 -0
- data/lib/jrubyfx_tasks.rb +183 -0
- metadata +145 -0
@@ -0,0 +1,127 @@
|
|
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_relative 'utils'
|
19
|
+
|
20
|
+
# Update load path to include the JavaFX runtime and fail nicely if we can't find it
|
21
|
+
begin
|
22
|
+
if ENV['JFX_DIR']
|
23
|
+
$LOAD_PATH << ENV['JFX_DIR']
|
24
|
+
else #should we check for 1.7 vs 1.8? oh well, adding extra paths won't hurt anybody (maybe performance loading)
|
25
|
+
jfx_path = ENV_JAVA["sun.boot.library.path"]
|
26
|
+
$LOAD_PATH << if jfx_path.include? ":\\" and !jfx_path.include? "/" # can be tricked, but should work fine
|
27
|
+
#windows
|
28
|
+
jfx_path.gsub(/\\bin[\\]*$/i, "\\lib")
|
29
|
+
else
|
30
|
+
# *nix
|
31
|
+
jfx_path.gsub(/[\/\\][amdix345678_]+$/, "") # strip i386 or amd64 (including variants). TODO: ARM
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Java 8 at some point requires explicit toolkit/platform initialization
|
36
|
+
# before any controls can be loaded.
|
37
|
+
JRubyFX.load_fx
|
38
|
+
|
39
|
+
# Attempt to load a javafx class
|
40
|
+
Java.javafx.application.Application
|
41
|
+
rescue LoadError, NameError
|
42
|
+
puts "JavaFX runtime not found. Please install Java 7u6 or newer or set environment variable JFX_DIR to the folder that contains jfxrt.jar "
|
43
|
+
puts "If you have Java 7u6 or later, this is a bug. Please report to the issue tracker on github. Include your OS version, 32/64bit, and architecture (x86, ARM, PPC, etc)"
|
44
|
+
exit -1
|
45
|
+
end
|
46
|
+
|
47
|
+
module JRubyFX
|
48
|
+
# If you need JavaFX, just include this module. Its sole purpose in life is to
|
49
|
+
# import all JavaFX stuff, plus a few useful Java classes (like Void)
|
50
|
+
module FXImports
|
51
|
+
|
52
|
+
# If something is missing, just java_import it in your code.
|
53
|
+
# And then ask us to put it in this list
|
54
|
+
###### IMPORTANT LINE ##### (see rakefile, this is a magic line, don't delete)
|
55
|
+
|
56
|
+
##
|
57
|
+
# This is the list of all classes in JavaFX that most apps should care about.
|
58
|
+
# It is a hashmaps with the leafs as arrays. Where a leaf also contains more
|
59
|
+
# packages, the hashmap key is "" (empty string). You can utilize this constant
|
60
|
+
# to save yourself some typing when adding code for most/all of the JavaFX
|
61
|
+
# classes by using either `Hash.flat_tree_inject` from jrubyfx/utils.rb or
|
62
|
+
# writing your own traversal function
|
63
|
+
#
|
64
|
+
JFX_CLASS_HIERARCHY = { :javafx => {
|
65
|
+
:animation => %w[Animation AnimationTimer FadeTransition FillTransition Interpolator KeyFrame KeyValue ParallelTransition PathTransition
|
66
|
+
PauseTransition RotateTransition ScaleTransition SequentialTransition StrokeTransition Timeline Transition TranslateTransition],
|
67
|
+
:application => ['Platform'],
|
68
|
+
:beans => {
|
69
|
+
:property => %w[SimpleBooleanProperty SimpleDoubleProperty SimpleFloatProperty SimpleIntegerProperty SimpleListProperty SimpleLongProperty SimpleMapProperty SimpleObjectProperty SimpleSetProperty SimpleStringProperty],
|
70
|
+
#TODO: import more
|
71
|
+
:value => ['ChangeListener']
|
72
|
+
},
|
73
|
+
:collections => ['FXCollections'],
|
74
|
+
:concurrent => %w[Worker Task Service],
|
75
|
+
:event => %w[Event ActionEvent EventHandler],
|
76
|
+
:fxml => ['Initializable', 'LoadException'],
|
77
|
+
:geometry => %w[HorizontalDirection HPos Insets Orientation Pos Rectangle2D Side VerticalDirection VPos],
|
78
|
+
:scene => {
|
79
|
+
'' => %w[Group Node Parent Scene],
|
80
|
+
:canvas => ['Canvas'],
|
81
|
+
:chart => %w[AreaChart Axis BarChart BubbleChart CategoryAxis Chart LineChart NumberAxis
|
82
|
+
PieChart ScatterChart StackedAreaChart StackedBarChart ValueAxis XYChart],
|
83
|
+
:control => %w[Accordion Button Cell CheckBox CheckBoxTreeItem CheckMenuItem ChoiceBox ColorPicker ComboBox ContextMenu Hyperlink
|
84
|
+
Label ListCell ListView Menu MenuBar MenuButton MenuItem Pagination PasswordField PopupControl ProgressBar ProgressIndicator RadioButton
|
85
|
+
RadioMenuItem ScrollBar ScrollPane Separator SeparatorMenuItem Slider SplitMenuButton SplitPane Tab TableView TableCell TableColumn TabPane TextArea
|
86
|
+
TextField TitledPane ToggleButton ToggleGroup ToolBar Tooltip TreeCell TreeItem TreeView ContentDisplay OverrunStyle SelectionMode],
|
87
|
+
:effect => %w[Blend BlendMode Bloom BlurType BoxBlur ColorAdjust ColorInput DisplacementMap DropShadow GaussianBlur Glow ImageInput
|
88
|
+
InnerShadow Lighting MotionBlur PerspectiveTransform Reflection SepiaTone Shadow],
|
89
|
+
:image => %w[Image ImageView PixelReader PixelWriter],
|
90
|
+
:input => %w[Clipboard ClipboardContent ContextMenuEvent DragEvent GestureEvent InputEvent InputMethodEvent KeyCode KeyEvent
|
91
|
+
Mnemonic MouseButton MouseDragEvent MouseEvent RotateEvent ScrollEvent SwipeEvent TouchEvent TransferMode ZoomEvent],
|
92
|
+
:layout => %w[AnchorPane BorderPane ColumnConstraints FlowPane GridPane HBox Pane Priority RowConstraints StackPane TilePane VBox],
|
93
|
+
:media => %w[AudioClip AudioEqualizer AudioTrack EqualizerBand Media MediaException
|
94
|
+
MediaErrorEvent MediaMarkerEvent MediaPlayer MediaView VideoTrack],
|
95
|
+
:paint => %w[Color CycleMethod ImagePattern LinearGradient Paint RadialGradient Stop],
|
96
|
+
:shape => %w[Arc ArcTo ArcType Circle ClosePath CubicCurve CubicCurveTo Ellipse FillRule HLineTo Line LineTo MoveTo Path PathElement
|
97
|
+
Polygon Polyline QuadCurve QuadCurveTo Rectangle Shape StrokeLineCap StrokeLineJoin StrokeType SVGPath VLineTo],
|
98
|
+
:text => %w[Font FontPosture FontSmoothingType FontWeight Text TextAlignment TextBoundsType],
|
99
|
+
:transform => %w[Affine Rotate Scale Shear Translate],
|
100
|
+
:web => ['WebView', 'HTMLEditor']
|
101
|
+
},
|
102
|
+
:stage => %w[DirectoryChooser FileChooser Modality Popup PopupWindow Screen Stage StageStyle Window WindowEvent],
|
103
|
+
:util => ['Duration']
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
$WRITE_OUT << <<HERE
|
108
|
+
def const_missing(c)
|
109
|
+
if LOCAL_NAME_MAP.has_key? c
|
110
|
+
java_import(LOCAL_NAME_MAP[c])[0]
|
111
|
+
else
|
112
|
+
super
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
HERE
|
117
|
+
|
118
|
+
# Imports all the listed JavaFX classes
|
119
|
+
$WRITE_OUT << "LOCAL_NAME_MAP = { \n "
|
120
|
+
$WRITE_OUT << (JFX_CLASS_HIERARCHY.flat_tree_inject do |res, name, values|
|
121
|
+
name = "#{name.to_s}."
|
122
|
+
name = "" if name == "."
|
123
|
+
res.concat(values.map{|i| "#{name}#{i}"})
|
124
|
+
end).map{|x| "#{x.split(".").last.to_sym.inspect} => #{x.inspect}"}.join(",\n ")
|
125
|
+
$WRITE_OUT << "\n}\njava_import 'java.lang.Void'"
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Java #:nodoc: all
|
2
|
+
module javafx
|
3
|
+
module animation
|
4
|
+
end
|
5
|
+
module beans
|
6
|
+
module value
|
7
|
+
end
|
8
|
+
end
|
9
|
+
module scene
|
10
|
+
module chart
|
11
|
+
end
|
12
|
+
module control
|
13
|
+
end
|
14
|
+
module effect
|
15
|
+
end
|
16
|
+
module layout
|
17
|
+
end
|
18
|
+
module media
|
19
|
+
end
|
20
|
+
module paint
|
21
|
+
end
|
22
|
+
module shape
|
23
|
+
end
|
24
|
+
module transform
|
25
|
+
end
|
26
|
+
end
|
27
|
+
module stage
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,223 @@
|
|
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
|
+
false # Do NOT delete this or it will make RDOC associate the copyright header with JRubyFX module
|
18
|
+
|
19
|
+
module JRubyFX
|
20
|
+
module Utils
|
21
|
+
# Contains conversion utilities to ease Ruby => JavaFX coding
|
22
|
+
module CommonConverters
|
23
|
+
java_import 'javafx.scene.paint.Color'
|
24
|
+
java_import 'javafx.geometry.Insets'
|
25
|
+
java_import 'javafx.geometry.Rectangle2D'
|
26
|
+
|
27
|
+
# argument converter method name suffix
|
28
|
+
ARG_CONVERTER_SUFFIX = '_arg_converter'
|
29
|
+
|
30
|
+
# map of snake_cased colors to JavaFX Colors
|
31
|
+
NAME_TO_COLORS = {
|
32
|
+
'darkyellow' => Color.web('0xc0c000'),
|
33
|
+
'lightmagenta' => Color.web('0xffc0ff'),
|
34
|
+
'lightred' => Color.web('0xffc0c0'),
|
35
|
+
}.merge(Color.java_class.fields.inject({}) {|final, field|
|
36
|
+
final[field.name.downcase] = field.value(nil) # TODO: what is nil supposed to be?
|
37
|
+
final
|
38
|
+
})
|
39
|
+
|
40
|
+
##
|
41
|
+
# Generate a converter for a map of supplied values.
|
42
|
+
def map_converter(map)
|
43
|
+
lambda do |value|
|
44
|
+
map.key?(value) ? map[value] : value
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Generate a converter for an enum of the given class
|
50
|
+
def enum_converter(enum_class)
|
51
|
+
lambda do |value|
|
52
|
+
(JRubyFX::Utils::CommonConverters.map_enums(enum_class)[value.to_s] || value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# call-seq:
|
58
|
+
# animation_converter_for :property_name, ...
|
59
|
+
#
|
60
|
+
# Generates an animation adapter for the given properties so you can specify
|
61
|
+
# transformations, etc with a hashmap of from, to values
|
62
|
+
# === Examples
|
63
|
+
# animation_converter_for :value
|
64
|
+
#
|
65
|
+
# ...
|
66
|
+
#
|
67
|
+
# _my_type_(value: {0 => 360})
|
68
|
+
#
|
69
|
+
def animation_converter_for(*prop_names)
|
70
|
+
prop_names.each do |prop_name|
|
71
|
+
self.__send__(:define_method, prop_name.to_s + "=") do |hash|
|
72
|
+
method("from_#{prop_name}=").call hash.keys[0]
|
73
|
+
method("to_#{prop_name}=").call hash.values[0]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Allows you to specify you want a converter method created for the
|
80
|
+
# specified method where each listed converter corresponds to each
|
81
|
+
# argument for that method. You can have n-arity lists for all
|
82
|
+
# matching Java overloads. This mechanism means you may not always
|
83
|
+
# be able to specify all coercions you want.
|
84
|
+
# === Examples
|
85
|
+
#
|
86
|
+
# coverter_for :new, [:none, :color]
|
87
|
+
#
|
88
|
+
# This method will define a method on the current class called
|
89
|
+
# *new_arg_converter* which will perform no argument coercion on
|
90
|
+
# the first argument and a color coercion on the second argument.
|
91
|
+
#
|
92
|
+
# e = enum_converter(Java::javafx::scene::input::TransferMode)
|
93
|
+
# converter_for :accept_transfer_modes &e
|
94
|
+
#
|
95
|
+
# This method will allow a catch-all converter to be used for all
|
96
|
+
# arities not specified. In this case since no arities are given
|
97
|
+
# all arities will pass through this enum_converter. This form
|
98
|
+
# is useful for single var_args signatures.
|
99
|
+
#
|
100
|
+
def converter_for(method_name, *converters, &default)
|
101
|
+
# puts "[converter for #{self}, #{method_name}]"
|
102
|
+
sheep = lambda do |direct, this, *values|
|
103
|
+
converter = converters.find { |e| e.length == values.length }
|
104
|
+
converter = Array.new(values.length, default) unless converter
|
105
|
+
|
106
|
+
# FIXME: Better error reporting on many things which can fail
|
107
|
+
i = 0
|
108
|
+
values = values.inject([]) do |s, value|
|
109
|
+
conv = converter[i]
|
110
|
+
if conv.kind_of? Proc
|
111
|
+
s << conv.call(value)
|
112
|
+
else
|
113
|
+
s << CONVERTERS[converter[i]].call(value)
|
114
|
+
end
|
115
|
+
i += 1
|
116
|
+
s
|
117
|
+
end
|
118
|
+
if direct
|
119
|
+
return this.method("set_" + method_name.to_s).call(*values)
|
120
|
+
else
|
121
|
+
return values
|
122
|
+
end
|
123
|
+
end
|
124
|
+
# define a setter for normal usage
|
125
|
+
unless method_name == :new
|
126
|
+
self.__send__(:define_method, method_name.to_s + "=") do |*values|
|
127
|
+
sheep.call(true, self, *values)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
# define a build/with usage
|
131
|
+
self.__send__(:define_method, method_name.to_s + ARG_CONVERTER_SUFFIX) do |*values|
|
132
|
+
sheep.call(false, self, *values)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Map of different kinds of known converters
|
137
|
+
CONVERTERS = {
|
138
|
+
:none => lambda { |value|
|
139
|
+
value
|
140
|
+
},
|
141
|
+
:color => lambda { |value|
|
142
|
+
new_value = NAME_TO_COLORS[value.to_s.gsub(/_/, "")]
|
143
|
+
if !new_value && value.kind_of?(Symbol)
|
144
|
+
raise ArgumentError.new("No such color: #{value.to_s}")
|
145
|
+
end
|
146
|
+
new_value ? new_value : value
|
147
|
+
},
|
148
|
+
:rectangle2d => lambda { |value|
|
149
|
+
if value == :empty
|
150
|
+
Rectangle2D::EMPTY
|
151
|
+
elsif value.is_a? Array
|
152
|
+
Rectangle2D.new(*value)
|
153
|
+
else
|
154
|
+
value
|
155
|
+
end
|
156
|
+
},
|
157
|
+
:insets => lambda { |value|
|
158
|
+
if value == :empty
|
159
|
+
Insets::EMPTY
|
160
|
+
elsif value.is_a? Numeric
|
161
|
+
Insets.new(value)
|
162
|
+
elsif value.is_a? Array
|
163
|
+
# top/bottom, left/right
|
164
|
+
value = [value[0], value[1], value[0], value[1]] if value.size == 2
|
165
|
+
Insets.new(*value)
|
166
|
+
else
|
167
|
+
value
|
168
|
+
end
|
169
|
+
},
|
170
|
+
}
|
171
|
+
|
172
|
+
ENUM_CACHE = {}
|
173
|
+
|
174
|
+
# Store enum mapping overrides
|
175
|
+
ENUM_OVERRIDES = {Java::JavafxAnimation::PathTransition::OrientationType => {:orthogonal_to_tangent => :orthogonal},
|
176
|
+
Java::JavafxSceneEffect::BlendMode => {:src_over => :over, :src_atop => :atop, :color_dodge => :dodge, :color_burn => :burn},
|
177
|
+
Java::JavafxSceneControl::ContentDisplay => {:graphic_only => :graphic, :text_only => :text},
|
178
|
+
Java::JavafxSceneEffect::BlurType => {:one_pass_box => [:one, :one_pass], :two_pass_box => [:two, :two_pass], :three_pass_box => [:three, :three_pass]},
|
179
|
+
Java::JavafxStage::Modality => {:window_modal => :window, :application_modal => [:application, :app]}}
|
180
|
+
|
181
|
+
# sets the given overrides for the given class/enum
|
182
|
+
def self.set_overrides_for(enum_class,ovr)
|
183
|
+
ENUM_OVERRIDES[enum_class] = ovr
|
184
|
+
end
|
185
|
+
|
186
|
+
# Given a class, returns a hash of lowercase strings mapped to Java Enums
|
187
|
+
def self.map_enums(enum_class)
|
188
|
+
res = Hash[enum_class.java_class.enum_constants.map {|i| [i.to_s.downcase, i] }]
|
189
|
+
(ENUM_OVERRIDES[enum_class]||[]).each do |oldk, newks|
|
190
|
+
[newks].flatten.each do |newk|
|
191
|
+
res[newk.to_s] = res[oldk.to_s]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
res
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.parse_ruby_symbols(const, enum)
|
198
|
+
ENUM_CACHE[enum] = JRubyFX::Utils::CommonConverters.map_enums(enum) if ENUM_CACHE[enum] == nil
|
199
|
+
ENUM_CACHE[enum][const.to_s] || const
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.convert_args(values, converters)
|
203
|
+
converter = converters.find { |e| e.length == values.length }
|
204
|
+
converter = Array.new(values.length) unless converter
|
205
|
+
|
206
|
+
# FIXME: Better error reporting on many things which can fail
|
207
|
+
i = 0
|
208
|
+
values = values.inject([]) do |s, value|
|
209
|
+
conv = converter[i]
|
210
|
+
if conv.kind_of? Proc
|
211
|
+
s << conv.call(value)
|
212
|
+
else
|
213
|
+
s << CONVERTERS[converter[i]].call(value)
|
214
|
+
end
|
215
|
+
i += 1
|
216
|
+
s
|
217
|
+
end
|
218
|
+
return values
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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_relative 'common_converters'
|
18
|
+
|
19
|
+
module JRubyFX
|
20
|
+
# Several utilities that have no better place to go
|
21
|
+
module Utils
|
22
|
+
# Utilities to manage argument properties for build/with
|
23
|
+
module CommonUtils
|
24
|
+
##
|
25
|
+
# If last argument of the arg list is a hash-like entity (:each_pair)
|
26
|
+
# then this strip off last argument and return it as second return
|
27
|
+
# value.
|
28
|
+
# === Examples:
|
29
|
+
# split_args_from_properties(1, 2, a: 1) #=> [[1,2], {a: 1}]
|
30
|
+
# split_args_from_properties(1, 2) #=> [[1,2], {}]
|
31
|
+
#
|
32
|
+
def split_args_from_properties(*args)
|
33
|
+
if !args.empty? and args.last.respond_to? :each_pair
|
34
|
+
properties = args.pop
|
35
|
+
else
|
36
|
+
properties = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
return args, properties
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Sets the hashmap given on the passed in object as a set of properties,
|
44
|
+
# using converter if necessary.
|
45
|
+
#
|
46
|
+
def populate_properties(obj, properties)
|
47
|
+
properties.each_pair do |name, value|
|
48
|
+
obj.send(name.to_s + '=', *attempt_conversion(obj, name, value))
|
49
|
+
end
|
50
|
+
obj
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Attempts to convert given value to JavaFX equvalent, if any, by calling
|
55
|
+
# obj.name_CommonConverters::ARG_CONVERTER_SUFFING, which is created by
|
56
|
+
# calling CommonConverters.converter_for in your class.
|
57
|
+
# See CommonConverters for current conversions
|
58
|
+
#
|
59
|
+
def attempt_conversion(obj, name, *values)
|
60
|
+
converter_method = name.to_s +
|
61
|
+
JRubyFX::Utils::CommonConverters::ARG_CONVERTER_SUFFIX
|
62
|
+
|
63
|
+
# Each type can create their own converter method to coerce things
|
64
|
+
# like symbols into real values JavaFX likes.
|
65
|
+
if obj.respond_to? converter_method
|
66
|
+
values = obj.__send__ converter_method, *values
|
67
|
+
end
|
68
|
+
values
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# steal handy methods from activesupport
|
4
|
+
# Tries to find a constant with the name specified in the argument string.
|
5
|
+
#
|
6
|
+
# 'Module'.constantize # => Module
|
7
|
+
# 'Test::Unit'.constantize # => Test::Unit
|
8
|
+
#
|
9
|
+
# The name is assumed to be the one of a top-level constant, no matter
|
10
|
+
# whether it starts with "::" or not. No lexical context is taken into
|
11
|
+
# account:
|
12
|
+
#
|
13
|
+
# C = 'outside'
|
14
|
+
# module M
|
15
|
+
# C = 'inside'
|
16
|
+
# C # => 'inside'
|
17
|
+
# 'C'.constantize # => 'outside', same as ::C
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# NameError is raised when the name is not in CamelCase or the constant is
|
21
|
+
# unknown.
|
22
|
+
def constantize_by(splitter="::")
|
23
|
+
camel_cased_word = self
|
24
|
+
names = camel_cased_word.split(splitter)
|
25
|
+
names.shift if names.empty? || names.first.empty?
|
26
|
+
|
27
|
+
names.inject(Object) do |constant, name|
|
28
|
+
if constant == Object
|
29
|
+
constant.const_get(name)
|
30
|
+
else
|
31
|
+
candidate = constant.const_get(name)
|
32
|
+
next candidate if constant.const_defined?(name, false)
|
33
|
+
next candidate unless Object.const_defined?(name)
|
34
|
+
|
35
|
+
# Go down the ancestors to check it it's owned
|
36
|
+
# directly before we reach Object or the end of ancestors.
|
37
|
+
constant = constant.ancestors.inject do |const, ancestor|
|
38
|
+
break const if ancestor == Object
|
39
|
+
break ancestor if ancestor.const_defined?(name, false)
|
40
|
+
const
|
41
|
+
end
|
42
|
+
|
43
|
+
# owner is in Object, so raise
|
44
|
+
constant.const_get(name, false)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,76 @@
|
|
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
|
+
# This feels kinda like a hack. If anyone has a better idea, please let me know
|
19
|
+
|
20
|
+
# Standard ruby Hash class extensions
|
21
|
+
class Hash
|
22
|
+
|
23
|
+
# call-seq:
|
24
|
+
# flat_tree_inject() {|results, key, value| block} => array
|
25
|
+
# flat_tree_inject(Hash) {|results, key, value| block} => hash
|
26
|
+
#
|
27
|
+
# Execute given block against all nodes in the hash tree, returning `results`.
|
28
|
+
# Similar to Hash#each except goes into all sub-Hashes
|
29
|
+
#
|
30
|
+
def flat_tree_inject(klass=Array,&block)
|
31
|
+
self.inject(klass.new) do |lres, pair|
|
32
|
+
if pair[1].is_a? Hash
|
33
|
+
pair[1] = pair[1].flat_tree_inject(klass, &block)
|
34
|
+
end
|
35
|
+
block.call(lres, *pair)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Standard ruby String class extensions
|
41
|
+
class String
|
42
|
+
# call-seq:
|
43
|
+
# snake_case() => string
|
44
|
+
#
|
45
|
+
# Converts a CamelCaseString to a snake_case_string
|
46
|
+
#
|
47
|
+
# "JavaFX".snake_case #=> "java_fx"
|
48
|
+
#
|
49
|
+
def snake_case
|
50
|
+
self.gsub(/::/, '/').
|
51
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
52
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
53
|
+
tr("-", "_").
|
54
|
+
downcase
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Enumerable
|
59
|
+
def map_find(&block)
|
60
|
+
m = {}
|
61
|
+
m[self.find do |i|
|
62
|
+
m[i] = block.call(i)
|
63
|
+
end]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module JRubyFX
|
68
|
+
def self.load_fx(force=false)
|
69
|
+
return if @already_loaded_fx and !force
|
70
|
+
@already_loaded_fx = true
|
71
|
+
java.util.concurrent.CountDownLatch.new(1).tap do |latch|
|
72
|
+
com.sun.javafx.application.PlatformImpl.startup { latch.countDown }
|
73
|
+
latch.await
|
74
|
+
end
|
75
|
+
end
|
76
|
+
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'
|