Skip to content
Patrick Plenefisch edited this page Aug 2, 2013 · 3 revisions

JavaFX extensions

This page lists all the JRubyFX-specific extensions for JavaFX. Almost all JavaFX code should work identically in Ruby, but there are provided for convenience and to make JavaFX look more rubyish. This does not go over JRuby extensions, like jobj.var = foo mapping to jobj.setVar(foo). See the JRuby wiki for those. Basic knowledge of Ruby is assumed

General

The Number class provides sec, ms, min, hr, and hrs methods that return JavaFX Durations. They are most likely to be used in animations:

timeline do
  animate foo_property, 0.sec => 5.sec, from => to
end

ObservableValues, ObservableLists, and ObservableMaps all add a new method add_change_listener that registers the provided block via addListener(*ChangeListener) without warnings. ObservableValue's also provide a short version when only one block argument is given (arity 1) and gives the new value only:

foo_property.add_change_listener {|new| puts "Foo just changed to #{new}" }

add_invalidation_listener is also provided for addListener(InvalidationListener)

All classes are augmented with property_accessor, property_reader, and property_writer. These methods function similarly to attr_* functions, except property_* methods get and set the observable value. Note these do not initialize the property. You must do that yourself before you use them.

class FooClass
  include JRubyFX
  property_accessor :bar

  def initialize
    @bar = SimpleDoubleProperty.new(this, "bar", 5)
  end
end

foo = FooClass.new
foo.bar #=> 5
foo.bar = 6
foo.bar_property.value #=> 6
foo.bar #=> 6

If you want to refer to a resource, its best to use resource_root and resource_url. resource_root defines the path that all resource urls gotten via resource_url are relative to, when in raw mode and when packed in a jar:

# resource_root(type, local_path, jar_path)
resource_root :images, File.join(File.dirname(__FILE__), "res", "img"), "res/img"
resource_root :css, "/example/path", "jar/path"

# ...
stage.icons.add image(resource_url(:images, "16x16-icon.png").to_s)
resource_url(:css, "my_css.css").to_s # "file:/example/path/my_css.css" or "jar:file:/path/to/jar!/jar/path/my_css.css"

DSL methods: with, build, and friends TODO: expand

UI via FXML

fxml_root is similar to resource_root, but without a type (just two arguments), and it effects fxml

JRubyFX::Controller#fxml is provided to specify the default fxml file (relative to fxml_root) for the class. javafx.stage.Stage#fxml, javafx.stage.Stage#fxml=, and JRubyFX::Controller::load_into (deprecated) are all synonyms and load the given fxml file name or class (using default fxml file), but are not for custom controls. JRubyFX::Controller#load_fxml loads an arbitrary fxml file once inside a controller, usually for custom controls with multiple ui's. Example:

require 'jrubyfx'
fxml_root File.dirname(__FILE__) # all fxml files are relative to the dir that this file is in

class DemoApp < JRubyFX::Application
  def start(stage)
    stage.fxml = "fxml file with fx:controller set or no controller needed.fxml"
    stage.fxml = DemoController
    stage.fxml DemoController # exact same as line above
    # this form can take other arguments
    stage.fxml DemoController, initialize: [:hey, 4.2], width: 600, height: 800, fill: :green
    # this form can still take a string
    stage.fxml "my fxml file.fxml"
    stage.show
  end
end

class DemoController
  include JRubyFX::Controller # must include this to be a controller
  fxml "layout.fxml" # loaded if using `stage.fxml DemoController` form

  def initialize(hey, four_dot_two)
    p [@stage, @scene, @location, @resources] # all these variables are provided for normal fxml controllers
    DemoControl.new # making custom controls is easy
  end
end

class DemoControl < Java::javafx.scene.layout.Pane # custom controls must inherit from something
  include JRubyFX::Controller
  fxml "control.fxml" # must use fx:root type="superclass type"

  def initialize
    # if you need to change the fxml file loaded
    load_fxml "different.fxml"
  end
end

DemoApp.launch

Also for FXML custom controls are fxml_accessor and fxml_raw_accessor which enable binding to properties in the custom control class from fxml. Note that the name must be camel case, but snake case versions are also generated:

class MyControl < Java::javafx.scene.layout.Pane
  include JRubyFX::Controller
  fxml_accessor :myString Java::javafx.beans.property.SimpleStringProperty # no need to specify type
  fxml_accessor :myPaint Java::javafx.beans.property.SimpleObjectProperty, Java::javafx.scene.paint.Paint

  # ...

  my_paint_property.bind(another_property)
  self.my_string = "some_string"
  my_string # => "some string"
end

FXML for above example:

<fx:root fx:id="myRoot" ... >
  ...
   <Button text="${myRoot.myString}" ... />

UI via code (aka the DSL)

Timeline#animate is provided for simpler animation api. Syntax:

timeline do #
  animate foo_property, 0.sec => 5.sec, from_value => to_value
  animate foo_property, 0.sec => [1.sec, 2.sec, 5.sec], from_value => [point_value, point_value, to_value]
end

All Events support removing the set from their names. Example (both are the same):

button.set_on_action { ... }
button.on_action { ... }

All enums and most constants support symbol values:

scene.fill = :green

javafx::stage::FileChooser#add_extension_filter and javafx::stage::FileChooser#add_extension_filters support easier ways to add extension filters to file choosers, and will auto-detect file extensions

TODO: more

Clone this wiki locally