glimmer 0.1.0.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +9 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.markdown +54 -0
  5. data/Rakefile +54 -0
  6. data/VERSION +1 -0
  7. data/bin/glimmer +132 -0
  8. data/glimmer.gemspec +145 -0
  9. data/images/Bitter-sweet.jpg +0 -0
  10. data/{src → lib}/command_handler.rb +7 -10
  11. data/{src → lib}/command_handler_chain_factory.rb +29 -22
  12. data/{src → lib}/command_handler_chain_link.rb +19 -22
  13. data/{src → lib}/command_handlers.rb +29 -26
  14. data/{src → lib}/command_handlers/bind_command_handler.rb +25 -28
  15. data/lib/command_handlers/combo_selection_data_binding_command_handler.rb +39 -0
  16. data/{src → lib}/command_handlers/data_binding_command_handler.rb +61 -64
  17. data/lib/command_handlers/list_selection_data_binding_command_handler.rb +42 -0
  18. data/lib/command_handlers/models/list_observer.rb +31 -0
  19. data/{src → lib}/command_handlers/models/model_observer.rb +28 -25
  20. data/{src → lib}/command_handlers/models/observable_array.rb +53 -46
  21. data/lib/command_handlers/models/observable_model.rb +61 -0
  22. data/{src → lib}/command_handlers/models/r_runnable.rb +11 -14
  23. data/{src → lib}/command_handlers/models/r_shell.rb +23 -26
  24. data/lib/command_handlers/models/r_tab_item_composite.rb +25 -0
  25. data/{src → lib}/command_handlers/models/r_widget.rb +16 -14
  26. data/lib/command_handlers/models/r_widget_listener.rb +9 -0
  27. data/{src → lib}/command_handlers/models/r_widget_packages.rb +5 -8
  28. data/{src → lib}/command_handlers/models/table_items_updater.rb +38 -39
  29. data/{src → lib}/command_handlers/models/widget_observer.rb +4 -6
  30. data/{src → lib}/command_handlers/shell_command_handler.rb +14 -17
  31. data/{src → lib}/command_handlers/swt_constant_command_handler.rb +18 -21
  32. data/lib/command_handlers/tab_item_command_handler.rb +22 -0
  33. data/{src → lib}/command_handlers/table_column_properties_data_binding_command_handler.rb +20 -23
  34. data/{src → lib}/command_handlers/table_items_data_binding_command_handler.rb +26 -29
  35. data/{src → lib}/command_handlers/widget_command_handler.rb +22 -25
  36. data/{src → lib}/command_handlers/widget_listener_command_handler.rb +36 -34
  37. data/{src → lib}/command_handlers/widget_method_command_handler.rb +18 -21
  38. data/{src → lib}/glimmer.rb +52 -45
  39. data/lib/parent.rb +5 -0
  40. data/{src → lib}/shine.rb +21 -24
  41. data/{src → lib}/xml_command_handlers.rb +15 -18
  42. data/{src → lib}/xml_command_handlers/html_command_handler.rb +45 -49
  43. data/{src → lib}/xml_command_handlers/models/depth_first_search_iterator.rb +17 -20
  44. data/{src → lib}/xml_command_handlers/models/name_space_visitor.rb +17 -20
  45. data/{src → lib}/xml_command_handlers/models/node.rb +80 -83
  46. data/{src → lib}/xml_command_handlers/models/node_visitor.rb +8 -11
  47. data/{src → lib}/xml_command_handlers/models/xml_visitor.rb +58 -61
  48. data/{src → lib}/xml_command_handlers/xml_command_handler.rb +18 -22
  49. data/{src → lib}/xml_command_handlers/xml_name_space_command_handler.rb +31 -34
  50. data/{src → lib}/xml_command_handlers/xml_tag_command_handler.rb +23 -26
  51. data/{src → lib}/xml_command_handlers/xml_text_command_handler.rb +19 -22
  52. data/samples/contactmanager/contact.rb +0 -3
  53. data/samples/contactmanager/contact_manager.rb +1 -4
  54. data/samples/contactmanager/contact_manager_presenter.rb +0 -3
  55. data/samples/contactmanager/contact_repository.rb +0 -3
  56. data/samples/hello_combo.rb +32 -0
  57. data/samples/hello_world.rb +1 -4
  58. data/samples/login.rb +1 -4
  59. data/samples/tictactoe/tic_tac_toe.rb +2 -5
  60. data/samples/tictactoe/tic_tac_toe_board.rb +0 -3
  61. data/test/glimmer_combo_data_binding_test.rb +131 -0
  62. data/test/glimmer_constant_test.rb +6 -11
  63. data/test/glimmer_data_binding_test.rb +16 -16
  64. data/test/glimmer_list_data_binding_test.rb +223 -0
  65. data/test/glimmer_listeners_test.rb +6 -6
  66. data/test/glimmer_shine_data_binding_test.rb +7 -6
  67. data/test/glimmer_tab_item_test.rb +61 -0
  68. data/test/glimmer_table_data_binding_test.rb +7 -20
  69. data/test/glimmer_test.rb +18 -13
  70. data/test/helper.rb +21 -0
  71. data/test/observable_model_test.rb +2 -4
  72. data/test/r_widget_test.rb +5 -5
  73. data/test/samples/contactmanager/contact_manager_presenter_test.rb +1 -4
  74. data/test/samples/tictactoe/tic_tac_toe_test.rb +1 -4
  75. data/test/xml/glimmer_xml_test.rb +43 -43
  76. metadata +210 -105
  77. data/COPYING.LGPL +0 -504
  78. data/README +0 -27
  79. data/src/command_handlers/models/observable_model.rb +0 -35
  80. data/src/command_handlers/models/r_widget_listener.rb +0 -12
  81. data/src/parent.rb +0 -8
  82. data/src/swt.rb +0 -10
  83. data/src/xml.rb +0 -10
