diff --git a/projects/samskivert/src/java/com/samskivert/swing/util/ButtonUtil.java b/projects/samskivert/src/java/com/samskivert/swing/util/ButtonUtil.java index c2d461e7..bcbc9e21 100644 --- a/projects/samskivert/src/java/com/samskivert/swing/util/ButtonUtil.java +++ b/projects/samskivert/src/java/com/samskivert/swing/util/ButtonUtil.java @@ -1,12 +1,22 @@ // -// $Id: ButtonUtil.java,v 1.1 2002/12/04 23:58:22 ray Exp $ +// $Id: ButtonUtil.java,v 1.2 2002/12/14 02:11:24 mdb Exp $ package com.samskivert.swing.util; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import javax.swing.AbstractButton; +import javax.swing.JToggleButton; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; + +import com.samskivert.util.Config; /** * Utilities for buttons. @@ -32,6 +42,80 @@ public class ButtonUtil b.addActionListener(_toggler); } + /** + * Binds the supplied button to the named boolean property in the + * supplied config repository. When the button is pressed, it will + * update the config property and when the config property is changed + * (by the button or by other means) it will update the selected state + * of the button. When the button is made non-visible, it will be + * unbound to the config's property and rebound again if it is once + * again visible. + */ + public static void bindToProperty ( + String property, Config config, AbstractButton button, boolean defval) + { + // create a config binding which will take care of everything + new ButtonConfigBinding(property, config, button, defval); + } + + /** Used for {@link #bindToProperty}. */ + protected static class ButtonConfigBinding + implements AncestorListener, PropertyChangeListener, ItemListener + { + public ButtonConfigBinding (String property, Config config, + AbstractButton button, boolean defval) + { + _property = property; + _config = config; + _button = button; + _defval = defval; + + // wire ourselves up to the button + button.addAncestorListener(this); + button.addItemListener(this); + + // if this is not already a toggle button, we'll need to make + // it toggle + if (!(button instanceof JToggleButton)) { + setToggling(button); + } + } + + public void ancestorAdded (AncestorEvent event) { + // listen for config changes + _config.addPropertyChangeListener(_property, this); + // set the button up appropriately + _button.setSelected(_config.getValue(_property, _defval)); + } + + public void ancestorRemoved (AncestorEvent event) { + // stop listening for config changes + _config.removePropertyChangeListener(_property, this); + } + + public void ancestorMoved (AncestorEvent event) { + // nothing doing + } + + public void propertyChange (PropertyChangeEvent event) { + // update the button + if (event.getPropertyName().equals(_property)) { + Boolean value = (Boolean)event.getNewValue(); + _button.setSelected(value.booleanValue()); + } + } + + public void itemStateChanged (ItemEvent event) { + boolean selected = (event.getStateChange() == ItemEvent.SELECTED); + _config.setValue(_property, selected); + } + + protected String _property; + protected Config _config; + protected AbstractButton _button; + protected boolean _defval; + } + /** Our lazily-initialized toggling action listener. */ protected static ActionListener _toggler; }