中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Java > 测试
JGoodies: Understanding Binding - Part 1
作者:未知 时间:2005-08-10 22:29 出处:Java频道 责编:chinaitpower
              摘要:JGoodies: Understanding Binding - Part 1
Overview

As of early February, the JGoodies binding framework finally reached 1.0 status. That is good news for nearly anyone who does Swing Java development, whether they know it or not. While the JGoodies Looks and JGoodies Forms frameworks are extremely valuable, I personally feel the binding framework has the potential to be the most powerful and useful in the long term. That is the beauty of JGoodies, however, each component has its place.

The binding framework is well titled. The main goal of this framework is to simplify and unify the process of connecting the state of visual components (such as buttons) with values in your application domain. Before I get too far in, let me link you to Karsten's Data Binding Presentation - it is a great supplement to understanding the intention behind the binding framework, as long as you can fill in the speech behind the slides. In addition, if you dowload the binding framework from here: https://binding.dev.java.net/ - you will be afforded a much more comprehensive set of documentation about what everything is, and when the binding framework is appropriate.

I'd love to be able to provide a short, quick tip to completely sell the binding framework. Unfortunately, I think it will take a little bit more than that. Today I want to talk about what this binding thing is all about, and hopefully given a quick run through; get you all fired up about what it does. Over the next few days, I want to get into more details about using the binding framework given real-world needs. So, what do I mean specifically by 'connecting the state of visual components with values in your application domain'? Well, more often than not, check boxes, text fields, lists, spinners, etc. correlate to values in your application domain. So, next question - what do I mean by 'application domain?'? Typically, your application will have objects that represent the data you are interacting with: Customer, Product, Meeting, Sprocket, yadayadayada. These objects are usually Javabeans (objects with fields, and getters and setters), and are usually what is called 'the domain model' - objects that model the application domain. Ok, enough verbal blathering. Let's get to the point.

The Problem at Hand

As I stated earlier, the binding framework tries to solve the problem of tying components with application objects. So, what is the problem? Well, typically if you wanted to get values from a GUI control down to an application object, you use a listener (such as an ActionListener of a checkbox). The same can be said for getting domain object changes up to the GUI controls. Typically there you would use a PropertyChangeListener or an Observer. One way or another, the goal is for changes on one side to be propagated to the other side. This pattern typically resolves to multiple listeners per property you want to synchronize (one for the way up, the other for the way down). When you get rather complicated beans, this is a cumbersome process at best. Granted, sometimes you only want to move all of the values in one direction or another when the user performs a particular behavior (such as pressing a 'Save' button or a 'Reload' button). Even still, in these cases you have at least two methods you have to write (copy up to GUI, copy down to domain), and they still require some effort to maintain.

If you don't take that route, you can always create adapters for the underlying presentation models on the various components to interact directly with your bean properties. This amounts to creating an implementation of the presentation model interface in question (e.g. ButtonModel) that interacts with the property of your bean. While this is a different approach, I'm not sure it's better. There is still a lot of overhead in this process. Both of these approaches are discussed in the binding presentation I linked to above.

The Binding Framework

Well, then how does the binding framework work? The binding framework acts as an intermediary between the view and your application model. It uses the same techniques on both sides to connect values as I just discussed -on the model side it uses observable or property change listeners depending on your choice, and on the view it adapts the presentation model. The difference is that it does so using an object (or chain of objects) in between that act as a 'universal translator' for both sides. Because the binding framework creates a single intermediary - the com.jgoodies.binding.value.ValueModel interface), both sides only have to interact with it in one common way. The distinction being that the value model always interacts with your bean, and then the presentation model implementations for buttons, text fields, and the like all interact with the value model API. So, to get a quick start for those who may be getting impatient by now, here is how to tie a boolean bean property to a checkbox:

// Example Bean... MyBean.java
import java.beans.PropertyChangeListener;
import com.jgoodies.binding.beans.*;
public class MyBean {
 // Note you don't HAVE to use this class - you can use java.beans.PropertyChangeSupport if you want.
 private ExtendedPropertyChangeSupport changeSupport = new ExtendedPropertyChangeSupport(this);
 private boolean booleanValue;
 
 public boolean getBooleanValue() {
  return booleanValue;
 }
 public void setBooleanValue(boolean newValue) {
  boolean oldValue = booleanValue;
  booleanValue = newValue;
  changeSupport.firePropertyChange("booleanValue", oldValue, newValue); 
 }
 
 public void addPropertyChangeListener(PropertyChangeListener x) {
  changeSupport.addPropertyChangeListener(x);
 }
 
 public void removePropertyChangeListener(PropertyChangeListener x) {
  changeSupport.removePropertyChangeListener(x);
 }
}
 
// Example test class - BindingTest.java
import javax.swing.*;
 
import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.beans.PropertyAdapter;
 