@@ -1,25 +1,28 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- class ModelObserver
5
- attr_reader :model, :property_name, :property_type
6
- @@property_type_converters = {
7
- :undefined => Proc.new { |value| value },
8
- :fixnum => Proc.new { |string_value| string_value.to_i }
9
- #TODO check what other types are needed
10
- }
11
- def initialize(model, property_name, property_type)
12
- property_type = :undefined unless property_type
13
- @model = model
14
- @property_name = property_name
15
- @property_type = property_type
16
- end
17
- def update(value)
18
- converted_value = @@property_type_converters[@property_type].call(value)
19
- @model.send(@property_name + "=", converted_value) unless evaluate_property == converted_value
20
- end
21
- def evaluate_property
22
- @model.send(@property_name)
23
- end
24
- end
25
-
1
+ class ModelObserver
2
+ attr_reader :model, :property_name, :property_type
3
+ @@property_type_converters = {
4
+ :undefined => lambda { |value| value },
5
+ :fixnum => lambda { |value| value.to_i },
6
+ :array => lambda { |value| value.to_a }
7
+ }
8
+ def initialize(model, property_name, property_type = :undefined)
9
+ property_type = :undefined if property_type.nil?
10
+ @model = model
11
+ @property_name = property_name
12
+ @property_type = property_type
13
+ end
14
+ def update(value)
15
+ converted_value = @@property_type_converters[@property_type].call(value)
16
+ @model.send(@property_name + "=", converted_value) unless evaluate_property == converted_value
17
+ end
18
+ def evaluate_property
19
+ @model.send(@property_name)
20
+ end
21
+ def evaluate_options_property
22
+ @model.send(@property_name + "_options")
23
+ end
24
+ def options_property_name
25
+ self.property_name + "_options"
26
+ end
27
+ end
28
+
@@ -1,46 +1,53 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- module ObservableArray
5
-
6
- def add_observer(element_properties, observer)
7
- property_observer_list << observer
8
- each do |element|
9
- element_properties.each do |property|
10
- element.extend(ObservableModel) unless element.is_a?(ObservableModel)
11
- element.add_observer(property, observer)
12
- end
13
- end
14
- end
15
-
16
- def property_observer_list
17
- @property_observer_list = [] unless @property_observer_list
18
- @property_observer_list
19
- end
20
-
21
- def notify_observers
22
- property_observer_list.each {|observer| observer.update}
23
- end
24
-
25
- def self.extend_object(array)
26
- array.instance_eval("alias original_add <<")
27
- array.instance_eval "def <<(value) \n self.original_add(value); notify_observers; \nend"
28
-
29
- notify_observers_on_invokation(array, "delete", 1)
30
- notify_observers_on_invokation(array, "delete_at", 1)
31
- notify_observers_on_invokation(array, "clear")
32
-
33
- super
34
- end
35
-
36
- def self.notify_observers_on_invokation(model, method, argument_count=0)
37
- model.instance_eval "alias original_#{method} #{method}\n"
38
- arguments = ""
39
- for index in 1..argument_count
40
- arguments += "argument" + index.to_s + ","
41
- end
42
- arguments = arguments[0..-2]
43
- model.instance_eval "def #{method}(#{arguments}) \n self.original_#{method}(#{arguments}); notify_observers; \nend"
44
- end
45
-
46
- end
1
+ module ObservableArray
2
+
3
+ def add_observer(element_properties, observer)
4
+ property_observer_list << observer
5
+ each do |element|
6
+ element_properties.each do |property|
7
+ element.extend(ObservableModel) unless element.is_a?(ObservableModel)
8
+ element.add_observer(property, observer)
9
+ end
10
+ end
11
+ end
12
+
13
+ def property_observer_list
14
+ @property_observer_list = [] unless @property_observer_list
15
+ @property_observer_list
16
+ end
17
+
18
+ def notify_observers
19
+ property_observer_list.each {|observer| observer.update}
20
+ end
21
+
22
+ def self.extend_object(array)
23
+ array.instance_eval("alias original_add <<")
24
+ array.instance_eval <<-end_eval, __FILE__, __LINE__
25
+ def <<(value)
26
+ self.original_add(value)
27
+ notify_observers
28
+ end
29
+ end_eval
30
+
31
+ notify_observers_on_invokation(array, "delete", 1)
32
+ notify_observers_on_invokation(array, "delete_at", 1)
33
+ notify_observers_on_invokation(array, "clear")
34
+
35
+ super
36
+ end
37
+
38
+ def self.notify_observers_on_invokation(model, method, argument_count=0)
39
+ model.instance_eval "alias original_#{method} #{method}\n"
40
+ arguments = ""
41
+ for index in 1..argument_count
42
+ arguments += "argument" + index.to_s + ","
43
+ end
44
+ arguments = arguments[0..-2]
45
+ model.instance_eval <<-end_eval, __FILE__, __LINE__
46
+ def #{method}(#{arguments})
47
+ self.original_#{method}(#{arguments})
48
+ notify_observers
49
+ end
50
+ end_eval
51
+ end
52
+
53
+ end
@@ -0,0 +1,61 @@
1
+ module ObservableModel
2
+
3
+ def add_observer(property_name, observer)
4
+ property_observer_list(property_name) << observer
5
+ end
6
+
7
+ def property_observer_hash
8
+ @property_observers = Hash.new unless @property_observers
9
+ @property_observers
10
+ end
11
+
12
+ def property_observer_list(property_name)
13
+ property_observer_hash[property_name.to_sym] = [] unless property_observer_hash[property_name.to_sym]
14
+ property_observer_hash[property_name.to_sym]
15
+ end
16
+
17
+ def notify_observers(property_name)
18
+ property_observer_list(property_name).each {|observer| observer.update(send(property_name))}
19
+ end
20
+
21
+ class Updater
22
+ def initialize(property_name, observable_model)
23
+ @property_name = property_name
24
+ @observable_model = observable_model
25
+ end
26
+ def update
27
+ @observable_model.notify_observers(@property_name)
28
+ end
29
+ end
30
+
31
+ def self.extend_object(model)
32
+ super
33
+ model.methods.each do |method|
34
+ self.add_method_observers(model, method)
35
+ end
36
+ end
37
+
38
+ def self.add_method_observers(model, method)
39
+ setter_method_pattern = /^(\w+=)$/
40
+ if (method.match(setter_method_pattern))
41
+ getter_method = method[0, method.length - 1]
42
+ getter_value = model.send(getter_method)
43
+ if (getter_value.is_a?(Array) and
44
+ !getter_value.is_a?(ObservableArray))
45
+ getter_value.extend(ObservableArray)
46
+ getter_value.add_observer([], Updater.new(getter_method, model))
47
+ end
48
+ model.instance_eval "alias original_#{method} #{method}\n"
49
+ model.instance_eval <<-end_eval, __FILE__, __LINE__
50
+ def #{method}(value)
51
+ self.original_#{method}(value)
52
+ notify_observers('#{getter_method}')
53
+ if (value.is_a?(Array) and !value.is_a?(ObservableArray))
54
+ value.extend(ObservableArray)
55
+ value.add_observer([], ObservableModel::Updater.new('#{getter_method}', self))
56
+ end
57
+ end
58
+ end_eval
59
+ end
60
+ end
61
+ end
@@ -1,14 +1,11 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- class RRunnable
5
- include java.lang.Runnable
6
-
7
- def initialize(&block)
8
- @block = block
9
- end
10
-
11
- def run
12
- @block.call
13
- end
14
- end
1
+ class RRunnable
2
+ include java.lang.Runnable
3
+
4
+ def initialize(&block)
5
+ @block = block
6
+ end
7
+
8
+ def run
9
+ @block.call
10
+ end
11
+ end
@@ -1,27 +1,24 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/r_widget"
5
-
6
- class RShell < RWidget
7
- include_package 'org.eclipse.swt.layout'
8
- include_package 'org.eclipse.swt.widgets'
9
-
10
- attr_reader :display
11
-
12
- def initialize(display = Display.new)
13
- @display = display
14
- @widget = Shell.new(@display)
15
- @widget.setLayout(FillLayout.new)
16
- end
17
-
18
- def open
19
- @widget.pack
20
- @widget.open
21
- until @widget.isDisposed
22
- @display.sleep unless @display.readAndDispatch
23
- end
24
- @display.dispose
25
- end
26
-
1
+ require File.dirname(__FILE__) + "/r_widget"
2
+
3
+ class RShell < RWidget
4
+ include_package 'org.eclipse.swt.layout'
5
+ include_package 'org.eclipse.swt.widgets'
6
+
7
+ attr_reader :display
8
+
9
+ def initialize(display = Display.new)
10
+ @display = display
11
+ @widget = Shell.new(@display)
12
+ @widget.setLayout(FillLayout.new)
13
+ end
14
+
15
+ def open
16
+ @widget.pack
17
+ @widget.open
18
+ until @widget.isDisposed
19
+ @display.sleep unless @display.readAndDispatch
20
+ end
21
+ @display.dispose
22
+ end
23
+
27
24
  end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + "/r_widget_listener"
