epubjs
Version:
Render ePub documents in the browser, across many devices
70 lines (69 loc) • 7 kB
HTML
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Binding Properties</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Binding Properties"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-22-SECT-5"/>Binding Properties</h1></div></div></div><p><a id="idx11150" class="indexterm"/>By using a combination of events and adapters, we can
connect beans in many interesting ways. We can even “bind” two beans
together so that if a property changes in the first bean, the
corresponding property is automatically changed in the second bean. In
this scenario, the beans don’t necessarily have to be of the same type,
but in order to make sense, the properties do.</p><p>Close the <code class="literal">Molecule</code> file and start
a new one. Grab two <a id="I_indexterm22_id821637" class="indexterm"/><code class="literal">NumericField</code> beans from
the palette, drop them in the workspace, and select one of them. You’ll
probably want to set the AbsoluteLayout again. You can also adjust the
width of the fields by dragging them at the sides. You’ll notice that a
<code class="literal">NumericField</code> has many of the standard
properties of a Swing component. If you look in the Other Properties
section of the Properties pane, you can find an integer property called
<code class="literal">value</code> that represents the numeric value
of the field. You can set it there or enter a number directly into the
field when you run the program. <code class="literal">NumericField</code> rejects nonnumeric text.</p><p>Let’s bind the <code class="literal">value</code> property of
one of the fields to the other. Activate the Connection Wizard to create a
connection between the two fields. Click first on <code class="literal">numericField1</code> and then on <code class="literal">numericField2</code> so that <code class="literal">numericField1</code> is the source. In the wizard,
choose the <code class="literal">propertyChange()</code> event of
the source field. This is the listener method for <code class="literal">PropertyChangeEvent</code>, a generic event sent by
beans when one of their properties changes. When a bean fires property
change events in response to changes in a particular property, that
property is said to be “bound.” This means that it is possible to bind the
property to another bean through the generic mechanism. In this case, the
<code class="literal">value</code> property of our <code class="literal">NumericField</code> beans is a bound property, so
whenever it changes, a <code class="literal">PropertyChange</code><code class="literal">Event</code> is
fired.</p><p>Choose Next, and select the <code class="literal">value</code>
property as the target for <code class="literal">numericField2</code>. Click Next again, and select the
Property radio button on the Parameters screen. Click the “...” editor
button to pop up a Select Property dialog. Select the source numeric field
(probably named <code class="literal">numericField1</code>, if that
is your source button) from the pull-down menu, and then choose the
<code class="literal">value</code> property. Click OK and Finish to
complete the hookup.</p><p>Run the application, and try entering values in the first field
(<code class="literal">numericField1</code>). The second field
should change each time. The second bean’s value property has been bound
to the first.</p><p>Try binding the value property in the other direction as well so
that you can change the value in either bean, and the changes are
propagated in both directions. (Some simple logic in the beans prevents
infinite loops from happening here.)</p><p>NetBeans has again generated an adapter for us. This time, the
adapter listens for <code class="literal">PropertyChangeEvent</code>s and invokes the <code class="literal">setValue()</code> method of our target field. We
haven’t done anything earth shattering. The <code class="literal">PropertyChangeEvent</code> does carry some extra
information—the old and new values of the property—but we’re not using
them here. And with the Connection Wizard, you can use any event source as
the impetus to set a property on your target bean. Finally, as we’ve seen,
the property can derive its value from any other bean in the layout. The
flexibility of the Connection Wizard is, to some extent, masking the
purpose of the events, but that’s OK. If we are interested in the specific
property that changed, or if we want to apply logic about the value, we
can fill in the generated method with our own code.</p><p>Many Swing components have bound properties, which are usually
documented in the Javadoc for the class.</p><div class="sect2" title="Constraining Properties"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-22-SECT-5.1"/>Constraining Properties</h2></div></div></div><p>In the previous section, we discussed how beans fire <a id="I_indexterm22_id821820" class="indexterm"/><code class="literal">PropertyChangeEvent</code>s to
notify other beans (and adapters) that a property has changed. In that
scenario, the object that receives the event is simply a passive
listener as far as the event’s source is concerned. JavaBeans also
supports <span class="emphasis"><em>constrained properties</em></span>, in which the event
listener gets to say whether it will allow a bean to change the
property’s value. If the new value is rejected, the change is cancelled;
the event source keeps its old value.</p><p>The concept of constrained properties has not been heavily used in
the normal operation of Swing, so we won’t cover it in detail here. But
it goes something like this. Normally, <code class="literal">PropertyChangeEvent</code>s are delivered to a
<code class="literal">propertyChange()</code> method in the
listener. Constrained properties are implemented by delivering
<a id="I_indexterm22_id821860" class="indexterm"/><code class="literal">PropertyChangeEvent</code>s to
a separate listener method called <code class="literal">vetoableChange()</code>. The <a id="I_indexterm22_id821877" class="indexterm"/><code class="literal">vetoableChange()</code> method
throws a <code class="literal">PropertyVetoException</code> if it
doesn’t like a proposed change. In this way, components can govern the
acceptable values set by other components.<a id="I_indexterm22_id821896" class="indexterm"/></p></div></div></body></html>