Class: Glimmer::Swing::ComponentProxy

Inherits:
Object
  • Object
show all
Extended by:
Packages
Includes:
Packages
Defined in:
lib/glimmer/swing/component_proxy.rb,
lib/glimmer/swing/component_proxy/j_frame_proxy.rb

Overview

Proxy for Swing/AWT component objects

Follows the Proxy Design Pattern

Direct Known Subclasses

JFrameProxy

Defined Under Namespace

Classes: JFrameProxy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Packages

included

Constructor Details

#initialize(parent, keyword, *args, &block) ⇒ ComponentProxy

Returns a new instance of ComponentProxy.



130
131
132
133
134
135
136
137
# 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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
# 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

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



128
129
130
# File 'lib/glimmer/swing/component_proxy.rb', line 128

def args
  @args
end

#blockObject (readonly)

Returns the value of attribute block.



128
129
130
# File 'lib/glimmer/swing/component_proxy.rb', line 128

def block
  @block
end

#keywordObject (readonly)

Returns the value of attribute keyword.



128
129
130
# File 'lib/glimmer/swing/component_proxy.rb', line 128

def keyword
  @keyword
end

#originalObject (readonly)

Returns the value of attribute original.



128
129
130
# File 'lib/glimmer/swing/component_proxy.rb', line 128

def original
  @original
end

#parent_proxyObject (readonly)

Returns the value of attribute parent_proxy.



128
129
130
# File 'lib/glimmer/swing/component_proxy.rb', line 128

def parent_proxy
  @parent_proxy
end

Class Method Details

.component_class(keyword) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 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_entriesObject



66
67
68
69
70
71
72
# 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) ⇒ Object



58
59
60
# File 'lib/glimmer/swing/component_proxy.rb', line 58

def component_class_symbol(keyword)
  keyword.camelcase(:upper).to_sym
end

.component_proxy_class(keyword) ⇒ Object



44
45
46
47
48
49
50
51
52
# 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) ⇒ Object



54
55
56
# 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) ⇒ Object



40
41
42
# 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) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/glimmer/swing/component_proxy.rb', line 36

def exist?(keyword)
  !!component_class(keyword)
end

.find_listener(component_class, underscored_listener_name) ⇒ Object

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



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# 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_classObject

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



123
124
125
# File 'lib/glimmer/swing/component_proxy.rb', line 123

def flyweight_component_class
  @flyweight_component_class ||= {}
end

.keyword(component_proxy_class) ⇒ Object



62
63
64
# 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) ⇒ Object

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



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# 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

Instance Method Details

#add_listener(underscored_listener_name, &block) ⇒ Object



207
208
209
210
211
212
213
# 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) ⇒ Boolean

Returns:

  • (Boolean)


203
204
205
# 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) ⇒ Boolean

Returns:

  • (Boolean)


186
187
188
189
190
191
# 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) ⇒ Object



182
183
184
# 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) ⇒ Object



193
194
195
196
197
198
199
200
201
# 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

#post_add_contentObject

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



140
141
142
# File 'lib/glimmer/swing/component_proxy.rb', line 140

def post_add_content
  @parent_proxy&.post_initialize_child(self)
end

#post_initialize_child(child) ⇒ Object

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



145
146
147
148
149
150
151
# 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) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
160
# 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) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
# 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) ⇒ Object



178
179
180
# 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_proxiesObject



153
154
155
# File 'lib/glimmer/swing/component_proxy.rb', line 153

def shape_proxies
  @shape_proxies ||= []
end