home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgLangD.iso
/
VCAFE.3.0A
/
Main.bin
/
RadioButtonGroupPanel.java
< prev
next >
Wrap
Text File
|
1998-08-21
|
16KB
|
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);
}