Search |
||||||
Beans Binding for Me? You Shouldn't Have.Posted by diverson on April 3, 2007 at 5:17 PM PDT
New Toys!As it turns out, yesterday was a momentous day. No, not because of my last post, but thank you for thinking so. Actually, Shannon Hickey finally managed to navigate through the licensing maze (scariest thing since Minotaurs lived on Crete) and the new Beans Binding framework has been released! Greedy bastard that I am, I downloaded it as soon as I found out it was available. I decided to subject it to the Clueless Newbie Test. Which is, "How long would it take a complete neophyte (that'd be me) to download the library, compile it, and make it do something useful?" I'm using a loose definition of the word useful here, but the result was: 20 minutes. I decided to try to see how nicely beans binding plays with the Swing app framework. You would think that they would integrate nicely, but one never knows. Sometimes the Sun gods like to torture us just to watch us squirm like little ants under a magnifying glass. Ok, I've never put an ant under a magnifying glass but I'm sure it's uncomfortable for the little guys and there must be squirming involved. Which is just how I've felt at times using certain Java technologies. So what brilliant demonstration of the awesome power of beans binding did I come up with? Well, I was thinking that if counting aloud can be rude, then we need some way to determine when counting is allowed. The really scary part is, that's all the logic I need to pursue my latest plot to take over the world. This time my instrument of world domination will be...the JCheckBox! Mwah, hah, hah, hah. Um...What?So I started with the code from Action Game 1, and transformed it into the new and improved Action Game 2 by adding my weapon of mass construction, the check box.
protected void startup(String[] args)
{
...
JCheckBox check = new JCheckBox();
check.setName( "allowCountingCheck" );
JPanel panel = new JPanel();
panel.setBorder( BorderFactory.createTitledBorder( rMap.getString( "countingDemo" ) ) );
panel.setLayout( new BorderLayout() );
panel.add( label, BorderLayout.NORTH );
panel.add( btn, BorderLayout.CENTER );
panel.add( check, BorderLayout.SOUTH );
show( panel );
}
And I made a small addition to the .properties file as well (now called ActionGame2.properties, naturally). allowCountingCheck.text=Allow Counting allowCountingCheck.font=Arial-BOLD-14 The idea is that the check box enables or disables the "Start Counting" button. Simple right? One thing I've learned from watching James Bond is that all world domination plans should be kept as simple as possible. Oh, and don't explain them to the hero until after you
Look Mom, No ActionListeners!All we need now is to somehow tie the state of the checkbox to the button's enabled property. An ActionListener you say? Hmm. Why don't you just step out onto that bridge over the shark tank while I push this big red button here.
With beans binding, there are no action listeners required. Just a minor modification to our
protected void startup(String[] args)
{
...
JButton btn = new JButton();
btn.setName( "startCountingBtn" );
btn.setAction( aMap.get( "startCounting" ) );
JCheckBox check = new JCheckBox();
check.setName( "allowCountingCheck" );
/*** NO ActionListeners ALLOWED!!! ***/
BindingContext context = new BindingContext();
context.addBinding( btn, "${enabled}", check, "selected" );
context.bind();
JPanel panel = new JPanel();
panel.setBorder( BorderFactory.createTitledBorder( rMap.getString( "countingDemo" ) ) );
panel.setLayout( new BorderLayout() );
panel.add( label, BorderLayout.NORTH );
panel.add( btn, BorderLayout.CENTER );
panel.add( check, BorderLayout.SOUTH );
show( panel );
}
Those three little lines with the BindingContext in them are all you need to tie the check box to the button. How's that for slick? But Wait, There's More!My blogs have never been short and to the point. So why start now? There is another cool way to do this. Say you don't want to tie the checkbox directly to the button. Say you need the check box's state to be tracked by a property in some Java bean. Say whatever you want, but I'm going to show this to you anyway.
The first thing we need is a new property in our
private boolean countingAllowed = true;
public boolean isCountingAllowed()
{
return countingAllowed;
}
public void setCountingAllowed(boolean allowed)
{
boolean old = isCountingAllowed();
countingAllowed = allowed;
firePropertyChange( "countingAllowed", old, countingAllowed );
}
Since the app framework's
context.addBinding( this, "${countingAllowed}", check, "selected" );
And viola! Now we are tracking the check box's state through our bean property! Oh, we still need to enable the button don't we. Picky, picky. Actually this gives us a chance to show off another cool feature of the Swing app framework's I Can Disable That Button In 35 Characters
All we need to do is add an
@Action( block = Block.COMPONENT, enabledProperty = "countingAllowed" )
public CountingTask startCounting( ActionEvent ev )
{
return new CountingTask();
}
And that's all there is to it! Now the enabled state of the action is tied to the state of our countingAllowed property. OMG this is, like, so easy! Are you sure this is Swing? The complete source code is listed below.
package playground.swing.framework.actions;
// import lots.of.classes
public class ActionGame2 extends SingleFrameApplication
{
private boolean countingAllowed = true;
public boolean isCountingAllowed()
{
return countingAllowed;
}
public void setCountingAllowed(boolean allowed)
{
boolean old = isCountingAllowed();
countingAllowed = allowed;
firePropertyChange( "countingAllowed", old, countingAllowed );
}
@Action( block = Block.COMPONENT, enabledProperty = "countingAllowed" )
public CountingTask startCounting( ActionEvent ev )
{
return new CountingTask();
}
protected void startup(String[] args)
{
ApplicationActionMap aMap = ApplicationContext.getInstance().getActionMap( getClass(), this );
ResourceMap rMap = ApplicationContext.getInstance().getResourceMap( getClass() );
JLabel label = new JLabel();
label.setName( "titleLabel" );
JButton btn = new JButton();
btn.setName( "startCountingBtn" );
btn.setAction( aMap.get( "startCounting" ) );
JCheckBox check = new JCheckBox();
check.setName( "allowCountingCheck" );
BindingContext context = new BindingContext();
context.addBinding( this, "${countingAllowed}", check, "selected" );
context.bind();
JPanel panel = new JPanel();
panel.setBorder( BorderFactory.createTitledBorder( rMap.getString( "countingDemo" ) ) );
panel.setLayout( new BorderLayout() );
panel.add( label, BorderLayout.NORTH );
panel.add( btn, BorderLayout.CENTER );
panel.add( check, BorderLayout.SOUTH );
show( panel );
}
public static void main( String[] args )
{
Application.launch( ActionGame2.class, args );
}
}
And here are a couple of gratuitous screen shots of our masterpiece.
I'm definitely going to be playing with this new framework a lot over the next few weeks. I wonder what I'll do first when I'm Grand Overlord of the Earth... »
Related Topics >>
Swing Comments
Comments are listed in date ascending order (oldest first)
|
||||||
|
|