2
+ require File.dirname(__FILE__) + "/r_runnable"
3
+
4
+ class RTabItemComposite < RWidget
5
+ include_package 'org.eclipse.swt.widgets'
6
+
7
+ attr_reader :tab_item
8
+ def initialize(tab_item, parent, style, &contents)
9
+ super("composite", parent, style, &contents)
10
+ @tab_item = tab_item
11
+ @tab_item.widget.control = self.widget
12
+ end
13
+
14
+ def respond_to?(method_symbol, *args)
15
+ if method_symbol.to_s == "text"
16
+ true
17
+ else
18
+ super(method_symbol, *args)
19
+ end
20
+ end
21
+
22
+ def text(text_value)
23
+ @tab_item.widget.text=text_value
24
+ end
25
+ end
@@ -1,6 +1,3 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
1
  require File.dirname(__FILE__) + "/r_widget_listener"
5
2
  require File.dirname(__FILE__) + "/r_runnable"
6
3
 
@@ -16,6 +13,7 @@ class RWidget
16
13
  "text" => SWT::BORDER,
17
14
  "table" => SWT::BORDER,
18
15
  "spinner" => SWT::BORDER,
16
+ "list" => SWT::BORDER | SWT::V_SCROLL,
19
17
  "button" => SWT::PUSH,
