class Glimmer::Swing::ComponentProxy

Proxy for Swing/AWT component objects

Follows the Proxy Design Pattern

Attributes

args[R]
block[R]
keyword[R]
original[R]
parent_proxy[R]

Public Class Methods

component_class(keyword) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 74
def component_class(keyword)
  unless flyweight_component_class[keyword]
    begin
      component_class_name = component_class_symbol(keyword).to_s
      component_class = eval(component_class_name)
      unless component_class.ancestors.include?(Java::JavaAwt::Component)
        component_class = component_class_manual_entries[keyword]
        if component_class.nil?
          Glimmer::Config.logger.debug {"Class #{component_class} matching #{keyword} is not a subclass of java.awt.Component"}
          return nil
        end
      end
      component_class = Class.new(component_class) {
        attr_accessor :shape_proxies
      
        def paint(g2)
          rendering_hints = RenderingHints.new(RenderingHints::KEY_ANTIALIASING, RenderingHints::VALUE_ANTIALIAS_ON)
          g2.set_rendering_hints(rendering_hints)
          super(g2)
          shape_proxies.each do |shape_proxy|
            original_paint = g2.get_paint
            original_stroke = g2.get_stroke
            if shape_proxy.fill_color
              g2.set_paint shape_proxy.fill_paint
              g2.fill(shape_proxy)
            end
            if shape_proxy.draw_color
              g2.set_stroke shape_proxy.stroke unless shape_proxy.stroke.nil?
              g2.set_paint shape_proxy.draw_paint
              g2.draw(shape_proxy)
            end
            g2.set_paint original_paint
            g2.set_stroke original_stroke || BasicStroke.new
          end
        end
      }
      flyweight_component_class[keyword] = component_class
    rescue SyntaxError, NameError => e
      Glimmer::Config.logger.debug {e.full_message}
      nil
    rescue => e
      Glimmer::Config.logger.debug {e.full_message}
      nil
    end
  end
  flyweight_component_class[keyword]
end
component_class_manual_entries() click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 66
def component_class_manual_entries
  # add mappings for any classes (minus the namespace) that conflict with standard Ruby classes
  {
    # example:
    # 'date_time' => Java::OrgEclipseSwtWidgets::DateTime
  }
end
component_class_symbol(keyword) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 58
def component_class_symbol(keyword)
  keyword.camelcase(:upper).to_sym
end
component_proxy_class(keyword) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 44
def component_proxy_class(keyword)
  begin
    class_name = component_proxy_class_symbol(keyword)
    Glimmer::Swing::ComponentProxy.const_get(class_name)
  rescue => e
    Glimmer::Config.logger.debug e.full_message
    Glimmer::Swing::ComponentProxy
  end
end
component_proxy_class_symbol(keyword) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 54
def component_proxy_class_symbol(keyword)
  "#{keyword.camelcase(:upper)}Proxy".to_sym
