glimmer-dsl-swt 0.6.2 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/VERSION +1 -1
  4. data/bin/girb +1 -1
  5. data/bin/glimmer +5 -1
  6. data/icons/scaffold_app.png +0 -0
  7. data/lib/ext/glimmer/config.rb +13 -1
  8. data/lib/glimmer-dsl-swt.rb +5 -9
  9. data/lib/glimmer/Rakefile +5 -0
  10. data/lib/glimmer/data_binding/table_items_binding.rb +4 -1
  11. data/lib/glimmer/dsl/swt/message_box_expression.rb +9 -1
  12. data/lib/glimmer/dsl/swt/widget_expression.rb +1 -7
  13. data/lib/glimmer/launcher.rb +59 -20
  14. data/lib/glimmer/package.rb +26 -9
  15. data/lib/glimmer/rake_task.rb +115 -5
  16. data/lib/glimmer/scaffold.rb +66 -33
  17. data/lib/glimmer/swt/display_proxy.rb +13 -2
  18. data/lib/glimmer/swt/message_box_proxy.rb +23 -5
  19. data/lib/glimmer/swt/shell_proxy.rb +0 -1
  20. data/lib/glimmer/swt/table_proxy.rb +60 -2
  21. data/lib/glimmer/swt/widget_proxy.rb +44 -19
  22. data/samples/elaborate/contact_manager.rb +121 -0
  23. data/samples/elaborate/contact_manager/contact.rb +11 -0
  24. data/samples/elaborate/contact_manager/contact_manager_presenter.rb +26 -0
  25. data/samples/elaborate/contact_manager/contact_repository.rb +244 -0
  26. data/samples/elaborate/login.rb +108 -0
  27. data/samples/elaborate/tic_tac_toe.rb +55 -0
  28. data/samples/elaborate/tic_tac_toe/board.rb +124 -0
  29. data/samples/elaborate/tic_tac_toe/cell.rb +27 -0
  30. data/samples/elaborate/user_profile.rb +55 -0
  31. data/samples/hello/hello_browser.rb +8 -0
  32. data/samples/hello/hello_combo.rb +38 -0
  33. data/samples/hello/hello_computed.rb +69 -0
  34. data/samples/hello/hello_computed/contact.rb +21 -0
  35. data/samples/hello/hello_drag_and_drop.rb +29 -0
  36. data/samples/hello/hello_list_multi_selection.rb +48 -0
  37. data/samples/hello/hello_list_single_selection.rb +37 -0
  38. data/samples/hello/hello_menu_bar.rb +64 -0
  39. data/samples/hello/hello_message_box.rb +15 -0
  40. data/samples/hello/hello_pop_up_context_menu.rb +36 -0
  41. data/samples/hello/hello_tab.rb +24 -0
  42. data/samples/hello/hello_world.rb +8 -0
  43. metadata +65 -8
@@ -4,6 +4,8 @@ require 'facets'
4
4
 
5
5
  # TODO refactor to nest under RakeTask namespace
6
6
 
7
+ MAIN_OBJECT = self
8
+
7
9
  class Scaffold
8
10
  class << self
9
11
  include FileUtils
@@ -73,7 +75,8 @@ class Scaffold
73
75
 
74
76
  # Glimmer
75
77
  dist
76
- packages
78
+ packages
79
+ vendor/jars
77
80
  MULTI_LINE_STRING
78
81
 
79
82
  GEMFILE = <<~MULTI_LINE_STRING
@@ -109,7 +112,6 @@ class Scaffold
109
112
  MULTI_LINE_STRING
110
113
 
111
114
  def app(app_name)