20
18
  }
21
19
 
@@ -32,7 +30,7 @@ class RWidget
32
30
 
33
31
  def initialize(underscored_widget_name, parent, style, &contents)
34
32
  style = default_style(underscored_widget_name) unless style
35
- @widget = eval underscored_widget_name.to_s.camelcase(true) + '.new(parent, style)'
33
+ @widget = eval underscored_widget_name.to_s.camelcase + '.new(parent, style)'
36
34
  @@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
37
35
  end
38
36
 
@@ -43,11 +41,11 @@ class RWidget
43
41
  end
44
42
 
45
43
  def respond_to?(method_symbol, *args)
46
- @widget.respond_to?("set" + method_symbol.to_s.camelcase(true), args)
44
+ @widget.respond_to?("set#{method_symbol.to_s.camelcase(:upper)}", args)
47
45
  end
48
46
 
49
47
  def method_missing(method_symbol, *args)
50
- statement_to_eval = "@widget.send('set' + method_symbol.to_s.camelcase(true)"
48
+ statement_to_eval = "@widget.send('set' + method_symbol.to_s.camelcase(:upper)"
51
49
  statement_to_eval << expand_arguments(args)
52
50
  statement_to_eval << ")"
53
51
  eval statement_to_eval
@@ -65,7 +63,7 @@ class RWidget
65
63
 