end
create(parent, keyword, *args, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 40
def create(parent, keyword, *args, &block)
  component_proxy_class(keyword).new(parent, keyword, *args, &block)
end
exist?(keyword) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 36
def exist?(keyword)
  !!component_class(keyword)
end
find_listener(component_class, underscored_listener_name) click to toggle source

Looks through SWT class add***Listener methods till it finds one for which the argument is a listener class that has an event method matching underscored_listener_name

# File lib/glimmer/swing/component_proxy.rb, line 218
def self.find_listener(component_class, underscored_listener_name)
  @listeners ||= {}
  listener_key = [component_class.name, underscored_listener_name]
  unless @listeners.has_key?(listener_key)
    listener_method_name = underscored_listener_name.camelcase(:lower)
    component_class.getMethods.each do |component_add_listener_method|
      if component_add_listener_method.getName.match(/add.*Listener/)
        component_add_listener_method.getParameterTypes.each do |listener_type|
          listener_type.getMethods.each do |listener_method|
            if (listener_method.getName == listener_method_name)
              @listeners[listener_key] = [component_add_listener_method.getName, listener_class(listener_type), listener_method.getName]
              return @listeners[listener_key]
            end
          end
        end
      end
    end
    @listeners[listener_key] = []
  end
  @listeners[listener_key]
end
flyweight_component_class() click to toggle source

Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.

# File lib/glimmer/swing/component_proxy.rb, line 123
def flyweight_component_class
  @flyweight_component_class ||= {}
end
keyword(component_proxy_class) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 62
def keyword(component_proxy_class)
  component_proxy_class.to_s.underscore.sub(/_proxy$/, '')
end
listener_class(listener_type) click to toggle source

Returns a Ruby class that implements listener type Java interface with ability to easily install a block that gets called upon calling a listener event method

# File lib/glimmer/swing/component_proxy.rb, line 242
def self.listener_class(listener_type)
  @listener_classes ||= {}
  listener_class_key = listener_type.name
  unless @listener_classes.has_key?(listener_class_key)
    @listener_classes[listener_class_key] = Class.new(Object).tap do |listener_class|
      listener_class.send :include, (eval listener_type.name.sub("interface", ""))
      listener_class.define_method('initialize') do |event_method_block_mapping|
        @event_method_block_mapping = event_method_block_mapping
      end
      listener_type.getMethods.each do |event_method|
        listener_class.define_method(event_method.getName) do |*args|
          @event_method_block_mapping[event_method.getName]&.call(*args)
        end
      end
    end
  end
  @listener_classes[listener_class_key]
end
new(parent, keyword, *args, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 130
def initialize(parent, keyword, *args, &block)
  @parent_proxy = parent
  @keyword = keyword
  @args = args
  @block = block
  build
  post_add_content if @block.nil?
end
paint(g2) click to toggle source
Calls superclass method
# File lib/glimmer/swing/component_proxy.rb, line 89
def paint(g2)
  rendering_hints = RenderingHints.new(RenderingHints::KEY_ANTIALIASING, RenderingHints::VALUE_ANTIALIAS_ON)
  g2.set_rendering_hints(rendering_hints)
  super(g2)
  shape_proxies.each do |shape_proxy|
    original_paint = g2.get_paint
    original_stroke = g2.get_stroke
    if shape_proxy.fill_color
      g2.set_paint shape_proxy.fill_paint
      g2.fill(shape_proxy)
    end
    if shape_proxy.draw_color
      g2.set_stroke shape_proxy.stroke unless shape_proxy.stroke.nil?
      g2.set_paint shape_proxy.draw_paint
      g2.draw(shape_proxy)
    end
    g2.set_paint original_paint
    g2.set_stroke original_stroke || BasicStroke.new
  end
end

Public Instance Methods

add_listener(underscored_listener_name, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 207
def add_listener(underscored_listener_name, &block)
  component_add_listener_method, listener_class, listener_method = self.class.find_listener(@original.getClass, underscored_listener_name)
  component_listener_proxy = nil
  listener = listener_class.new(listener_method => block)
  @original.send(component_add_listener_method, listener)
  ComponentListenerProxy.new(component: @original, listener: listener, component_add_listener_method: component_add_listener_method, listener_class: listener_class, listener_method: listener_method)
end
can_add_listener?(underscored_listener_name) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 203
def can_add_listener?(underscored_listener_name)
  @original && !self.class.find_listener(@original.getClass, underscored_listener_name).empty?
end
can_handle_observation_request?(observation_request) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 186
def can_handle_observation_request?(observation_request)
  if observation_request.start_with?('on_')
    event = observation_request.sub(/^on_/, '')
    can_add_listener?(event)
  end
end
content(&block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 182
def content(&block)
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Swing::ComponentExpression.new, @keyword, &block)
end
handle_observation_request(observation_request, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 193
def handle_observation_request(observation_request, &block)
  if observation_request.start_with?('on_')
    event = observation_request.sub(/^on_/, '')
    if can_add_listener?(event)
      event = observation_request.sub(/^on_/, '')
      add_listener(event, &block)
    end
  end
end
method_missing(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/swing/component_proxy.rb, line 166
def method_missing(method_name, *args, &block)
  if respond_to?("#{method_name}=", true) && !args.empty?
    send("#{method_name}=", *args)
  elsif @original.respond_to?("set_#{method_name}", true) && !args.empty?
    send_to_original("set_#{method_name}", *args, &block)
  elsif @original.respond_to?(method_name, true)
    send_to_original(method_name, *args, &block)
  else
    super
  end
end
post_add_content() click to toggle source

Subclasses may override to perform post add_content work (normally must call super)

# File lib/glimmer/swing/component_proxy.rb, line 140
def post_add_content
  @parent_proxy&.post_initialize_child(self)
end
post_initialize_child(child) click to toggle source

Subclasses may override to perform post initialization work on an added child (normally must also call super)

# File lib/glimmer/swing/component_proxy.rb, line 145
def post_initialize_child(child)
  if child.is_a?(ComponentProxy)
    add(child)
  elsif child.is_a?(ShapeProxy)
    shape_proxies << child
  end
end
respond_to?(method_name, *args, &block) click to toggle source
Calls superclass method
# File lib/glimmer/swing/component_proxy.rb, line 157
def respond_to?(method_name, *args, &block)
  respond_to_original?(method_name, *args, &block) ||
    super(method_name, true)
end
respond_to_original?(method_name, *args, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 162
def respond_to_original?(method_name, *args, &block)
  @original.respond_to?(method_name, true) || @original.respond_to?("set_#{method_name}", true)
end
send_to_original(method_name, *args, &block) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 178
def send_to_original(method_name, *args, &block)
  @original.send(method_name, *normalize_args(args), &block)
end
shape_proxies() click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 153
def shape_proxies
  @shape_proxies ||= []
end

Private Instance Methods

build() click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 263
def build
  @original = ComponentProxy.component_class(keyword).new(*normalize_args(args))
  @original.shape_proxies = shape_proxies
end
normalize_args(args) click to toggle source
# File lib/glimmer/swing/component_proxy.rb, line 268
def normalize_args(args)
  args.map do |arg|
    arg.is_a?(ComponentProxy) ? arg.original : arg
  end
end