112
- return puts('Namespace is required! Usage: glimmer scaffold:custom_shell_gem[custom_shell_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
113
115
  gem_name = file_name(app_name)
114
116
  gem_summary = human_name(app_name)
115
117
  system "jruby -r git-glimmer -S jeweler --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
@@ -127,17 +129,22 @@ class Scaffold
127
129
  mkdir 'app/models'
128
130
  mkdir 'app/views'
129
131
  custom_shell('AppView', current_dir_name, :app)
130
- if OS::Underlying.windows?
131
- mkdir_p 'package/windows'
132
- icon_file = "package/windows/#{human_name(app_name)}.ico"
133
- cp File.expand_path('../../../icons/scaffold_app.ico', __FILE__), icon_file
134
- puts "Created #{current_dir_name}/#{icon_file}"
135
- elsif OS.mac?
136
- mkdir_p 'package/macosx'
137
- icon_file = "package/macosx/#{human_name(app_name)}.icns"
138
- cp File.expand_path('../../../icons/scaffold_app.icns', __FILE__), icon_file
139
- puts "Created #{current_dir_name}/#{icon_file}"
140
- end
132
+
133
+ mkdir_p 'package/windows'
134
+ icon_file = "package/windows/#{human_name(app_name)}.ico"
135
+ cp File.expand_path('../../../icons/scaffold_app.ico', __FILE__), icon_file
136
+ puts "Created #{current_dir_name}/#{icon_file}"
137
+
138
+ mkdir_p 'package/macosx'
139
+ icon_file = "package/macosx/#{human_name(app_name)}.icns"
140
+ cp File.expand_path('../../../icons/scaffold_app.icns', __FILE__), icon_file
141
+ puts "Created #{current_dir_name}/#{icon_file}"
142
+
143
+ mkdir_p 'package/linux'
144
+ icon_file = "package/linux/#{human_name(app_name)}.png"
145
+ cp File.expand_path('../../../icons/scaffold_app.png', __FILE__), icon_file
146
+ puts "Created #{current_dir_name}/#{icon_file}"
147
+
141
148
  mkdir 'bin'
142
149
  write "bin/#{file_name(app_name)}", app_bin_file(app_name)
143
150
  write 'spec/spec_helper.rb', spec_helper_file
@@ -147,9 +154,12 @@ class Scaffold
147
154
  system "\"packages/bundles/#{human_name(app_name)}/#{human_name(app_name)}.exe\""
148
155
  else
149
156
  system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n glimmer package\n'"
150
- system "open packages/bundles/#{human_name(app_name).gsub(' ', '\ ')}.app" if OS.mac?
157
+ if OS.mac?
158
+ system "open packages/bundles/#{human_name(app_name).gsub(' ', '\ ')}.app"
159
+ else
160
+ system "glimmer bin/#{file_name(app_name)}"
161
+ end
151
162
  end
152
- # TODO generate rspec test suite
153
163
  end
154
164
 
155
165
  def custom_shell(custom_shell_name, namespace, shell_type = nil)
@@ -169,13 +179,20 @@ class Scaffold
169
179
  end
170
180
 
171
181
  def custom_shell_gem(custom_shell_name, namespace)
172
- return puts('Namespace is required! Usage: glimmer scaffold:custom_shell_gem[custom_shell_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
173
182
  gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
174
183
  gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
184
+ begin
185
+ custom_shell_keyword = dsl_widget_name(custom_shell_name)
186
+ MAIN_OBJECT.method(custom_shell_keyword)
187
+ return puts("CustomShell keyword `#{custom_shell_keyword}` is unavailable (occupied by a built-in Ruby method)! Please pick a different name.")
188
+ rescue NameError
189
+ # No Op (keyword is not taken by a built in Ruby method)
190
+ end
175
191
  if namespace
176
192
  gem_name += "-#{compact_name(namespace)}"
177
193
  gem_summary += " (#{human_name(namespace)})"
178
194
  else
195
+ return puts('Namespace is required! Usage: glimmer scaffold:gem:customshell[name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
179
196
  namespace = 'glimmer'
180
197
  end
181
198
  system "jruby -r git-glimmer -S jeweler --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
@@ -194,24 +211,33 @@ class Scaffold
194
211
  write "bin/#{file_name(custom_shell_name)}", gem_bin_command_file(gem_name)
195
212
  FileUtils.chmod 0755, "bin/#{file_name(custom_shell_name)}"
196
213
  write 'spec/spec_helper.rb', spec_helper_file
197
- if OS::Underlying.windows?
198
- mkdir_p 'package/windows'
199
- icon_file = "package/windows/#{human_name(custom_shell_name)}.ico"
200
- cp File.expand_path('../../../icons/scaffold_app.ico', __FILE__), icon_file
201
- puts "Created #{current_dir_name}/#{icon_file}"
202
- elsif OS.mac?
203
- mkdir_p 'package/macosx'
204
- icon_file = "package/macosx/#{human_name(custom_shell_name)}.icns"
205
- cp File.expand_path('../../../icons/scaffold_app.icns', __FILE__), icon_file
206
- puts "Created #{current_dir_name}/#{icon_file}"
207
- end
214
+
215
+ mkdir_p 'package/windows'
216
+ icon_file = "package/windows/#{human_name(custom_shell_name)}.ico"
217
+ cp File.expand_path('../../../icons/scaffold_app.ico', __FILE__), icon_file
218
+ puts "Created #{current_dir_name}/#{icon_file}"
219
+
220
+ mkdir_p 'package/macosx'
221
+ icon_file = "package/macosx/#{human_name(custom_shell_name)}.icns"
222
+ cp File.expand_path('../../../icons/scaffold_app.icns', __FILE__), icon_file
223
+ puts "Created #{current_dir_name}/#{icon_file}"
224
+
225
+ mkdir_p 'package/linux'
226
+ icon_file = "package/linux/#{human_name(custom_shell_name)}.png"
227
+ cp File.expand_path('../../../icons/scaffold_app.png', __FILE__), icon_file
228
+ puts "Created #{current_dir_name}/#{icon_file}"
229
+
208
230
  if OS.windows?
209
231
  system "bundle"
210
232
  system "glimmer package[image]"
211
233
  system "\"packages/bundles/#{human_name(custom_shell_name)}/#{human_name(custom_shell_name)}.exe\""
212
234
  else
213
235
  system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n glimmer package\n'"
214
- system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
236
+ if OS.mac?
237
+ system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
238
+ else
239
+ system "bin/#{file_name(custom_shell_name)}"
240
+ end
215
241
  end
216
242
  puts "Finished creating #{gem_name} Ruby gem."
217
243
  puts 'Edit Rakefile to configure gem details.'
@@ -333,18 +359,25 @@ class Scaffold
333
359
  end
334
360
 
335
361
  def gem_bin_file(gem_name, custom_shell_name, namespace)
362
+ # TODO change this so that it does not mix Glimmer unto the main object
336
363
  <<~MULTI_LINE_STRING
337
364
  require_relative '../lib/#{gem_name}'
338
365
 
339
- include Glimmer
366
+ class #{class_name(custom_shell_name)}App
367
+ include Glimmer
368
+
369
+ def open
370
+ #{dsl_widget_name(custom_shell_name)}.open
371
+ end
372
+ end
340
373
 
341
- #{dsl_widget_name(custom_shell_name)}.open
374
+ #{class_name(custom_shell_name)}App.new.open
342
375
  MULTI_LINE_STRING
343
376
  end
344
377
 
345
378
  def gem_bin_command_file(gem_name)
346
379
  <<~MULTI_LINE_STRING
347
- #!/usr/bin/env ruby
380
+ #!/usr/bin/env jruby
348
381
 
349
382
  require 'glimmer/launcher'
350
383
 
@@ -377,7 +410,7 @@ class Scaffold
377
410
  " -name '#{human_name(custom_shell_name)}'" +
378
411
  " -title '#{human_name(custom_shell_name)}'" +
379
412
  " -Bmac.CFBundleName='#{human_name(custom_shell_name)}'" +
380
- " -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name)}'"
413
+ " -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).capitalize}'"
381
414
  # " -BlicenseType=" +
382
415
  # " -Bmac.category=" +
383
416
  # " -Bmac.signing-key-developer-id-app="
@@ -489,7 +522,7 @@ class Scaffold
489
522
  menu {
490
523
  text '&File'
491
524
  menu_item {
492
- text 'Preferences...'
525
+ text '&Preferences...'
493
526
  on_widget_selected {
494
527
  display_preferences_dialog
495
528
  }
@@ -35,16 +35,26 @@ module Glimmer
35
35
  @swt_display = Display.new(*args)
36
36
  @swt_display.set_data('proxy', self)
37
37
  end
38
+
39
+ def content(&block)
40
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::DisplayExpression.new, &block)
41
+ end
38
42
 
39
43
  def method_missing(method, *args, &block)
40
- swt_display.send(method, *args, &block)
44
+ if can_handle_observation_request?(method)
45
+ handle_observation_request(method, &block)
46
+ else
47
+ swt_display.send(method, *args, &block)
48
+ end
41
49
  rescue => e
42
50
  Glimmer::Config.logger.debug {"Neither DisplayProxy nor #{swt_display.class.name} can handle the method ##{method}"}
43
51
  super
44
52
  end
45
53
 
46
54
  def respond_to?(method, *args, &block)
47
- super || swt_display.respond_to?(method, *args, &block)
55
+ super ||
56
+ can_handle_observation_request?(method) ||
57
+ swt_display.respond_to?(method, *args, &block)
48
58
  end
49
59
 
50
60
  def can_handle_observation_request?(observation_request)
@@ -61,6 +71,7 @@ module Glimmer
61
71
  end
62
72
 
63
73
  def handle_observation_request(observation_request, &block)
74
+ observation_request = observation_request.to_s
64
75
  if observation_request.start_with?('on_swt_')
65
76
  constant_name = observation_request.sub(/^on_swt_/, '')
66
77
  add_swt_event_listener(constant_name, &block)
@@ -14,16 +14,22 @@ module Glimmer
14
14
  attr_reader :swt_widget
15
15
 
16
16
  def initialize(parent, style)
17
- parent = parent.swt_widget if parent.respond_to?(:swt_widget) && parent.swt_widget.is_a?(Shell)
18
- @temporary_parent = parent = Glimmer::SWT::ShellProxy.new.swt_widget if parent.nil?
19
- @swt_widget = MessageBox.new(parent, style)
17
+ if parent.nil?
18
+ @temporary_parent = parent = Glimmer::SWT::ShellProxy.new.swt_widget
19
+ end
20
+ @swt_widget = MessageBox.new(parent, style)
20
21
  end
21
22
 
22
23
  def open
23
- @swt_widget.open
24
- @temporary_parent&.dispose
24
+ @swt_widget.open.tap do |result|
25
+ @temporary_parent&.dispose
26
+ end
25
27
  end
26
28
 
29
+ def content(&block)
30
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::MessageBoxExpression.new, &block)
31
+ end
32
+
27
33
  # TODO refactor the following methods to put in a JavaBean mixin or somethin (perhaps contribute to OSS project too)
28
34
 
29
35
  def attribute_setter(attribute_name)
@@ -44,6 +50,18 @@ module Glimmer
44
50
 
45
51
  def get_attribute(attribute_name)
46
52
  @swt_widget.send(attribute_getter(attribute_name))
53
+ end
54
+
55
+ def method_missing(method, *args, &block)
56
+ swt_widget.send(method, *args, &block)
57
+ rescue => e
58
+ Glimmer::Config.logger.debug {"Neither MessageBoxProxy nor #{swt_widget.class.name} can handle the method ##{method}"}
59
+ super
60
+ end
61
+
62
+ def respond_to?(method, *args, &block)
63
+ super ||
64
+ swt_widget.respond_to?(method, *args, &block)
47
65
  end
48
66
  end
49
67
  end
@@ -1,7 +1,6 @@
1
1
  require 'glimmer/swt/swt_proxy'
2
2
  require 'glimmer/swt/widget_proxy'
3
3
  require 'glimmer/swt/display_proxy'
4
- require 'glimmer/swt/swt_proxy'
5
4
 
6
5
  module Glimmer
7
6
  module SWT
@@ -85,7 +85,55 @@ module Glimmer
85
85
  }
86
86
  table_editor_widget_proxy
87
87
  end,
88
- }
88
+ },
89
+ checkbox: {
90
+ widget_value_property: :selection,
91
+ editor_gui: lambda do |args, model, property, table_proxy|
92
+ first_time = true
93
+ table_proxy.table_editor.minimumHeight = 25
94
+ checkbox(*args) {
95
+ selection model.send(property)
96
+ focus true
97
+ on_widget_selected {
98
+ table_proxy.finish_edit!
99
+ }
100
+ on_focus_lost {
101
+ table_proxy.finish_edit!
102
+ }
103
+ on_key_pressed { |key_event|
104
+ if key_event.keyCode == swt(:cr)
105
+ table_proxy.finish_edit!
106
+ elsif key_event.keyCode == swt(:esc)
107
+ table_proxy.cancel_edit!
108
+ end
109
+ }
110
+ }
111
+ end,
112
+ },
113
+ radio: {
114
+ widget_value_property: :selection,
115
+ editor_gui: lambda do |args, model, property, table_proxy|
116
+ first_time = true
117
+ table_proxy.table_editor.minimumHeight = 25
118
+ radio(*args) {
119
+ selection model.send(property)
120
+ focus true
121
+ on_widget_selected {
122
+ table_proxy.finish_edit!
123
+ }
124
+ on_focus_lost {
125
+ table_proxy.finish_edit!
126
+ }
127
+ on_key_pressed { |key_event|
128
+ if key_event.keyCode == swt(:cr)
129
+ table_proxy.finish_edit!
130
+ elsif key_event.keyCode == swt(:esc)
131
+ table_proxy.cancel_edit!
132
+ end
133
+ }
134
+ }
135
+ end,
136
+ }
89
137
  }
