Java Database Application Library

Get JDAL (Java Database Application Library) at Fast, secure and Free Open Source software downloads



AbstractView is the principal template ( Template , GoF) of JDAL Swing. Although it is possible to use the different functions provided by JDAL Swing in an independent form, AbstractView permits you condense the development work of forms in one unique job: Implement the method buildPanel().

AbstractView supports the automatic way of the following commune jobs in the development of Swing forms:

The process of building a form based on Abstractview can be summarised in the following steps:

Data Binding

AbstractView supports at the moment two forms of realizing the binding of data between user interface controls and the domain models:

In both cases, in creating binding between a Swing component and a property of the model, it will undertake the following actions:


Finally, AbstractView provides three template methods to customize the data binding process:


AbstractView delegates much of the work in strategies or support classes of JDAL. It is interesting to take a look as you might be interested in using them directly o personalising the behaviours.


Performs all work in data binding between the conttols and models. It can be used independently outside of AbstractView. It is not necessary to extend JDAL classes to dispose of data binding system. You can find more information in the data binding chapter..


Processing strategy of binding errors. The implementation by default, BackgroundErrorProcessor changes the colour of the background of the controls that have failed and add a tooltip with the information of the error.


PropertyBinder factory, CompositeBinder uses it to find the Binder appropriate for each type of control.


Allow access to generic Swing controls. That is to say, perform control operations without the specific knowledge of the type of control.


Strategy of control initialization, usually with data from the respositories or other entities. The implementatión by default DefaultControlInitializer is able to detect annotationes JPA and the annotation @Reference of JDAL Core.



We will create a View for the following Project entity:

public class Project  {
	protected Long id;     
	protected String name = ""; 
	private Company customer;
	private Double amount;
	private Bid bid;
	private String description;
	private Set<Work> works;
	@OneToMany(mappedBy="project", targetEntity=ProjectAttachment.class, cascade=CascadeType.ALL, orphanRemoval=true)
	private List<Attachment> attachments;
	private Set<User> users;
	// Accessors, Mutators and Behavior Omited.


The target objective is to create a form to edit projects with the following specification:/p>

The following is the code of the projects form using AbstracView

public class ProjectView extends AbstractView<Project> {
	private JTextField name = new JTextField();
	private JComboBox customer = new JComboBox();
	private JComboBox bid = new JComboBox();
	private JTextField amount = new JTextField();
	private JTextArea description = new JTextArea(5, 0);
	/** ManyToMany editor */
	private Selector<User> users = new Selector<User>();
	/** inner view to show edit attachments */
	private AttachmentView attachments;
	/** service to initialize entities */
	private PersistentService<Project, Long> service;
	public ProjectView() {
		this(new Project());
	 * @param model 
	public ProjectView(Project model) {
	 * Init method, called by container after property sets
	public void init() {
		service.initialize(getModel());   // initialize model, ie drop Hibernate Proxies
		getControlInitializer().setInitializeEntities(true);  /
		users.init();  // initialize Selector
		autobind();    // the binding code, bid, "bids");  // link customer and bids
	 * {@inheritDoc}
	protected JComponent buildPanel() {
		// create a Box form builder to build the form
		BoxFormBuilder fb  = new BoxFormBuilder(FormUtils.createTitledBorder(getMessage("Project.title")));
		fb.startBox();    // first Box (name, customer, bid and amount
		fb.setFixedHeight(true); //  fixed height on resizes
		fb.add(getMessage("Name"), name);
		fb.add(getMessage("Customer"), customer);
		fb.add(getMessage("Bid"), bid);
		fb.add(getMessage("Amount"), amount);
		fb.endBox();     // end first box
		fb.startBox();   // second box for description
		fb.row(Short.MAX_VALUE);    // let this row to be as higher as it can.
		fb.add(new JScrollPane(description));
		fb.endBox();     // end second box
		fb.startBox();   // third box for user selector 
		fb.add(new SeparatorTitled(getMessage("Users")));
		fb.row(Short.MAX_VALUE);  // let this row to be as higher as it can.
		fb.endBox();     // end third box
		fb.startBox();   // last box for attachment
		fb.add(new SeparatorTitled(getMessage("Attachments")));
		fb.row(Short.MAX_VALUE);  // let this row to be as higher as it can.
		fb.endBox();    // end last box.
		return = fb.getForm();  // return the JCompoenent
	 * {@inheritDoc}
	public void onSetModel(Project project) {
		if (service != null)
	 * @return the service
	public PersistentService<Project, Long> getService() {
		return service;
	 * @param service the service to set
	public void setService(PersistentService<Project, Long> service) {
		this.service = service;

Context Configuration

<!-- Persistent Serivice for Projects -->    
<jdal:service entity="info.joseluismartin.gefa.model.Project"/> 
<!-- Generic context service -->
<bean id="contextService" class="info.joseluismartin.logic.ContextPersistentManager" />
<!-- Configure factories and related swing dependences -->
<swing:defaults /> 
<!-- JSR-303 Validation -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="errorProcessor" class="info.joseluismartin.gui.validation.BackgroundErrorProcessor" />
 <!-- Actions -->
 <bean id="acceptAction" class="info.joseluismartin.gui.action.ViewSaveAction" scope="prototype">
        <property name="icon" value="/images/16x16/dialog-ok.png"/>
        <property name="service" ref="objectService"/>
        <property name="name" value="Accept"/>
 <bean id="cancelAction" class="info.joseluismartin.gui.action.DialogCancelAction" scope="prototype">
        <property name="icon" value="/images/16x16/dialog-cancel.png"/>
        <property name="name" value="Cancel"/>
 <!-- Base definition for Editors  -->
 <bean id="editor" abstract="true" >
        <property name="acceptAction" ref="acceptAction" />
        <property name="cancelAction" ref="cancelAction" />
        <property name="dialogWidth" value="800" />
        <property name="dialogHeight" value="600" />
 <!-- Base definition for Views -->  
 <bean id="view" abstract="true" >
        <property name="controlAccessorFactory" ref="controlAccessorFactory" />
        <property name="binderFactory" ref="binderFactory" />
        <property name="controlInitializer" ref="controlInitializer" />
        <property name="validator"  ref="validator" />
        <property name="errorProcessors">
                <ref bean="errorProcessor" />
 <!--  Default Control Initializer -->
 <bean id="controlInitializer" class="info.joseluismartin.gui.bind.AnnotationControlInitializer">
        <property name="persistentService" ref="contextService" />
<!-- Our Project View -->
<bean id="projectView" class="info.joseluismartin.gefa.ui.ProjectView" parent="view" scope="prototype" >
        <property name="service" ref="projectService" />
<!-- Our Project Editor -->
<bean id="projectEditor" class="info.joseluismartin.gui.ViewDialog" parent="editor" scope="prototype">
        <property name="view" ref="projectView" />

Now, we can get instances of the project editor by the bean "projectEditor".