home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-18 | 15.2 KB | 488 lines |
- package symantec.itools.awt;
-
- import java.awt.Panel;
- import java.awt.Checkbox;
- import java.awt.CheckboxGroup;
- import java.awt.Component;
- import java.awt.AWTEventMulticaster;
- import java.awt.event.ItemEvent;
- import java.awt.event.ItemListener;
- import java.util.Vector;
- import java.beans.PropertyVetoException;
- import java.beans.PropertyChangeListener;
- import java.beans.VetoableChangeListener;
- import java.beans.PropertyChangeEvent;
- import java.util.ResourceBundle;
-
- // 01/27/97 RKM Changed moveIntoGroup to preserve checkbox's state
- // 01/29/97 TWB Integrated changes from Windows and RKM's changes
- // 01/29/97 TWB Integrated changes from Macintosh
- // 06/01/97 RKM Updated to support Java 1.1
- // Updated mechanism to keep track of contents of panel
- // 09/10/97 LAB Made it extend BorderPanel to give it BorderPanel's properties (Addresses Mac
- // Bug #3086). Made it fire an ItemEvent when the "station" changes (Addresses
- // Mac Bug #3093).
- // 10/05/97 LAB Added mechanism for values passed to setSelectedRadioButtonIndex to be
- // validated on each call to addImpl to avoid code-gen order specific
- // dependencies.
-
- /**
- * Creates an rectangular panel area that automatically groups
- * the RadioButtons that it contains.
- * <p>
- * All the RadioButtons within the RadioButtonGroupPanel act together. Only
- * one of the RadioButtons can be "on" at a time.
- * <p>
- * @version 1.1, August 22, 1997
- * @author Symantec
- */
- public class RadioButtonGroupPanel extends BorderPanel implements java.awt.ItemSelectable
- {
- /**
- * Constructs a RadioButtonGroupPanel.
- */
- public RadioButtonGroupPanel()
- {
- group = new CheckboxGroup();
- try
- {
- setPaddingTop(0);
- setPaddingBottom(0);
- setPaddingLeft(0);
- setPaddingRight(0);
- }
- catch (PropertyVetoException exc) {}
-
- rbList = new Vector();
- item = new IL();
- tempSelectionIndex = -1;
- }
-
- /**
- * Returns the selected items or null if no items are selected.
- */
- public Object[] getSelectedObjects()
- {
- Object object[] = {getSelectedRadioButton()};
- return object;
- }
-
- /**
- * Sets the current choice to the specified RadioButton.
- * @param rb the current RadioButton (CheckBox) choice
- * @exception PropertyVetoException if the recipient wishes the property
- * change to be rolled back.
- */
- public synchronized void setSelectedRadioButton(Checkbox rb) throws PropertyVetoException
- {
- Checkbox oldValue = getSelectedRadioButton();
- if(! symantec.itools.util.GeneralUtils.objectsEqual(rb, oldValue))
- {
- vetos.fireVetoableChange("selectedRadioButton", oldValue, rb);
-
- group.setSelectedCheckbox(rb);
- //Fire an event to our listeners, since the previous line doensn't seem to result in an event being fired.
- sourceItemEvent(rb);
-
- changes.firePropertyChange("selectedRadioButton", oldValue, getSelectedRadioButton());
- }
- }
-
- /**
- * Gets the current choice.
- */
- public Checkbox getSelectedRadioButton()
- {
- return group.getSelectedCheckbox();
- }
-
- /**
- * Sets the current choice to the specified RadioButton.
- * @param index the index of the RadioButton to be the selected.
- * @see #getSelectedRadioButtonIndex
- * @exception PropertyVetoException if the recipient wishes the property
- * change to be rolled back.
- */
- public synchronized void setSelectedRadioButtonIndex(int index) throws PropertyVetoException
- {
- tempSelectionIndex = index;
- if(isAdded)
- {
- Integer oldValue = new Integer(getSelectedRadioButtonIndex());
- if(oldValue.intValue() != index)
- {
- Integer newValue = new Integer(index);
- vetos.fireVetoableChange("selectedRadioButtonIndex", oldValue, newValue);
-
- setSelectedRadioButton((Checkbox)rbList.elementAt(index));
-
- changes.firePropertyChange("selectedRadioButtonIndex", oldValue, newValue);
- }
- }
- }
-
- /**
- * Gets the index of the current choice.
- * @return the index of the selected RadioButton. -1 if no selection.
- * @see #setSelectedRadioButtonIndex
- */
- public int getSelectedRadioButtonIndex()
- {
- Checkbox cb = getSelectedRadioButton();
- if(cb != null && rbList.contains(cb))
- {
- for(int i = 0; i < rbList.size(); i++)
- {
- if((Checkbox)rbList.elementAt(i) == cb)
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Returns the String representation of this RadioButtonGroup's values.
- * Convert to String.
- */
- public String toString()
- {
- return getClass().getName() + "[selectedRadioButton=" + getSelectedRadioButton() + "]";
- }
-
- /**
- * Removes the component at the specified index from this container.
- * @param index the index of the component to be removed
- * @see java.awt.Container#add
- */
- public void remove(int index)
- {
- Component comp = getComponent(index);
-
- if(comp instanceof Checkbox)
- {
- ((Checkbox)comp).removeItemListener(item);
- //Remove it from out internal list.
- rbList.removeElement(comp);
- }
-
- super.remove(index);
- }
-
- /**
- * Removes all the components from this container.
- * @see java.awt.Container#add
- * @see #remove
- */
- public void removeAll()
- {
- Component[] comp = getComponents();
-
- for (int i = 0; i < comp.length; ++i)
- {
- if(comp[i] instanceof Checkbox)
- ((Checkbox)comp[i]).removeItemListener(item);
- }
-
- //Reset our internal list.
- rbList = new Vector();
-
- super.removeAll();
- }
-
- /**
- * Tells this component that it has been added to a container.
- * This is a standard Java AWT method which gets called by the AWT when
- * this component is added to a container. Typically, it is used to
- * create this component's peer.
- *
- * It has been overridden here to hook-up event listeners.
- *
- * @see #removeNotify
- */
- public synchronized void addNotify()
- {
- super.addNotify();
- errors = ResourceBundle.getBundle("symantec.itools.resources.ErrorsBundle");
-
- //Hook up listeners
- if (indexVeto == null)
- {
- indexVeto = new IV();
- addSelectedRadioButtonIndexListener(indexVeto);
- }
- isAdded = true;
- }
-
- /**
- * Tells this component that it is being removed from a container.
- * This is a standard Java AWT method which gets called by the AWT when
- * this component is removed from a container. Typically, it is used to
- * destroy the peers of this component and all its subcomponents.
- *
- * It has been overridden here to unhook event listeners.
- *
- * @see #addNotify
- */
- public synchronized void removeNotify()
- {
- //Unhook listeners
- if (indexVeto != null)
- {
- removeSelectedRadioButtonIndexListener(indexVeto);
- indexVeto = null;
- }
-
- super.removeNotify();
- }
-
- /**
- * Adds a listener for all event changes.
- * @param listener the listener to add.
- * @see #removePropertyChangeListener
- */
- public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
- {
- super.addPropertyChangeListener(listener);
- changes.addPropertyChangeListener(listener);
- }
-
- /**
- * Removes a listener for all event changes.
- * @param listener the listener to remove.
- * @see #addPropertyChangeListener
- */
- public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
- {
- super.removePropertyChangeListener(listener);
- changes.removePropertyChangeListener(listener);
- }
-
- /**
- * Adds a vetoable listener for all event changes.
- * @param listener the listener to add.
- * @see #removeVetoableChangeListener
- */
- public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
- {
- super.addVetoableChangeListener(listener);
- vetos.addVetoableChangeListener(listener);
- }
-
- /**
- * Removes a vetoable listener for all event changes.
- * @param listener the listener to remove.
- * @see #addVetoableChangeListener
- */
- public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
- {
- super.removeVetoableChangeListener(listener);
- vetos.removeVetoableChangeListener(listener);
- }
-
- /**
- * Adds a listener for the SelectedRadioButtonIndex property changes.
- * @param listener the listener to add.
- * @see #removeSelectedRadioButtonIndexListener(java.beans.PropertyChangeListener)
- */
- public synchronized void addSelectedRadioButtonIndexListener(PropertyChangeListener listener)
- {
- changes.addPropertyChangeListener("selectedRadioButtonIndex", listener);
- }
-
- /**
- * Removes a listener for the SelectedRadioButtonIndex property changes.
- * @param listener the listener to remove.
- * @see #addSelectedRadioButtonIndexListener(java.beans.PropertyChangeListener)
- */
- public synchronized void removeSelectedRadioButtonIndexListener(PropertyChangeListener listener)
- {
- changes.removePropertyChangeListener("selectedRadioButtonIndex", listener);
- }
-
- /**
- * Adds a vetoable listener for the SelectedRadioButtonIndex property changes.
- * @param listener the listener to add.
- * @see #removeSelectedRadioButtonIndexListener(java.beans.VetoableChangeListener)
- */
- public synchronized void addSelectedRadioButtonIndexListener(VetoableChangeListener listener)
- {
- vetos.addVetoableChangeListener("selectedRadioButtonIndex", listener);
- }
-
- /**
- * Removes a vetoable listener for the SelectedRadioButtonIndex property changes.
- * @param listener the listener to remove.
- * @see #addSelectedRadioButtonIndexListener(java.beans.VetoableChangeListener)
- */
- public synchronized void removeSelectedRadioButtonIndexListener(VetoableChangeListener listener)
- {
- vetos.removeVetoableChangeListener("selectedRadioButtonIndex", listener);
- }
-
- /**
- * Adds the specified item listener to receive item events
- * from this component.
- * @param l the item listener
- * @see #removeItemListener
- */
- public synchronized void addItemListener(ItemListener l)
- {
- itemListener = AWTEventMulticaster.add(itemListener, l);
- }
-
- /**
- * Removes the specified Item listener so it no longer receives
- * Item events from this component.
- * @param l the action listener
- * @see #addItemListener
- */
- public synchronized void removeItemListener(ItemListener l)
- {
- itemListener = AWTEventMulticaster.remove(itemListener, l);
- }
-
- /**
- * This is the Item Event handling innerclass.
- */
- class IL implements java.awt.event.ItemListener
- {
- /**
- * Handles Item State Changed events
- * @param e the ItemEvent
- */
- public void itemStateChanged(ItemEvent e)
- {
- sourceItemEvent((Checkbox) e.getSource());
- }
- }
-
- /**
- * This is the PropertyChangeEvent handling inner class for the constrained SelectedRadioButtonIndex property.
- * Handles vetoing SelectedRadioButtonIndex indexes that are not valid.
- */
- class IV implements java.beans.VetoableChangeListener, java.io.Serializable
- {
- /**
- * This method gets called when an attempt to change the constrained Frame property is made.
- * Ensures the given Frame string is valid for this button.
- *
- * @param e a <code>PropertyChangeEvent</code> object describing the
- * event source and the property that has changed.
- * @exception PropertyVetoException if the recipient wishes the property
- * change to be rolled back.
- */
- public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
- {
- int i = ((Integer)e.getNewValue()).intValue();
- if (!isValidSelectedRadioButtonIndex(i))
- {
- throw new PropertyVetoException(errors.getString("InvalidSelectedRadioButtonIndex") + i, e);
- }
- }
- }
-
- /**
- * Is the given index value valid.
- * @param index the given index to test
- * @return true if the given index is acceptable, false if not.
- * To be valid it has to be within the limits of the rbList:
- */
- protected boolean isValidSelectedRadioButtonIndex(int index)
- {
- if(rbList != null && index < rbList.size() && index >= 0)
- return true;
- else
- return false;
- }
-
- /**
- * Fires an item event to the listeners.
- * @param item the radio button that changed state
- */
- protected void sourceItemEvent(Checkbox item)
- {
- if(item != lastItem)
- {
- if (itemListener != null)
- itemListener.itemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, item, (item.getState() ? ItemEvent.SELECTED : ItemEvent.DESELECTED)));
- lastItem = item;
- }
- }
-
- protected void addImpl(Component component, Object constraints, int index)
- {
- moveIntoGroup(component);
-
- super.addImpl(component,constraints,index);
- if(isValidSelectedRadioButtonIndex(tempSelectionIndex))
- try { setSelectedRadioButtonIndex(tempSelectionIndex); } catch (PropertyVetoException exc) { /*Silently verify.*/ }
-
- }
-
- /**
- * Internal helper method.
- * Adds the given Checkbox into this panel's CheckboxGroup without changing
- * its "selected" state.
- * @param component the Checkbox to add to this RadioButtonGroupPanel
- */
- protected void moveIntoGroup(Component component)
- {
- if(!(component instanceof Checkbox))
- {
- return;
- }
-
- //Cast the component to a checkbox
- Checkbox checkBox = ((Checkbox)component);
-
- //Save the state
- boolean savedState = checkBox.getState();
-
- //Set up the checkbox group
- checkBox.setCheckboxGroup(group);
-
- //Restore the state if it was true
- if (savedState)
- checkBox.setState(savedState);
-
- checkBox.addItemListener(item);
-
- //Keep the component in our internal vector.
- rbList.addElement(checkBox);
- }
-
- /**
- * The Checkbox group for the radio buttons.
- */
- protected CheckboxGroup group;
- /**
- * Vector of Checkboxes added to the panel. Used to set selected RadioButton by index.
- */
- protected Vector rbList;
- /**
- * Listener(s) that get notified when an ItemEvent is generated.
- */
- protected ItemListener itemListener = null;
- /**
- * Internal use.
- * Remembers the requested selected index so that <code>setSelectedIndex</code>
- * may be called before the appropriate radio button has been added.
- */
- protected int tempSelectionIndex;
- /**
- * is the component added to a container hierarchy?
- */
- protected boolean isAdded = false;
- /**
- * Error strings.
- */
- transient protected ResourceBundle errors;
-
- private IL item = null;
- private IV indexVeto = null;
- private Checkbox lastItem = null;
- private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
- private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
- }
-
-