| Home | « Prev Contents Next » | Download |
| JRBuilder: Binding Demo 2 | ||
| Still more on Binding: Using prototypes. Binding contexts and inheritance. |
|
|
|
This example builds on the
the previous example,
and introduces the concepts of binding contexts and
prototypes.
A binding context is a collection of zero or more each of
bindings, prototypes, translators, and converters,
and potentially other types of things in the future. (Translators
and converters are discussed in
a later example.) Each
A named binding context is created the first time it is specified
in a (I will probably add multiple inheritance in the near future. It seems like it could be quite useful, at least to the extent that any of this is.)
A new binding context is created in a bound state; that is,
any bindings specified immediately go into effect. (This will
change soon; I plan to add an
In this example, I first create a new Bindery, and then create a
new named binding context, '
The new binding context defines two prototypes. A prototype
definition usually looks something like a correspondent
definition, except that a class (or nil) is specified
instead of a particular instance of a class; and a correspondent
is specified in a Prototypes are searched from nearest to farthest defined, matching on class, event method, getter, setter, unit, and type, where a nil value in the prototype acts as a wildcard, matching any value in the correspondent. All six elements above must match, by equality or wildcard, for the prototype to be used. If a prototype matches, any element that it defines that is not yet present in the correspondent will be set in the correspondent. Prototypes that are specified after a given binding will not be searched for that binding.
Prototypes use the method name So, to get back to the example (you're undoubtedly relieved), I've created a named context with two prototypes, in a Bindery created outside of any Swing context. Next, I create two Swing contexts, each using the new Bindery. Then, in each Swing context I create a new binding context that inherits the prototypes from the 'lib' context. I then declare my bindings, omitting those elements that I expect to inherit from a prototype.
You'll notice that in the specification of the prototype for
In this example, the attribute |
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 = nil
field2 = nil
@my_frame = frame('Binding Demo 2A') { 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
}
}
# create a binding context that inherits from
# our lib
binding_context('my_swing_lib', 'my_ctx_1') {
bind { sliders.each do |slider| proto(slider); end }
bind {
proto(field1.document) { obj field1 }
proto(field2.document) { obj field2 }
}
}
}
ctx2.enter {
attr_reader :my_frame
sliders = []
field1 = nil
field2 = nil
@my_frame = frame('Binding Demo 2B') { 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
}
}
# create a binding context that inherits from
# our lib
binding_context('my_swing_lib', 'my_ctx_2') {
bind { sliders.each do |slider| proto(slider); end }
bind {
proto(field1.document) { obj field1 }
proto(field2.document) { obj field2 }
}
}
}
ctx1.my_frame.show
ctx2.my_frame.show
|
|
| Home | « Prev Contents Next » | Download |