90
138
  end
91
139
  end
@@ -161,9 +209,19 @@ module Glimmer
161
209
  @editor = args
162
210
  end
163
211
 
212
+ def cells_for(model)
213
+ column_properties.map {|property| model.send(property)}
214
+ end
215
+
216
+ def cells
217
+ column_count = @table.column_properties.size
218
+ swt_widget.items.map {|item| column_count.times.map {|i| item.get_text(i)} }
219
+ end
220
+
164
221
  def sort
165
222
  return unless sort_property && (sort_type || sort_block || sort_by_block)
166
223
  array = model_binding.evaluate_property
224
+ array = array.sort_by(&:hash) # this ensures consistent subsequent sorting in case there are equivalent sorts to avoid an infinite loop
167
225
  # Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
168
226
  if sort_block
169
227
  sorted_array = array.sort(&sort_block)
@@ -276,7 +334,7 @@ module Glimmer
276
334
  new_value = @table_editor_widget_proxy&.swt_widget&.send(widget_value_property)
277
335
  if table_item.isDisposed
278
336
  @cancel_edit.call
279
- elsif new_value && !action_taken && !@edit_in_progress && !@cancel_in_progress
337
+ elsif !new_value.nil? && !action_taken && !@edit_in_progress && !@cancel_in_progress
280
338
  action_taken = true
