| Home | « Prev Contents Next » | Download |
| JRBuilder: Binding Demo 3 | ||
| Still more on Binding: Binding across applications. Unbind, Rebind, Remove. |
|
|
This example builds on the
the previous example.
It demonstrates binding properties from two applications, and
shows the use of the binding management statements
unbind,
rebind,
unbind_context,
rebind_context, and
remove_context. It also
shows the use of named bindings.
This example is all but self-explanatory (if you've gone through the previous examples), but I'll touch on a few points. As with the previous example, the notable code (those lines that differ from the previous example) are shown in blue. In this example, the binding contexts and bindings that were defined in each Swing context have been removed, and replaced by an externally-defined binding context. The properties to be bound in each Swing context have been given accessors so they may be bound externally. Furthermore, the properties of each application are now bound to those of the other, whereas previously they were only bound to other internal properties. You'll notice that each binding now has a name. That permits them to be managed individually. All the previous bindings shown have been anonymous bindings, which may be fine in many applications, so long as they are defined in a named binding context, rather than the default context. An anonymous binding in the default context is there to stay; because the default context cannot be unbound, and an anonymous binding cannot be unbound, there is no way to clean up once your application terminates. If all bindings are intra-application, that may not matter much, but it is generally a good idea to unbind and remove bindings when they are no longer needed. The balance of the example shows the use of the various binding management statements. Here's a brief summary:
|
require 'jrbuilder'
bindery = Bindery::Bindery.new
# create a named binding context with some
# useful prototypes
bindery.binding_context('my_swing_lib') {
undoable_edit_happened(javax.swing.text.Document) {
getter { |obj,attribs| attribs[:obj].text }
setter { |obj,value,attribs| attribs[:obj].text = value }
}
state_changed(javax.swing.JSlider,'value')
}
# create two Swing contexts that share the same bindery
ctx1 = JRBuilder.new_swing_context(bindery)
ctx2 = JRBuilder.new_swing_context(bindery)
ctx1.enter {
attr_reader :my_frame, :sliders, :field1, :field2
@sliders = []
@field1 = nil
@field2 = nil
@my_frame = frame('Binding Demo 3A') { size 200, 400; location 200, 100
layout :grid,2,1; border :bevel, :RAISED
on_window_closing { my_frame.dispose }
menu_bar {
menu('File') { mnemonic :VK_F; background :WHITE
menu_item('Exit') { mnemonic :VK_X; background :WHITE
on_click { my_frame.dispose }
}
}
}
y_box { border(:titled, 'Horizontal Sliders') { border :etched, :LOWERED }
y_glue
4.times {
@sliders << slider(:HORIZONTAL) { value 0 }
y_glue
}
}
y_box { border(:titled, 'Text Fields') { border :etched, :LOWERED }
y_glue
text_area('Type text in one box, and watch it appear in the other') {
line_wrap true; wrap_style_word true; editable false;
border :etched, :RAISED; fixed_size 175,40
}
y_glue
@field1 = text_field('Enter text here',15) {
border :bevel, :LOWERED; fixed_size 175,24
on_focus_gained { @field1.select_all }
}
y_glue
@field2 = text_field('Enter text here',15) {
border :bevel, :LOWERED; fixed_size 175,24
on_focus_gained { |event,obj| obj.select_all }
}
y_glue
}
}
# binding moved outside of Swing context
}
ctx1.my_frame.show
ctx2.enter {
attr_reader :my_frame, :sliders, :field1, :field2
@sliders = []
@field1 = nil
@field2 = nil
@my_frame = frame('Binding Demo 3B') { size 200, 400; location 500, 100
layout :grid,2,1; border :bevel, :RAISED
on_window_closing { my_frame.dispose }
menu_bar {
menu('File') { mnemonic :VK_F; background :WHITE
menu_item('Exit') { mnemonic :VK_X; background :WHITE
on_click { my_frame.dispose }
}
}
}
y_box { border(:titled, 'Horizontal Sliders') { border :etched, :LOWERED }
y_glue
4.times {
@sliders << slider(:HORIZONTAL) { value 0 }
y_glue
}
}
y_box { border(:titled, 'Text Fields') { border :etched, :LOWERED }
y_glue
text_area('Type text in one box, and watch it appear in the other') {
line_wrap true; wrap_style_word true; editable false;
border :etched, :RAISED; fixed_size 175,40
}
y_glue
@field1 = text_field('Enter text here',15) {
border :bevel, :LOWERED; fixed_size 175,24
on_focus_gained { @field1.select_all }
}
y_glue
@field2 = text_field('Enter text here',15) {
border :bevel, :LOWERED; fixed_size 175,24
on_focus_gained { |event,obj| obj.select_all }
}
y_glue
}
}
# binding moved outside of Swing context
}
ctx2.my_frame.show
puts 'Binding all objects'
# create a binding context that inherits from
# our lib, and bind the objects from each app
bindery.binding_context('my_swing_lib', 'my_ctx') {
bind('sliders') {
ctx1.sliders.each do |slider| proto(slider); end
ctx2.sliders.each do |slider| proto(slider); end
}
bind('text fields') {
proto(ctx1.field1.document) { obj ctx1.field1 }
proto(ctx1.field2.document) { obj ctx1.field2 }
proto(ctx2.field1.document) { obj ctx2.field1 }
proto(ctx2.field2.document) { obj ctx2.field2 }
}
}
puts 'All objects bound, try them out'
# wait a bit for the user to try them
sleep 12
puts 'Unbinding sliders, check it out'
bindery.unbind('my_ctx','sliders')
# wait a bit for the user to try them
sleep 10
puts 'Unbinding text fields, rebinding sliders, check it out'
bindery.unbind('my_ctx','text fields')
bindery.rebind('my_ctx','sliders')
# wait a bit for the user to try them
sleep 10
puts 'Rebinding text fields, check it out'
bindery.rebind('my_ctx','text fields')
# wait a bit for the user to try them
sleep 10
puts 'Unbinding context, check it out'
bindery.unbind_context('my_ctx')
# wait a bit for the user to try them
sleep 10
puts 'Rebinding context, check it out'
bindery.rebind_context('my_ctx')
# wait a bit for the user to try them
sleep 10
puts 'Unbinding and removing context, check it out'
bindery.unbind_context('my_ctx')
bindery.remove_context('my_ctx')
puts 'bye'
|
|
| Home | « Prev Contents Next » | Download |