Module: JRubyFX::Controller

Includes:
DSL, FXImports
Defined in:
lib/jrubyfx/controller.rb

Overview

Inherit from this class for FXML controllers

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

DEFAULT_SETTINGS =
{
  width: -1,
  height: -1,
  fill: :white,
  depth_buffer: false,
  root_dir: nil,
  initialized: nil
}

Constants included from FXImports

FXImports::JFX_CLASS_HIERARCHY, FXImports::LOCAL_NAME_MAP

Constants included from DSL

DSL::NAME_TO_CLASSES, DSL::NAME_TO_CLASS_NAME

Constants included from JRubyFX

VERSION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FXImports

#const_missing

Methods included from DSL

compile_dsl, load_dsl, #logical_lookup, #method_missing, #self_test_lookup, write_color_method_converter, write_enum_converter, write_enum_method_converter, write_event_method

Methods included from JRubyFX

#build, load_fx, #run_later, #with

Methods included from Utils::CommonUtils

#attempt_conversion, #populate_properties, #split_args_from_properties

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class JRubyFX::DSL

Instance Attribute Details

#scene=(value) ⇒ Object (writeonly)

Controllers usually need access to the stage.


69
70
71
# File 'lib/jrubyfx/controller.rb', line 69

def scene=(value)
  @scene = value
end

#stage=(value) ⇒ Object (writeonly)

Controllers usually need access to the stage.


69
70
71
# File 'lib/jrubyfx/controller.rb', line 69

def stage=(value)
  @stage = value
end

Class Method Details

.get_fxml_loader(filename, controller = nil, root_dir = nil) ⇒ Object

call-seq:

get_fxml_loader(filename) => FXMLLoader
get_fxml_loader(filename, controller_instance) => FXMLLoader
get_fxml_loader(filename, controller_instance, root_dir) => FXMLLoader

Load a FXML file given a filename and a controller and return the loader root_dir is a directory that the file is relative to.

Examples

root = JRubyFX::Controller.get_fxml_loader("Demo.fxml").load

root = JRubyFX::Controller.get_fxml_loader("Demo.fxml", my_controller).load

Equivalent Java

Parent root = FXMLLoader.load(getClass().getResource("Demo.fxml"));

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/jrubyfx/controller.rb', line 339

def self.get_fxml_loader(filename, controller = nil, root_dir = nil)
  fx = FxmlLoader.new
  fx.location =
  if JRubyFX::Application.in_jar?
    # If we are in a jar file, use the class loader to get the file from the jar (like java)
    # TODO: should just be able to use URLs
    
    # According to how class loader works, the correct path for a file inside a jar is NOT "/folder/file.fxml" 
    # but "folder/file.fxml" (without starting "/" or ".", which would both make the path to be seen as a filesystem 
    # reference) so we assume that if root_dir is set to "" or to any other path not starting with "." or "/" then 
    # we want to point to a folder inside the jar, otherwise to a filesystem's one. According to this we format and 
    # feed the right path to the class loader.
    
    if root_dir == "" or not ["/", "."].include? (root_dir[0])
      JRuby.runtime.jruby_class_loader.get_resource filename
    else
      JRuby.runtime.jruby_class_loader.get_resource File.join(root_dir, filename)
    end
  else
    root_dir ||= fxml_root
    # If we are in the normal filesystem, create a file url path relative to relative_to or this file
    URL.new "file:#{File.join root_dir, filename}"
  end
  # we must set this here for JFX to call our events
  fx.controller = controller
  fx
end

.included(base) ⇒ Object


71
72
73
74
75
76
77
# File 'lib/jrubyfx/controller.rb', line 71

def self.included(base)
  base.extend(ClassMethods)
  base.extend(JRubyFX::FXMLClassUtils) if defined? JRubyFX::FXMLClassUtils
  base.extend(JRubyFX::FXImports)
  # register ourselves as a control. overridable with custom_fxml_control
  register_type base if base.is_a? Class
end

.load_fxml_only(filename, stage, settings = {}) ⇒ Object

Loads a controller-less file


300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/jrubyfx/controller.rb', line 300

def self.load_fxml_only(filename, stage, settings={})
  # Inherit from default settings
  settings = DEFAULT_SETTINGS.merge({root_dir: fxml_root,
      filename: filename}).merge settings

  # load the FXML file
  root = Controller.get_fxml_loader(settings[:filename], nil, settings[:root_dir]).load

  # TODO: de-duplicate this code

  # Unless the FXML root node is a scene, wrap that node in a scene
  if root.is_a? Scene
    scene = root
  else
    scene = Scene.new root, settings[:width], settings[:height], settings[:depth_buffer]
    scene.fill = settings[:fill]
  end

  # set the controller and stage scene
  stage.scene = scene
end

Instance Method Details

#css(css_selector) ⇒ Object

return an array of matched nodes


295
296
297
# File 'lib/jrubyfx/controller.rb', line 295

def css(css_selector)
  @scene.get_root.lookup_all(css_selector).to_a
end

#find(css_selector) ⇒ Object

return first matched node or nil


283
284
285
# File 'lib/jrubyfx/controller.rb', line 283

def find(css_selector)
  @scene.lookup(css_selector)
end

#find!(css_selector) ⇒ Object

Return first matched node or throw exception


288
289
290
291
292
# File 'lib/jrubyfx/controller.rb', line 288

def find!(css_selector)
  res = find(css_selector)
  raise "Selector(#{css_selector}) returned no results!" unless res
  res
end

#finish_initialization(*args, &block) ⇒ Object


263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/jrubyfx/controller.rb', line 263

def finish_initialization(*args, &block)
  @nodes_by_id = {}

  # custom controls are their own scene
  self.scene = self unless @scene

  # Everything is ready, call initialize
  if private_methods.include? :initialize
    self.send :initialize, *args, &block
  end

  #return ourself
  self
end

#initialize_controller(options = {}, *args, &block) ⇒ Object

Initialize all controllers


236
237
238
239
240
241
242
243
244
245
# File 'lib/jrubyfx/controller.rb', line 236

def initialize_controller(options={}, *args, &block)

  # JRuby complains loudly (probably broken behavior) if we don't call the ctor
  java_ctor self.class.superclass.instance_method(:initialize).bind(self), args

  # load the FXML file with the current control as the root
  load_fxml options[:filename], options[:root_dir]

  finish_initialization *args, &block
end

#java_ctor(ctor, initialize_arguments) ⇒ Object

default java ctor, override for arguments


231
232
233
# File 'lib/jrubyfx/controller.rb', line 231

def java_ctor(ctor, initialize_arguments)
  ctor.call
end

#load_fxml(filename, root_dir = nil) ⇒ Object


257
258
259
260
261
# File 'lib/jrubyfx/controller.rb', line 257

def load_fxml(filename, root_dir=nil)
  fx = Controller.get_fxml_loader(filename, self, root_dir || @fxml_root_dir || fxml_root)
  fx.root = self
  fx.load
end

#pre_initialize_controller(options = {}) ⇒ Object

Initialize all controllers


248
249
250
251
252
253
254
255
# File 'lib/jrubyfx/controller.rb', line 248

def pre_initialize_controller(options={})

  # JRuby complains loudly (probably broken behavior) if we don't call the ctor
  java_ctor self.class.superclass.instance_method(:initialize).bind(self), [] #TODO: do we need to call this now with []?

  # load the FXML file with the current control as the root
  load_fxml options[:filename], options[:root_dir]
end