| Home | « Prev Contents Next » | Download |
| JRBuilder: Hello World Demo 2 | ||
| A beefed-up Hello World application. Binding with Bob and Sue, and Wombats. | ![]() |
|
|
This example builds on the
previous Hello World example,
and introduces binding.
Binding enables you to link together, or bind, data in different
objects, so their values remain synchronized. Binding in
JRBuilder is supplied by the
The Bindery currently supports two binding strategies, intercept and listen (aka observe). (A third, poll, is in the works.) Both strategies are employed in this example.
The intercept strategy is used with plain old Ruby objects (POROs?).
In it, the setter for the desired property is aliased and replaced
with one that relays all changes to the Bindery, where other
participants in the binding (known as correspondents in the
The listen strategy is used with Java objects proxied by JRuby
(though it could conceivably be adapted to other event models). In
it, an event listener is registered with an object, and notifies the
Bindery of any changes when it receives an event. Again, the Bindery
propagates the change to the other correspondents in the binding. As
with event handlers (see previous example),
any event method defined in a It is also possible to use the intercept strategy with proxied Java objects, but the results will be unreliable in many (if not most) cases. That's because the setter methods of the JavaProxy will be intercepted, not those of the Java object itself. If a setter will be called only by other JRuby objects, that's fine; but if another Java object (or possibly the object itself, or a subcomponent) calls the setter, that event will not be intercepted, and the binding will effectively be broken.
So it is better to look for a
Ok, looks like I've typed my way down to the interesting part of the example.
In JRBuilder/Bindery, n number of objects (where n > 1) may be bound
in a single binding. (A given object may also be used in multiple bindings.)
In this case, we're binding three objects: two POROs and a Java object. The
The optional
A predicate may accept a second parameter,
You may have noticed that This example has demonstrated Ruby-to-Ruby and Ruby-to-Java binding. The next example demonstrates Java-to-Java binding, to silly excess. |
require 'jrbuilder'
ctx = JRBuilder.new_swing_context
ctx.enter {
attr_reader :my_frame
bgcolor = color(240,238,220)
class MyClass
attr_reader :name,:value
def initialize(name)
@name = name
end
def value=(val)
@value = val
puts "#{@name} set value = #{@value}"
end
end
bob = MyClass.new('Bob')
sue = MyClass.new('Sue')
hello = nil # label
@running = false # flag for demo
@exiting = false # flag for demo
@my_frame = frame('Hello World Demo 2') { size 320, 240
on_window_closing { @running = false; @exiting = true; my_frame.dispose }
content_pane { layout :box,_parent,:Y_AXIS; background bgcolor;
border :bevel, :RAISED }
menu_bar { background bgcolor
menu('File') { mnemonic :VK_F; background :WHITE
menu_item('Exit') { mnemonic :VK_X; background :WHITE
on_click { @running = false; @exiting = true; my_frame.dispose }
}
}
menu('Run') { mnemonic :VK_R; background :WHITE
@start = menu_item('Start') { mnemonic :VK_S; background :WHITE
enabled(!@running && !@exiting)
on_click { @running = true unless @exiting }
}
@stop = menu_item('Stop') { mnemonic :VK_P; background :WHITE
enabled(@running && !@exiting)
on_click { @running = false }
}
}
}
y_glue
panel {layout :box,_parent,:X_AXIS; background :WHITE
hello = label('Hello, World!') { align :CENTER
foreground :BLUE; border :bevel, :RAISED;
font('Dialog',:BOLD,40)
}
}
y_strut 20
button('Reverse!') { align :CENTER
on_click { hello.text = hello.text.reverse }
}
y_glue
}
# ok, let's hook some things together
bind {
property_change(hello,'text') {
predicate { |event| event.property_name == 'text' }
}
property(bob,'value')
property(sue,'value')
}
@bob = bob
@sue = sue
@hello = hello
def run_demo
@running = true
@start.enabled = false
@stop.enabled = true
while !@exiting
sleep 2
@stop.enabled = @running
@start.enabled = !@running
next unless @running
@bob.value = 'Wombat!'
sleep 2
next unless @running
@sue.value = 'Platypus!'
sleep 2
next unless @running
@hello.text = 'Hobbit!'
sleep 2
next unless @running
@sue.value = 'Wow!'
sleep 2
next unless @running
@hello.text = 'Hello, World!'
end
end
}
ctx.my_frame.show
ctx.run_demo
|
|
| Home | « Prev Contents Next » | Download |