public class BindingTest {
 
 public static void main(String[] args) {
 
  MyBean bean = new MyBean();
  
  // property adapter is implementation of ValueModel
  // this implementation observes property changes on the bean (hence the 'true')
  PropertyAdapter adapter = new PropertyAdapter(bean, "booleanValue", true);
  // creates a JCheckBox with the property adapter providing the underlying model.
  JCheckBox box = BasicComponentFactory.createCheckBox(adapter, "Boolean Value");
  
  JFrame frame = new JFrame();
  frame.getContentPane().add(box);
  frame.pack();
  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  frame.setVisible(true);
 }
}

In the above block of code, all I do is create a property adapter for the property we want to connect, create a component for that property adapter, and put it in our GUI. The rest is taken care of for us. Now, every time the checkbox is checked/unchecked, the 'bean' object will be updated automagically, and likewise, everytime the bean object is updated, the checkbox will be checked/unchecked automagically.

Bean Adapters

In addition to the PropertyAdapter API, there is also the BeanAdapter API which is more efficient when dealing with multiple properties on a single bean. Here is an extended example using the bean adapter:

// Example Bean... MyBean.java
import java.beans.PropertyChangeListener;
 
import com.jgoodies.binding.beans.*;
 
public class MyBean {
 // Note you don't HAVE to use this class - you can use
 // java.beans.PropertyChangeSupport if you want.
 private ExtendedPropertyChangeSupport changeSupport = new ExtendedPropertyChangeSupport(
   this);
 
 private boolean booleanValue;
 private String stringValue;
 
 public boolean getBooleanValue() {
  return booleanValue;
 }
 
 public void setBooleanValue(boolean newValue) {
  System.out.println("Boolean value set: " +newValue);
  boolean oldValue = booleanValue;
  booleanValue = newValue;
  changeSupport.firePropertyChange("booleanValue", oldValue, newValue);
 }
 
 public void addPropertyChangeListener(PropertyChangeListener x) {
  changeSupport.addPropertyChangeListener(x);
 }
 
 public void removePropertyChangeListener(PropertyChangeListener x) {
  changeSupport.removePropertyChangeListener(x);
 }
 
 public String getStringValue() {
  return stringValue;
 }
 
 public void setStringValue(String newValue) {
  System.out.println("String value set: "+  newValue);
  String oldValue = stringValue;
  this.stringValue = newValue;
  changeSupport.firePropertyChange("stringValue", oldValue, newValue);
 }
}
 
// Example test class - BindingTest.java
import java.awt.GridLayout;
 
import javax.swing.*;
 
import com.jgoodies.binding.adapter.BasicComponentFactory;
import com.jgoodies.binding.beans.BeanAdapter;
import com.jgoodies.binding.value.ValueModel;
 
public class BindingTest {
 
 public static void main(String[] args) {
 
  MyBean bean = new MyBean();
  
  // Bean adapter is an adapter that can create many value model objects for a single 
  // bean. It is more efficient than the property adapter. The 'true' once again means 
  // we want it to observe our bean for changes.
  BeanAdapter adapter = new BeanAdapter(bean, true);
  
  ValueModel booleanModel = adapter.getValueModel("booleanValue");
  ValueModel stringModel = adapter.getValueModel("stringValue");
  // creates a JCheckBox with the property adapter providing the underlying model.
  JCheckBox box = BasicComponentFactory.createCheckBox(booleanModel, "Boolean Value");
  JTextField field = BasicComponentFactory.createTextField(stringModel);
  JFrame frame = new JFrame();
  frame.getContentPane().setLayout(new GridLayout(2,1));
  frame.getContentPane().add(box);
  frame.getContentPane().add(field);
  frame.pack();
  frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  frame.setVisible(true);
 }
}

In this example I have added print statements to the bean just to show you how well the binding framework works. Pretty cool, huh?

The last thing I want to mention today in my breakneck tutorial is the two different factory classes - com.jgoodies.binding.adapter.BasicComponentFactory - which you have seen me use here, and com.jgoodies.binding.adapter.Bindings which I haven't mentioned. Where as the BasicComponentFactory creates components and then binds them to a value model, the Bindings class simply does the latter - it lets you provide your own widget implementation:

BasicComponentFactory.createCheckBox(booleanModel); 
// --> equates to:
JCheckBox checkbox = new JCheckBox();
Bindings.bind(checkbox, booleanModel);

The reason I bring this up is because it may be important for you to bind to already constructed widgets, or maybe custom implementations of widgets. In other words, if your application requires you use your own widgets, you can use the Bindings class to hook value models up just the same.

Now, I realize I have only very broadly brushed this subject. I hope, however, I have given you some insight on how to bind bean properties to GUI controls. I plan to cover some more complicated topics over the coming tips, so stay tuned!

Until next time,

R.J. Lorimer

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有