66
64
  def self.widget_exists?(underscored_widget_name)
67
65
  begin
68
- eval underscored_widget_name.camelcase(true)
66
+ eval underscored_widget_name.camelcase
69
67
  true
70
68
  rescue NameError
71
69
  false
@@ -73,12 +71,12 @@ class RWidget
73
71
  end
74
72
 
75
73
  def widget_listener_exists?(underscored_listener_name)
76
- listener_method_name = underscored_listener_name.camelcase()
74
+ listener_method_name = underscored_listener_name.listener_method_name(:lower)
77
75
  @widget.getClass.getMethods.each do |widget_method|
78
76
  if widget_method.getName.match(/add.*Listener/)
79
77
  widget_method.getParameterTypes.each do |listener_type|
80
78
  listener_type.getMethods.each do |listener_method|
81
- if (listener_method.getName.match(listener_method_name))
79
+ if (listener_method.getName == listener_method_name)
82
80
  return true
83
81
  end
84
82
  end
@@ -89,12 +87,12 @@ class RWidget
89
87
  end
90
88
 
91
89
  def can_add_listener?(underscored_listener_name)
92
- listener_method_name = underscored_listener_name.camelcase()
90
+ listener_method_name = underscored_listener_name.camelcase(:lower)
93
91
  @widget.getClass.getMethods.each do |widget_method|
94
92
  if widget_method.getName.match(/add.*Listener/)
95
93
  widget_method.getParameterTypes.each do |listener_type|
96
94
  listener_type.getMethods.each do |listener_method|
97
- if (listener_method.getName.match(listener_method_name))
95
+ if (listener_method.getName == listener_method_name)
98
96
  return true
99
97
  end
100
98
  end
@@ -105,14 +103,14 @@ class RWidget
105
103
  end
106
104
 
107
105
  def add_listener(underscored_listener_name, &block)
108
- listener_method_name = underscored_listener_name.camelcase()
106
+ listener_method_name = underscored_listener_name.camelcase(:lower)
109
107
  @widget.getClass.getMethods.each do |widget_method|
110
108
  if widget_method.getName.match(/add.*Listener/)
111
109
  widget_method.getParameterTypes.each do |listener_type|
112
110
  listener_type.getMethods.each do |listener_method|
113
- if (listener_method.getName.match(listener_method_name))
111
+ if (listener_method.getName == listener_method_name)
114
112
  listener_class = Class.new(Object)
115
- listener_class.send :include, (eval listener_type.to_s)
113
+ listener_class.send :include, (eval listener_type.to_s.sub("interface", ""))
116
114
  listener = listener_class.new
117
115
  listener_type.getMethods.each do |t_method|
118
116
  eval "def listener.#{t_method.getName}(event) end"
@@ -143,4 +141,8 @@ class RWidget
143
141
  @widget.getDisplay.syncExec(RRunnable.new(&block))
144
142
  end
145
143
 
144
+ def has_style?(style)
145
+ (widget.style & style) == style
146
+ end
147
+
146
148
  end
@@ -0,0 +1,9 @@
1
+ class RWidgetListener
2
+
3
+ attr_reader :listener
4
+
5
+ def initialize(listener)
6
+ @listener = listener
7
+ end
8
+
9
+ end
@@ -1,9 +1,6 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- # edit to add more packages and support custom widgets
5
- class RWidget
6
- include_package 'org.eclipse.swt'
7
- include_package 'org.eclipse.swt.layout'
8
- include_package 'org.eclipse.swt.widgets'
1
+ # edit to add more packages and support custom widgets
2
+ class RWidget
3
+ include_package 'org.eclipse.swt'
4
+ include_package 'org.eclipse.swt.layout'
5
+ include_package 'org.eclipse.swt.widgets'
9
6
  end
@@ -1,39 +1,38 @@
1
- # Copyright (C) 2007-2008 Annas Al Maleh
2
- # Licensed under the LGPL. See /COPYING.LGPL for more details.
3
-
4
- require File.dirname(__FILE__) + "/observable_array"
5
- require File.dirname(__FILE__) + "/observable_model"
6
-
7
- class TableItemsUpdater
8
- include_package 'org.eclipse.swt'
9
- include_package 'org.eclipse.swt.widgets'
10
-
11
- def initialize(parent, model_observer, column_properties)
12
- @table = parent
13
- @model_observer = model_observer
14
- @column_properties = column_properties
15
- update(@model_observer.evaluate_property)
16
- model = model_observer.model
17
- model.extend(ObservableModel) unless model.is_a?(ObservableModel)
18
- model.add_observer(model_observer.property_name, self)
19
- end
20
- def update(model_collection=nil)
21
- if (model_collection and model_collection.is_a?(Array))
22
- model_collection.extend(ObservableArray)
23
- model_collection.add_observer(@column_properties, self)
24
- @model_collection = model_collection
25
- end
26
- populate_table(@model_collection, @table, @column_properties)
27
- end
28
- def populate_table(model_collection, parent, column_properties)
29
- parent.widget.removeAll
30
- model_collection.each do |model|
31
- table_item = TableItem.new(parent.widget, SWT::NONE)
32
- for index in 0..(column_properties.size-1)
33
- table_item.setText(index, model.send(column_properties[index]).to_s)
34
- end
35
- end
36
- end
37
-
38
- end
39
-
1
+ require File.dirname(__FILE__) + "/observable_array"
2
+ require File.dirname(__FILE__) + "/observable_model"
3
+
4
+ class TableItemsUpdater
5
+ include_package 'org.eclipse.swt'
6
+ include_package 'org.eclipse.swt.widgets'
7
+
8
+ def initialize(parent, model_observer, column_properties)
9
+ @table = parent
10
+ @model_observer = model_observer
11
+ @column_properties = column_properties
12
+ update(@model_observer.evaluate_property)
13
+ model = model_observer.model
14
+ model.extend(ObservableModel) unless model.is_a?(ObservableModel)
15
+ model.add_observer(model_observer.property_name, self)
16
+ end
17
+ def update(model_collection=nil)
18
+ if (model_collection and
19
+ model_collection.is_a?(Array) and
20
+ !model_collection.is_a?(ObservableArray))
21
+ model_collection.extend(ObservableArray)
22
+ model_collection.add_observer(@column_properties, self)
23
+ @model_collection = model_collection
24
+ end
25
+ populate_table(@model_collection, @table, @column_properties)
26
+ end
27
+ def populate_table(model_collection, parent, column_properties)
28
+ parent.widget.removeAll
29
+ model_collection.each do |model|
30
+ table_item = TableItem.new(parent.widget, SWT::NONE)
31
+ for index in 0..(column_properties.size-1)
32
+ table_item.setText(index, model.send(column_properties[index]).to_s)
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+