UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

70 lines (69 loc) 7 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <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>