281
339
  @edit_in_progress = true
282
340
  if new_value == model.send(model_editing_property)
@@ -25,6 +25,7 @@ module Glimmer
25
25
  "arrow" => [:arrow],
26
26
  "button" => [:push],
27
27
  "checkbox" => [:check],
28
+ "check" => [:check],
28
29
  "drag_source" => [:drop_copy],
29
30
  "drop_target" => [:drop_copy],
30
31
  "list" => [:border, :v_scroll],
@@ -41,21 +42,17 @@ module Glimmer
41
42
 
42
43
  DEFAULT_INITIALIZERS = {
43
44
  "composite" => lambda do |composite|
44
- layout = GridLayout.new
45
- layout.marginWidth = 15
46
- layout.marginHeight = 15
47
- composite.layout = layout
45
+ if composite.get_layout.nil?
46
+ layout = GridLayout.new
47
+ layout.marginWidth = 15
48
+ layout.marginHeight = 15
49
+ composite.layout = layout
50
+ end
48
51
  end,
49
52
  "scrolled_composite" => lambda do |scrolled_composite|
50
53
  scrolled_composite.expand_horizontal = true
51
54
  scrolled_composite.expand_vertical = true
52
55
  end,
53
- "shell" => lambda do |shell|
54
- layout = FillLayout.new
55
- layout.marginWidth = 15
56
- layout.marginHeight = 15
57
- shell.layout = layout
58
- end,
59
56
  "table" => lambda do |table|
60
57
  table.setHeaderVisible(true)
61
58
  table.setLinesVisible(true)
@@ -64,21 +61,48 @@ module Glimmer
64
61
  table_column.setWidth(80)
65
62
  end,
66
63
  "group" => lambda do |group|
67
- group.setLayout(GridLayout.new)
64
+ group.layout = GridLayout.new if group.get_layout.nil?
68
65
  end,
69
66
  }
