Saturday, April 26, 2008

Metawidget and JIDE

Update: the APIs shown in this blog entry have changed slightly in newer releases of Metawidget. Specifically you can now use WidgetBuilders to plug in third-party component libraries. Please download the latest documentation from http://metawidget.org

I was recently asked whether Metawidget can output JIDE components instead of standard Swing ones. The answer is yes! Metawidget makes it easy to support third-party component libraries. Here's how:

Step 1: Derive your own JideMetawidget

Subclass SwingMetawidget and override its buildActiveWidget method to select JIDE components. For example:

package com.myapp.metawidget.jide;

import static org.metawidget.inspector.InspectionResultConstants.*;
import java.util.*;
import javax.swing.*;
import org.metawidget.util.ClassUtils;
import com.jidesoft.spinner.DateSpinner;

public class JideMetawidget extends SwingMetawidget {

   public JComponent buildActiveWidget(Map<String, String> attributes)
      throws Exception {
      String type = attributes.get( TYPE );

      if ( type != null ) {
         Class<?> clazz = ClassUtils.niceForName( type );

         // Use JIDE DateSpinner
         if (Date.class.isAssignableFrom( clazz )) {
            DateSpinner dateSpinner = new DateSpinner();
            dateSpinner.setFormat( "dd/MM/yyyy" );
            return dateSpinner;
         }

      }

      // Not for JIDE
      return super.buildActiveWidget( attributes );
   }
}

That's it! You'll get all the other Metawidget benefits (like layouts, Beans Binding, etc.) for free.

Step 2: Use JideMetawidget in your Application

To try it, download the Metawidget source and update the Swing Address Book example's ContactDialog to say...

final SwingMetawidget metawidget = new JideMetawidget();

...(on about line 135). Run the example, double click on Homer Simpson and you'll see the JIDE DateSpinner component used for the 'Date of Birth' field (previously it was just a JTextField, because vanilla Swing doesn't have a Date picker):


Note: JIDE's DateSpinner doesn't support null values, but
in the Address Book example Date is a nullable field. This causes errors if you click on anything other than Homer Simpson. Note that SwingX's JXDatePicker doesn't have this problem.

4 comments:

Mark Ashworth said...

I was trying to create my own SwingMetawidget class that would create JXDatePicker or JDateEditor components for java.util.Date. The build methods worked but when it came to binding the components the values from the JXDatePicker would not propagate to the bound variable. It might be because both JXDatePicker and JDateEditor do not have a getValue() / setValue() property but a getDate() / setDate(). I looked at creating a stub to resolve the binding but could not figure out how to do this. I also tried sub-classing these components and implementing the missing properties but somehow that also did not work. Is there something I can do to resolve this because JSpinner or JDateSpinner does not like null dates.

Richard said...

Mark,

Thanks for continuing to work with Metawidget.

Funny, we had the exact same question on the forum a couple of days ago from someone else.

Here's a link to it

Regards,

Richard

Mark Ashworth said...

I thought I would just comment here, if other people stumble on this post.

I added the following to get JXDatePicker to work.

public class SwingXMetawidget extends SwingMetawidget {

protected String getValueProperty(Component component) {
if (component instanceof JXDatePicker) {
return "date";
}
return super.getValueProperty(component);
}
}

Richard said...

Thanks, Mark.

If you find time to write a blog about your overall 'Metawidget and JXDatePicker' solution, I'd love to link to it from our Wiki.

Regards,

Richard.