All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.tidalwave.metadata.viewer.PaneSupport Maven / Gradle / Ivy

/*******************************************************************************
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 *******************************************************************************/

package it.tidalwave.metadata.viewer;

import javax.annotation.Nonnull;
import java.beans.PropertyChangeListener;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JPanel;
import it.tidalwave.beans.AbstractEnhancer.PropertyFilter;
import it.tidalwave.beans.JavaBeanEnhancer;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.metadata.viewer.impl.Syncer;

/*******************************************************************************
 *
 * @author  Fabrizio Giudici
 * @version $Id: $
 *
 ******************************************************************************/
public class PaneSupport extends JPanel
  {
    private static final String CLASS = PaneSupport.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS);

    private static final JavaBeanEnhancer JAVA_BEAN_ENHANCER = new JavaBeanEnhancer();

    /** The class of the managed bean. */
    @Nonnull
    private final Class beanClass;

    /** A bean that is EDT compliant - i.e. you can change it from any thread. */
    @Nonnull
    private final Bean edtBean;

    /** This synchronizer detects changes in the bound bean and updates the internal bean in the EDT. */
    private Syncer inboundSyncer;

    /** This synchronizer detects changes in the internal bean and updates the external bean in a separate thread. */
    private Syncer outboundSyncer;

    /***************************************************************************
     *
     *
     **************************************************************************/
    protected PaneSupport (@Nonnull final Class beanClass,
                           @Nonnull final PropertyFilter propertyFilter)
      {
        this.beanClass = beanClass;

        try
          {
            if (isJavaBean(beanClass))
              {
                edtBean = beanClass.newInstance();
              }
            else
              {
                edtBean = (Bean)JAVA_BEAN_ENHANCER.createEnhancedBean(beanClass.newInstance(), JavaBeanEnhancer.EDT_COMPLIANT, propertyFilter);
              }
          }
        catch (InstantiationException e)
          {
            throw new IllegalArgumentException(e);
          }
        catch (IllegalAccessException e)
          {
            throw new IllegalArgumentException(e);
          }
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    public void bind (@Nonnull Bean bean)
      throws IllegalArgumentException
      {
        logger.info("bind(%s)", bean);
        validateBean(bean);

        if (inboundSyncer != null)
          {
            inboundSyncer.unbind();
          }

        if (outboundSyncer != null)
          {
            outboundSyncer.unbind();
          }

        preBind(bean);
        inboundSyncer = new Syncer("inbound", bean, edtBean, true, true);
        outboundSyncer = new Syncer("outbound", edtBean, bean, false, false);
        inboundSyncer.bind();
        outboundSyncer.bind();
        postBind(bean);
      }

    /***************************************************************************
     *
     * Returns a reference to the EDT-safe bean. It can be used to bind
     * components in Matisse.
     *
     * @return  the EDT-safe bean
     *
     **************************************************************************/
    @Nonnull
    public final Bean getEDTBean()
      {
        return edtBean;
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    @Override
    public void setForeground (@Nonnull final Color color)
      {
        super.setForeground(color);

        for (final Component component : getComponents())
          {
            component.setForeground(color);
          }
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    protected void preBind (@Nonnull final Bean bean)
      {
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    protected void postBind (@Nonnull final Bean bean)
      {
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    private void validateBean (@Nonnull final Bean bean)
      {
        if (!isJavaBean(bean.getClass()))
          {
            throw new IllegalArgumentException(String.format(
                    "bean not valid %s %s, doesn't support PropertyChangeListener", bean, beanClass));
          }
      }

    /***************************************************************************
     *
     *
     **************************************************************************/
    private boolean isJavaBean (@Nonnull final Class beanClass)
      {
        try
          {
            beanClass.getMethod("addPropertyChangeListener", PropertyChangeListener.class);
            return true;
          }
        catch (NoSuchMethodException e)
          {
            return false;
          }
      }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy