Package com.starlight.ui

Source Code of com.starlight.ui.ValueChangeRelay$InnerListener

/*
* Copyright(c) 2002-2004, StarLight Systems
* All rights reserved.
*/
package com.starlight.ui;

import com.starlight.listeners.ListenerSupport;
import com.starlight.listeners.ListenerSupportFactory;
import org.jdesktop.swingx.JXDatePicker;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.JTextComponent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;


/**
* Provides and easy way to listen for changes in value for any of a bunch of components.
* It will fire an event when a values are different.
*/
@SuppressWarnings( "UnusedDeclaration" )
public class ValueChangeRelay<K> {
  private final ListenerSupport<ValueChangeListener,?> vcr_listeners;
 
  private final InnerListener<K> inner_listener;

  public ValueChangeRelay( ValueChangeListener<K> listener ) {
    vcr_listeners =
      ListenerSupportFactory.create( ValueChangeListener.class, false );
    vcr_listeners.add( listener );

    this.inner_listener = new InnerListener<K>( vcr_listeners.dispatch() );
  }


  public void addListener( ValueChangeListener<K> listener ) {
    vcr_listeners.add( listener );
  }


  public void removeListener( ValueChangeListener<K> listener ) {
    vcr_listeners.remove( listener );
  }


  /**
   * Temporarily disable event notifications. Example:
   * <pre>
   * ValueChangeRelay vcr = ...
   *
   * vcr.disable();
   * try {
   *   // Make a bunch of modifications to fields that you
   *   // don't want to be notified about.
   * }
   * finally {
   *   vcr.enable();
   * }
   * </pre>
   */
  public void disable() {
    inner_listener.enabled = false;
  }

  /**
   * Enable event notifications.
   * <pre>
   * ValueChangeRelay vcr = ...
   *
   * vcr.disable();
   * try {
   *   // Make a bunch of modifications to fields that you
   *   // don't want to be notified about.
   * }
   * finally {
   *   vcr.enable();
   * }
   * </pre>
   */
  public void enable() {
    inner_listener.enabled = true;
  }

  public boolean isEnabled() {
    return inner_listener.enabled;
  }


  /**
   * Add a new component to be monitored for changes.
   *
   * @param new_component    The component to be watched.
   * @param key        A key to help identify the component.
   */
  public void add( final JComponent new_component, final K key ) {
    if ( new_component == null )
      throw new IllegalArgumentException( "Component cannot be null." );

    if ( new_component instanceof ValueChangeSource ) {
      final ValueChangeSource source = ( ValueChangeSource ) new_component;
      source.addValueChangeListener( new ValueChangeListener() {
        @Override
        public void valueChanged( JComponent component, Object inner_key,
          Object new_value ) {

          inner_listener.valueChanged( new_component, key, new_value );
        }
      } );
    }
    else if ( new_component instanceof AddRemovePanel ) {
      final AddRemovePanel panel = ( AddRemovePanel ) new_component;
      panel.addListDataListener( new ListDataListener() {
        public void contentsChanged( ListDataEvent e ) {
          inner_listener.valueChanged( new_component, key,
            panel.getItems() );
        }

        public void intervalAdded( ListDataEvent e ) {
          inner_listener.valueChanged( new_component, key,
            panel.getItems() );
        }

        public void intervalRemoved( ListDataEvent e ) {
          inner_listener.valueChanged( new_component, key,
            panel.getItems() );
        }
      } );
    }
    else if ( new_component instanceof JFormattedTextField ) {
      final JFormattedTextField text = ( JFormattedTextField ) new_component;
      new_component.addPropertyChangeListener( "value",
        new FormattedTextFieldPCListener( text.getValue(), new_component,
        key ) );
//      new_component.addPropertyChangeListener( "editValid",
//        new FormattedTextFieldPCListener( text.getValue(), new_component,
//        key ) );
//      text.getDocument().addDocumentListener( new DocumentListener() {
//        public void insertUpdate( DocumentEvent e ) {
//          checkUpdate();
//        }
//
//        public void removeUpdate( DocumentEvent e ) {
//          checkUpdate();
//        }
//
//        public void changedUpdate( DocumentEvent e ) {
//          checkUpdate();
//        }
//
//        private void checkUpdate() {
//          if ( !text.isEditValid() ) return;
//
//          // See if it's the mask
//          if ( text.getFormatter() instanceof MaskFormatter ) {
//            MaskFormatter mformatter = ( MaskFormatter ) text.getFormatter();
//            String text_text = text.getText();
//
//            try {
//              if ( MiscKit.equal( text_text, mformatter.getMask() ) ||
//                MiscKit.equal( text_text, mformatter.getPlaceholder() ) ||
//                MiscKit.equal( text_text, mformatter.valueToString( null ) ) ) {
//
//                return;
//              }
//            }
//            catch( ParseException ex ) {}
//          }
//
//          try {
//            text.commitEdit();
//          }
//          catch( ParseException ex ) {
//            System.err.println( "Failed to commit: \"" + text.getText() +
//              "\" (" + text.getFormatter().getClass().getName() + ")" );
//            ex.printStackTrace();
//            return;
//          }
//
//          System.out.println( "FTF edit valid: " + text.getValue() );
//          inner_listener.valueChanged( text, key, text.getValue() );
//        }
//      } );
    }
    else if ( new_component instanceof JTextComponent ) {
      final JTextComponent text_component = ( JTextComponent ) new_component;
      ( ( JTextComponent ) new_component ).getDocument().addDocumentListener(
        new DocumentListener() {
          public void insertUpdate( DocumentEvent e ) {
            inner_listener.valueChanged( new_component, key,
              text_component.getText() );
          }

          public void removeUpdate( DocumentEvent e ) {
            inner_listener.valueChanged( new_component, key,
              text_component.getText() );
          }

          public void changedUpdate( DocumentEvent e ) {
            inner_listener.valueChanged( new_component, key,
              text_component.getText() );
          }
        } );
    }
    else if ( new_component instanceof JComboBox ) {
      ( ( JComboBox ) new_component ).addItemListener( new ItemListener() {
        public void itemStateChanged( ItemEvent e ) {
          JComboBox box = ( JComboBox ) e.getItemSelectable();

          // Fire in two cases:
          //   - If it's a selection event
          //   - It's a deselection event and the new selection is null.
          // We do this because no selection event is fired if null is selected.
          if ( e.getStateChange() == ItemEvent.SELECTED ||
            box.getSelectedItem() == null ) {

            inner_listener.valueChanged( new_component, key,
              ( ( JComboBox ) e.getItemSelectable() ).getSelectedItem() );
          }
        }
      } );
    }
    else if ( new_component instanceof JList ) {
      final JList list = ( JList ) new_component;
      ( ( JList ) new_component ).addListSelectionListener( new ListSelectionListener() {
        public void valueChanged( ListSelectionEvent e ) {
          if ( e.getValueIsAdjusting() ) return;

          inner_listener.valueChanged( new_component, key,
            list.getSelectedValuesList() );
        }
      } );
    }
    else if ( new_component instanceof JSpinner ) {
      final JSpinner spinner = ( JSpinner ) new_component;
      ( ( JSpinner ) new_component ).addChangeListener( new ChangeListener() {
        public void stateChanged( ChangeEvent e ) {
          inner_listener.valueChanged( new_component, key, spinner.getValue() );
        }
      } );
    }
    else if ( new_component instanceof JToggleButton ) {
      ( ( JToggleButton ) new_component ).addItemListener( new ItemListener() {
        public void itemStateChanged( ItemEvent e ) {
          inner_listener.valueChanged( new_component, key,
            Boolean.valueOf( e.getStateChange() == ItemEvent.SELECTED ) );
        }
      } );
    }
    else if ( new_component instanceof JSlider ) {
      final JSlider slider = ( JSlider ) new_component;
      slider.addChangeListener( new ChangeListener() {
        public void stateChanged( ChangeEvent e ) {
          inner_listener.valueChanged( slider, key,
            Integer.valueOf( slider.getValue() ) );
        }
      } );
    }
    else if ( new_component instanceof JXDatePicker ) {
      final JXDatePicker picker = ( JXDatePicker ) new_component;
      picker.addPropertyChangeListener( "date", new PropertyChangeListener() {
        public void propertyChange( PropertyChangeEvent evt ) {
          inner_listener.valueChanged( picker, key, picker.getDate() );
        }
      }  );

    }
    else {
      throw new IllegalArgumentException( "Unsupported component type: " +
        new_component.getClass().getName() );
    }
  }


  /**
   * Convenience method equivalent to:
   * <pre>
   * add( component, component );
   * </pre>
   * Note that this assume a key type of JComponent or some compatible type
   * (can be untyped).
   */
  public void add( JComponent component ) {
    add( component, ( K ) component );
  }


  /**
   * Add a button group whose buttons will be monitored for changes. Note that changes
   * to the buttons in the group will not be seen after the group is added. (Sorry,
   * the ButtonGroup class is kind of stupid.)
   *
   * @param group        The ButtonGroup to be watched.
   * @param key        A key to help identify the component.
   */
  public void add( final ButtonGroup group, final K key ) {
    Enumeration enoom = group.getElements();
    while( enoom.hasMoreElements() ) {
      AbstractButton button = ( AbstractButton ) enoom.nextElement();
      add( button, key );
    }
  }


  public static interface ValueChangeListener<K> {
    public void valueChanged( JComponent component, K key, Object new_value );
  }


  public static interface ValueChangeSource<K> {
    public void addValueChangeListener( ValueChangeListener<K> listener );
  }


  private class InnerListener<K> implements ValueChangeListener<K> {
    boolean enabled = true;

    private ValueChangeListener<K> listener;

    InnerListener( ValueChangeListener<K> listener ) {
      this.listener = listener;
    }

    public void valueChanged( JComponent component, K key, Object new_value ) {
      if ( !enabled ) return;

      listener.valueChanged( component, key, new_value );
    }
  }


  private class FormattedTextFieldPCListener implements PropertyChangeListener {
    private Object initial_value;
    private JComponent component;
    private K key;

//    private boolean fire_mode = false;

    FormattedTextFieldPCListener( Object inital_value, JComponent component,
      K key ) {

      this.initial_value = inital_value;
      this.component = component;
      this.key = key;
    }

    public void propertyChange( PropertyChangeEvent evt ) {
//      if ( !fire_mode ) {
//        if ( MiscKit.equal( initial_value, evt.getNewValue() ) ) return;
//
//        fire_mode = false;
//      }

      inner_listener.valueChanged( component, key, evt.getNewValue() );
    }
  }
}
TOP

Related Classes of com.starlight.ui.ValueChangeRelay$InnerListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.