67
+
68
+ class << self
69
+ def create(keyword, parent, args)
70
+ widget_proxy_class(keyword).new(keyword, parent, args)
71
+ end
72
+
73
+ def widget_proxy_class(keyword)
74
+ begin
75
+ class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym
76
+ Glimmer::SWT.const_get(class_name)
77
+ rescue
78
+ Glimmer::SWT::WidgetProxy
79
+ end
80
+ end
81
+
82
+ def underscored_widget_name(swt_widget)
83
+ swt_widget.class.name.split(/::|\./).last.underscore
84
+ end
85
+ end
70
86
 
71
87
  attr_reader :parent_proxy, :swt_widget, :drag_source_proxy, :drop_target_proxy, :drag_source_style, :drag_source_transfer, :drop_target_transfer
72
-
88
+
73
89
  # Initializes a new SWT Widget
74
90
  #
75
91
  # Styles is a comma separate list of symbols representing SWT styles in lower case
76
- def initialize(underscored_widget_name, parent, args)
77
- @parent_proxy = parent
78
- styles, extra_options = extract_args(underscored_widget_name, args)
79
- swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
80
- @swt_widget = swt_widget_class.new(@parent_proxy.swt_widget, style(underscored_widget_name, styles), *extra_options)
81
- @swt_widget.set_data('proxy', self)
92
+ def initialize(*init_args, swt_widget: nil)
93
+ if swt_widget.nil?
94
+ underscored_widget_name, parent, args = init_args
95
+ @parent_proxy = parent
96
+ styles, extra_options = extract_args(underscored_widget_name, args)
97
+ swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
98
+ @swt_widget = swt_widget_class.new(@parent_proxy.swt_widget, style(underscored_widget_name, styles), *extra_options)
99
+ else
100
+ @swt_widget = swt_widget
101
+ underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
102
+ parent_proxy_class = self.class.widget_proxy_class(self.class.underscored_widget_name(@swt_widget.parent))
103
+ @parent_proxy = parent_proxy_class.new(swt_widget: swt_widget.parent)
104
+ end
105
+ @swt_widget.set_data('proxy', self)
82
106
  DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@swt_widget)
83
107
  @parent_proxy.post_initialize_child(self)
84
108
  end
@@ -288,7 +312,7 @@ module Glimmer
288
312
 
289
313
  # This supports widgets in and out of basic SWT
290
314
  def self.swt_widget_class_for(underscored_widget_name)
291
- underscored_widget_name = 'button' if %w[radio checkbox toggle arrow].include?(underscored_widget_name)
315
+ underscored_widget_name = 'button' if %w[radio checkbox check toggle arrow].include?(underscored_widget_name)
292
316
  swt_widget_name = underscored_widget_name.camelcase(:upper)
293
317
  swt_widget_class = eval(swt_widget_name)
294
318
  unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
@@ -430,6 +454,7 @@ module Glimmer
430
454
  rescue => e
431
455
  Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{swt_widget.class.name} can handle the method ##{method}"}
432
456
  super
457
+ # TODO consider get_attribute too
433
458
  end
434
459
 
435
460
  def respond_to?(method, *args, &block)