glimmer 0.1.0.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+