jrubyfx 0.9.1-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.
- data/LICENSE +202 -0
- data/README.md +97 -0
- data/bin/jrubyfx-jarify +90 -0
- data/bin/rubyfx-generator +81 -0
- data/lib/jrubyfx.rb +27 -0
- data/lib/jrubyfx/core_ext/border_pane.rb +29 -0
- data/lib/jrubyfx/core_ext/circle.rb +26 -0
- data/lib/jrubyfx/core_ext/column_constraints.rb +41 -0
- data/lib/jrubyfx/core_ext/duration.rb +28 -0
- data/lib/jrubyfx/core_ext/effects.rb +30 -0
- data/lib/jrubyfx/core_ext/file_chooser.rb +60 -0
- data/lib/jrubyfx/core_ext/labeled.rb +24 -0
- data/lib/jrubyfx/core_ext/media_player.rb +23 -0
- data/lib/jrubyfx/core_ext/node.rb +24 -0
- data/lib/jrubyfx/core_ext/observable_value.rb +36 -0
- data/lib/jrubyfx/core_ext/pagination.rb +26 -0
- data/lib/jrubyfx/core_ext/parallel_transition.rb +28 -0
- data/lib/jrubyfx/core_ext/parent.rb +28 -0
- data/lib/jrubyfx/core_ext/path.rb +41 -0
- data/lib/jrubyfx/core_ext/progress_indicator.rb +38 -0
- data/lib/jrubyfx/core_ext/radial_gradient.rb +37 -0
- data/lib/jrubyfx/core_ext/region.rb +39 -0
- data/lib/jrubyfx/core_ext/rotate.rb +37 -0
- data/lib/jrubyfx/core_ext/scene.rb +29 -0
- data/lib/jrubyfx/core_ext/shape.rb +27 -0
- data/lib/jrubyfx/core_ext/stage.rb +77 -0
- data/lib/jrubyfx/core_ext/stop.rb +29 -0
- data/lib/jrubyfx/core_ext/table_view.rb +35 -0
- data/lib/jrubyfx/core_ext/timeline.rb +47 -0
- data/lib/jrubyfx/core_ext/transition.rb +25 -0
- data/lib/jrubyfx/core_ext/xy_chart.rb +53 -0
- data/lib/jrubyfx/dsl.rb +217 -0
- data/lib/jrubyfx/fxml_application.rb +44 -0
- data/lib/jrubyfx/fxml_controller.rb +270 -0
- data/lib/jrubyfx/fxml_module.rb +98 -0
- data/lib/jrubyfx/java_fx_impl.rb +139 -0
- data/lib/jrubyfx/jfx_imports.rb +107 -0
- data/lib/jrubyfx/utils.rb +56 -0
- data/lib/jrubyfx/utils/__ignore_java_stupid_rdoc.rb +24 -0
- data/lib/jrubyfx/utils/common_converters.rb +140 -0
- data/lib/jrubyfx/utils/common_utils.rb +72 -0
- data/lib/jrubyfx/version.rb +4 -0
- data/lib/jrubyfx_tasks.rb +110 -0
- metadata +116 -0
@@ -0,0 +1,98 @@
|
|
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'
|
19
|
+
require 'jrubyfx/utils/common_utils'
|
20
|
+
|
21
|
+
# This module contains useful methods for defining JavaFX code. Include it in your
|
22
|
+
# class to use it, and the JRubyFX::FXImports. JRubyFX::Application and JRubyFX::Controller already include it.
|
23
|
+
module JRubyFX
|
24
|
+
include JRubyFX::FXImports
|
25
|
+
include JRubyFX::Utils::CommonUtils
|
26
|
+
|
27
|
+
##
|
28
|
+
# call-seq:
|
29
|
+
# with(obj, hash) => obj
|
30
|
+
# with(obj) { block } => obj
|
31
|
+
# with(obj, hash) { block }=> obj
|
32
|
+
#
|
33
|
+
# Set properties (e.g. setters) on the passed in object plus also invoke
|
34
|
+
# any block passed against this object.
|
35
|
+
# === Examples
|
36
|
+
#
|
37
|
+
# with(grid, vgap: 2, hgap: 2) do
|
38
|
+
# set_pref_size(500, 400)
|
39
|
+
# children << location << go << view
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
def with(obj, properties = {}, &block)
|
43
|
+
populate_properties(obj, properties)
|
44
|
+
|
45
|
+
if block_given?
|
46
|
+
# cache the proxy - http://wiki.jruby.org/Persistence
|
47
|
+
obj.class.__persistent__ = true if obj.class.ancestors.include? JavaProxy
|
48
|
+
obj.extend(JRubyFX)
|
49
|
+
obj.instance_eval(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
obj
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# call-seq:
|
57
|
+
# run_later { block }
|
58
|
+
#
|
59
|
+
# Convenience method so anything can safely schedule to run on JavaFX
|
60
|
+
# main thread.
|
61
|
+
def run_later(&block)
|
62
|
+
Platform.run_later &block
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# call-seq:
|
67
|
+
# build(class) => obj
|
68
|
+
# build(class, hash) => obj
|
69
|
+
# build(class) { block } => obj
|
70
|
+
# build(class, hash) { block } => obj
|
71
|
+
#
|
72
|
+
# Create "build" a new JavaFX instance with the provided class and
|
73
|
+
# set properties (e.g. setters) on that new instance plus also invoke
|
74
|
+
# any block passed against this new instance. This also can build a proc
|
75
|
+
# or lambda form in which case the return value of the block will be what
|
76
|
+
# is used to set the additional properties on.
|
77
|
+
# === Examples
|
78
|
+
#
|
79
|
+
# grid = build(GridPane, vgap: 2, hgap: 2) do
|
80
|
+
# set_pref_size(500, 400)
|
81
|
+
# children << location << go << view
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# build(proc { Foo.new }, vgap: 2, hgap: 2)
|
85
|
+
#
|
86
|
+
def build(klass, *args, &block)
|
87
|
+
args, properties = split_args_from_properties(*args)
|
88
|
+
|
89
|
+
obj = if klass.kind_of? Proc
|
90
|
+
klass.call(*args)
|
91
|
+
else
|
92
|
+
klass.new(*attempt_conversion(klass, :new, *args))
|
93
|
+
end
|
94
|
+
|
95
|
+
with(obj, properties, &block)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1,139 @@
|
|
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
|
+
#:nodoc: all
|
18
|
+
require 'jrubyfx'
|
19
|
+
|
20
|
+
# Due to certain bugs in JRuby 1.7 (namely some newInstance mapping bugs), we
|
21
|
+
# are forced to re-create the Launcher if we want a pure ruby wrapper
|
22
|
+
# I can't wait to delete this. The _ONLY_ code that should use this is
|
23
|
+
# JRubyFX::Application.launch. Do _NOT_ use this code anywhere else.
|
24
|
+
module JavaFXImpl #:nodoc: all
|
25
|
+
java_import 'com.sun.javafx.application.PlatformImpl'
|
26
|
+
java_import 'javafx.stage.Stage'
|
27
|
+
|
28
|
+
#JRuby, you make me have to create real classes!
|
29
|
+
class FinisherInterface
|
30
|
+
include PlatformImpl::FinishListener
|
31
|
+
|
32
|
+
def initialize(&block)
|
33
|
+
@exitBlock = block
|
34
|
+
end
|
35
|
+
|
36
|
+
def idle(someBoolean)
|
37
|
+
@exitBlock.call
|
38
|
+
end
|
39
|
+
|
40
|
+
def exitCalled()
|
41
|
+
@exitBlock.call
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Launcher
|
46
|
+
java_import 'java.util.concurrent.atomic.AtomicBoolean'
|
47
|
+
java_import 'java.util.concurrent.CountDownLatch'
|
48
|
+
java_import 'java.lang.IllegalStateException'
|
49
|
+
|
50
|
+
@@launchCalled = AtomicBoolean.new(false) # Atomic boolean go boom on bikini
|
51
|
+
|
52
|
+
def self.launch_app(classObj, args=nil)
|
53
|
+
#prevent multiple!
|
54
|
+
if @@launchCalled.getAndSet(true)
|
55
|
+
throw IllegalStateException.new "Application launch must not be called more than once"
|
56
|
+
end
|
57
|
+
|
58
|
+
begin
|
59
|
+
#create a java thread, and run the real worker, and wait till it exits
|
60
|
+
count_down_latch = CountDownLatch.new(1)
|
61
|
+
thread = Java.java.lang.Thread.new do
|
62
|
+
begin
|
63
|
+
launch_app_from_thread(classObj)
|
64
|
+
rescue => ex
|
65
|
+
puts "Exception starting app:"
|
66
|
+
p ex
|
67
|
+
p ex.backtrace
|
68
|
+
end
|
69
|
+
count_down_latch.countDown #always count down
|
70
|
+
end
|
71
|
+
thread.name = "JavaFX-Launcher"
|
72
|
+
thread.start
|
73
|
+
count_down_latch.await
|
74
|
+
rescue => ex
|
75
|
+
puts "Exception launching JavaFX-Launcher thread:"
|
76
|
+
p ex
|
77
|
+
puts ex.backtrace
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.launch_app_from_thread(classO)
|
82
|
+
#platformImpl startup?
|
83
|
+
finished_latch = CountDownLatch.new(1)
|
84
|
+
PlatformImpl.startup do
|
85
|
+
finished_latch.countDown
|
86
|
+
end
|
87
|
+
finished_latch.await
|
88
|
+
|
89
|
+
begin
|
90
|
+
launch_app_after_platform(classO) #try to launch the app
|
91
|
+
rescue => ex
|
92
|
+
puts "Error running Application:"
|
93
|
+
p ex
|
94
|
+
puts ex.backtrace
|
95
|
+
end
|
96
|
+
|
97
|
+
#kill the toolkit and exit
|
98
|
+
PlatformImpl.tkExit
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.launch_app_after_platform(classO)
|
102
|
+
#listeners - for the end
|
103
|
+
finished_latch = CountDownLatch.new(1)
|
104
|
+
|
105
|
+
# register for shutdown
|
106
|
+
PlatformImpl.addListener(FinisherInterface.new {
|
107
|
+
# this is called when the stage exits
|
108
|
+
finished_latch.countDown
|
109
|
+
})
|
110
|
+
|
111
|
+
app = classO.new
|
112
|
+
# do we need to register the params if there are none? - apparently not
|
113
|
+
app.init()
|
114
|
+
|
115
|
+
error = false
|
116
|
+
#RUN! and hope it works!
|
117
|
+
PlatformImpl.runAndWait do
|
118
|
+
begin
|
119
|
+
stage = Stage.new
|
120
|
+
stage.impl_setPrimary(true)
|
121
|
+
app.start(stage)
|
122
|
+
# no countDown here because its up top... yes I know
|
123
|
+
rescue => ex
|
124
|
+
puts "Exception running Application:"
|
125
|
+
p ex
|
126
|
+
puts ex.backtrace
|
127
|
+
error = true
|
128
|
+
finished_latch.countDown # but if we fail, we need to unlatch it
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
#wait for stage exit
|
133
|
+
finished_latch.await
|
134
|
+
|
135
|
+
# call stop on the interface
|
136
|
+
app.stop() unless error
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,107 @@
|
|
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'
|
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
|
+
require 'jfxrt.jar'
|
35
|
+
rescue LoadError
|
36
|
+
puts "JavaFX runtime not found. Please install Java 7u6 or newer or set environment variable JFX_DIR to the folder that contains jfxrt.jar "
|
37
|
+
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)"
|
38
|
+
exit -1
|
39
|
+
end
|
40
|
+
|
41
|
+
module JRubyFX
|
42
|
+
# If you need JavaFX, just include this module. Its sole purpose in life is to
|
43
|
+
# import all JavaFX stuff, plus a few useful Java classes (like Void)
|
44
|
+
module FXImports
|
45
|
+
|
46
|
+
# If something is missing, just java_import it in your code.
|
47
|
+
# And then ask us to put it in this list
|
48
|
+
|
49
|
+
##
|
50
|
+
# This is the list of all classes in JavaFX that most apps should care about.
|
51
|
+
# It is a hashmaps with the leafs as arrays. Where a leaf also contains more
|
52
|
+
# packages, the hashmap key is "" (empty string). You can utilize this constant
|
53
|
+
# to save yourself some typing when adding code for most/all of the JavaFX
|
54
|
+
# classes by using either `Hash.flat_tree_inject` from jrubyfx/utils.rb or
|
55
|
+
# writing your own traversal function
|
56
|
+
#
|
57
|
+
JFX_CLASS_HIERARCHY = { :javafx => {
|
58
|
+
:animation => %w[Animation AnimationTimer FadeTransition FillTransition Interpolator KeyFrame KeyValue ParallelTransition PathTransition
|
59
|
+
PauseTransition RotateTransition ScaleTransition SequentialTransition StrokeTransition Timeline Transition TranslateTransition],
|
60
|
+
:application => ['Platform'],
|
61
|
+
:beans => {
|
62
|
+
:property => ['SimpleDoubleProperty'],
|
63
|
+
#TODO: import more
|
64
|
+
:value => ['ChangeListener']
|
65
|
+
},
|
66
|
+
:collections => ['FXCollections'],
|
67
|
+
:event => %w[Event ActionEvent EventHandler],
|
68
|
+
:fxml => ['Initializable', 'LoadException'],
|
69
|
+
:geometry => %w[HorizontalDirection HPos Insets Orientation Pos Side VerticalDirection VPos],
|
70
|
+
:scene => {
|
71
|
+
'' => %w[Group Node Parent Scene],
|
72
|
+
:canvas => ['Canvas'],
|
73
|
+
:chart => %w[Axis CategoryAxis Chart LineChart NumberAxis XYChart],
|
74
|
+
# TODO: import more of these
|
75
|
+
:control => %w[Accordion Button Cell CheckBox CheckBoxTreeItem CheckMenuItem ChoiceBox ColorPicker ComboBox ContextMenu Hyperlink
|
76
|
+
Label ListCell ListView Menu MenuBar MenuButton MenuItem Pagination PasswordField PopupControl ProgressBar ProgressIndicator RadioButton
|
77
|
+
RadioMenuItem ScrollBar ScrollPane Separator SeparatorMenuItem Slider SplitMenuButton SplitPane Tab TableView TableColumn TabPane TextArea
|
78
|
+
TextField TitledPane ToggleButton ToggleGroup ToolBar Tooltip TreeItem TreeView ContentDisplay OverrunStyle SelectionMode],
|
79
|
+
:effect => %w[Blend BlendMode Bloom BlurType BoxBlur ColorAdjust ColorInput DisplacementMap DropShadow GaussianBlur Glow ImageInput
|
80
|
+
InnerShadow Lighting MotionBlur PerspectiveTransform Reflection SepiaTone Shadow],
|
81
|
+
:image => %w[Image ImageView PixelReader PixelWriter],
|
82
|
+
:input => %w[Clipboard ContextMenuEvent DragEvent GestureEvent InputEvent InputMethodEvent KeyEvent
|
83
|
+
Mnemonic MouseDragEvent MouseEvent RotateEvent ScrollEvent SwipeEvent TouchEvent ZoomEvent],
|
84
|
+
:layout => %w[AnchorPane BorderPane ColumnConstraints FlowPane GridPane HBox Pane Priority RowConstraints StackPane TilePane VBox],
|
85
|
+
:media => %w[Media MediaPlayer MediaView],
|
86
|
+
# TODO: fill this out
|
87
|
+
:paint => %w[Color CycleMethod ImagePattern LinearGradient Paint RadialGradient Stop],
|
88
|
+
:shape => %w[Arc ArcTo ArcType Circle ClosePath CubicCurve CubicCurveTo Ellipse FillRule HLineTo Line LineTo MoveTo Path PathElement
|
89
|
+
Polygon Polyline QuadCurve QuadCurveTo Rectangle Shape StrokeLineCap StrokeLineJoin StrokeType SVGPath VLineTo],
|
90
|
+
:text => %w[Font FontPosture FontSmoothingType FontWeight Text TextAlignment TextBoundsType],
|
91
|
+
:transform => %w[Affine Rotate Scale Shear Translate],
|
92
|
+
:web => ['WebView', 'HTMLEditor']
|
93
|
+
},
|
94
|
+
:stage => %w[DirectoryChooser FileChooser Modality Popup PopupWindow Screen Stage StageStyle Window WindowEvent],
|
95
|
+
:util => ['Duration']
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
# Imports all the listed JavaFX classes
|
100
|
+
java_import *(JFX_CLASS_HIERARCHY.flat_tree_inject do |res, name, values|
|
101
|
+
name = "#{name.to_s}."
|
102
|
+
name = "" if name == "."
|
103
|
+
res.concat(values.map{|i| "#{name}#{i}"})
|
104
|
+
end)
|
105
|
+
java_import 'java.lang.Void'
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,56 @@
|
|
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
|
@@ -0,0 +1,24 @@
|
|
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 layout
|
15
|
+
end
|
16
|
+
module paint
|
17
|
+
end
|
18
|
+
module shape
|
19
|
+
end
|
20
|
+
end
|
21
|
+
module stage
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,140 @@
|
|
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
|
+
module JRubyFX
|
18
|
+
module Utils
|
19
|
+
# Contains conversion utilities to ease Ruby => JavaFX coding
|
20
|
+
module CommonConverters
|
21
|
+
java_import 'javafx.scene.paint.Color'
|
22
|
+
|
23
|
+
# argument converter method name suffix
|
24
|
+
ARG_CONVERTER_SUFFIX = '_arg_converter'
|
25
|
+
|
26
|
+
# map of snake_cased colors to JavaFX Colors
|
27
|
+
NAME_TO_COLORS = {
|
28
|
+
'darkyellow' => Color.web('0xc0c000'),
|
29
|
+
'lightmagenta' => Color.web('0xffc0ff'),
|
30
|
+
'lightred' => Color.web('0xffc0c0'),
|
31
|
+
}.merge(Color.java_class.fields.inject({}) {|final, field|
|
32
|
+
final[field.name.downcase] = field.value(nil) # TODO: what is nil supposed to be?
|
33
|
+
final
|
34
|
+
})
|
35
|
+
|
36
|
+
##
|
37
|
+
# Generate a converter for a map of supplied values.
|
38
|
+
def map_converter(map)
|
39
|
+
lambda do |value|
|
40
|
+
map.key?(value) ? map[value] : value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Generate a converter for an enum of the given class
|
46
|
+
def enum_converter(enum_class)
|
47
|
+
lambda do |value|
|
48
|
+
(JRubyFX::Utils::CommonConverters.map_enums(enum_class)[value.to_s] || value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def animation_converter_for(*prop_names)
|
53
|
+
prop_names.each do |prop_name|
|
54
|
+
self.__send__(:define_method, prop_name.to_s + "=") do |hash|
|
55
|
+
method("from_#{prop_name}=").call hash.keys[0]
|
56
|
+
method("to_#{prop_name}=").call hash.values[0]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Allows you to specify you want a converter method created for the
|
63
|
+
# specified method where each listed converter corresponds to each
|
64
|
+
# argument for that method. You can have n-arity lists for all
|
65
|
+
# matching Java overloads. This mechanism means you may not always
|
66
|
+
# be able to specify all coercions you want.
|
67
|
+
# === Examples
|
68
|
+
#
|
69
|
+
# coverter_for :new, [:none, :color]
|
70
|
+
#
|
71
|
+
# This method will define a method on the current class called
|
72
|
+
# *new_arg_converter* which will perform no argument coercion on
|
73
|
+
# the first argument and a color coercion on the second argument.
|
74
|
+
#
|
75
|
+
def converter_for(method_name, *converters)
|
76
|
+
sheep = lambda do |direct, this, *values|
|
77
|
+
converter = converters.find { |e| e.length == values.length }
|
78
|
+
|
79
|
+
# FIXME: Better error reporting on many things which can fail
|
80
|
+
i = 0
|
81
|
+
values = values.inject([]) do |s, value|
|
82
|
+
conv = converter[i]
|
83
|
+
if conv.kind_of? Proc
|
84
|
+
s << conv.call(value)
|
85
|
+
else
|
86
|
+
s << CONVERTERS[converter[i]].call(value)
|
87
|
+
end
|
88
|
+
i += 1
|
89
|
+
s
|
90
|
+
end
|
91
|
+
if direct
|
92
|
+
return this.method("set_" + method_name.to_s).call(*values)
|
93
|
+
else
|
94
|
+
return values
|
95
|
+
end
|
96
|
+
end
|
97
|
+
# define a setter for normal usage
|
98
|
+
unless method_name == :new
|
99
|
+
self.__send__(:define_method, method_name.to_s + "=") do |*values|
|
100
|
+
sheep.call(true, self, *values)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
# define a build/with usage
|
104
|
+
self.__send__(:define_method, method_name.to_s + ARG_CONVERTER_SUFFIX) do |*values|
|
105
|
+
sheep.call(false, self, *values)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Map of different kinds of known converters
|
110
|
+
CONVERTERS = {
|
111
|
+
:none => lambda { |value|
|
112
|
+
value
|
113
|
+
},
|
114
|
+
:color => lambda { |value|
|
115
|
+
new_value = NAME_TO_COLORS[value.to_s.gsub(/_/, "")]
|
116
|
+
new_value ? new_value : value
|
117
|
+
},
|
118
|
+
}
|
119
|
+
|
120
|
+
# Store enum mapping overrides
|
121
|
+
@overrides = {}
|
122
|
+
|
123
|
+
# sets the given overrides for the given class/enum
|
124
|
+
def self.set_overrides_for(enum_class,ovr)
|
125
|
+
@overrides[enum_class] = ovr
|
126
|
+
end
|
127
|
+
|
128
|
+
# Given a class, returns a hash of lowercase strings mapped to Java Enums
|
129
|
+
def self.map_enums(enum_class)
|
130
|
+
res = enum_class.java_class.enum_constants.inject({}) {|res, i| res[i.to_s.downcase] = i; res }
|
131
|
+
(@overrides[enum_class]||[]).each do |oldk, newks|
|
132
|
+
[newks].flatten.each do |newk|
|
133
|
+
res[newk.to_s] = res[oldk.to_s]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
res
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|