Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

JRadioButton and ButtonGroup

Status
Not open for further replies.

DanJR

Technical User
Oct 29, 2002
392
AU
simple question,

version 1.5

i have a data entry form (JPanel) which contains 3 radio buttons in a ButtonGroup. Rather than create a new JPanel every time i want to use this form, i have a method that allows me to clear all the items in the form. However, i'm having a problem setting all the JRadioButton's in the ButtonGroup to 'not selected'.

from a java tutorial it states
"There's no supported API for unselecting all the buttons."

and when i look at the code for setSelected(ButtonModel, boolean) in the ButtonGroup class, i don't understand why the method takes a second argument (or perhaps its for backwards compatability), because the code does nothing if the second argument is false:

Code:
    public void setSelected(ButtonModel m, boolean b) {
        if (b && m != null && m != selection) {
            ButtonModel oldSelection = selection;
            selection = m;
            if (oldSelection != null) {
                oldSelection.setSelected(false);
            }
            m.setSelected(true);
        } 
    }

am i missing something here - or do i just create my own ButtonGroup class


cheers,
dan
 
oldSelection.setSelected(false);
m.setSelected(true);

I think the parameter b should be passed into these two methods.

oldSelection.setSelected(b);
m.setSelected(b);

So you can set the button selection in both way (true/false).


Chinese Java Faq Forum
 
as a quick fix, i created by own button group which inherits ButtonGroup and overridden the setSelected method, then added a clearSelection() method.

Code:
	public void setSelected(ButtonModel m, boolean b) {
		
		if(m == null) {
			ButtonModel oldSelection = selection;
			selection = null;
			if(oldSelection != null) {
				oldSelection.setSelected(false);
			}
		} else if (b && m != null && m != selection) {
			ButtonModel oldSelection = selection;
			selection = m;
			if (oldSelection != null) {
				oldSelection.setSelected(false);
			}
			m.setSelected(true);
		} 
		
	}

	public void clearSelection() {
		setSelected(null, false);
	}

it seems to work as expected. Does anyone see a problem with this? When I looked a little closer at the API it makes sense why the setSelected has two parameters, as the ButtonModel called the ButtonGroup's setSelected if the radio button is part of a group.

cheers
dan
 
Dan,

I had exactly the same problem with a ButtonGroup for RadioButtons also. I have three grouped buttons, which I reset the text for from an actionlistener method on a JButton.

I reused your approach as is, but it didn't work for me. I get the problem that now my RadioButtons whilst clear, don't select at all!! Any ideas what I may have done wrong?

Regards,
--Pete
 
Hi Pete,

I'm not sure off the top of my head, however here is the complete code for Java's modified ButtonGroup class (i've called the class JButtonGroup). The setSelected() has been modified and the clearSelection() method has been added. Try using this class as a substitute for Java's ButtonGroup class.

Let me know how ya get on. If the problem still presists then send me some sample code and i'll see if i can reproduce the problem too.

cheers,
dan.

Code:
/*
 * @(#)ButtonGroup.java	1.37 04/05/05
 *
 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package nz.ac.ipru.gui.swing;


import java.util.Vector;
import java.util.Enumeration;
import java.io.Serializable;

import javax.swing.*;

/**
 * This class is used to create a multiple-exclusion scope for
 * a set of buttons. Creating a set of buttons with the
 * same <code>ButtonGroup</code> object means that
 * turning "on" one of those buttons 
 * turns off all other buttons in the group.
 * <p>
 * A <code>ButtonGroup</code> can be used with
 * any set of objects that inherit from <code>AbstractButton</code>.
 * Typically a button group contains instances of 
 * <code>JRadioButton</code>,
 * <code>JRadioButtonMenuItem</code>,
 * or <code>JToggleButton</code>.
 * It wouldn't make sense to put an instance of 
 * <code>JButton</code> or <code>JMenuItem</code>
 * in a button group
 * because <code>JButton</code> and <code>JMenuItem</code>
 * don't implement the selected state.
 * <p>
 * Initially, all buttons in the group are unselected. Once any button is
 * selected, one button is always selected in the group. There is no way
 * to turn a button programmatically to "off", in order to clear the button
 * group. To give the appearance of "none selected", add an invisible radio
 * button to the group and then programmatically select that button to 
 * turn off all the displayed radio buttons. For example, a normal button
 * with the label "none" could be wired to select the invisible radio button.
 * <p>
 * The above paragraph is no longer true. All the buttons in the group can be
 * unselected by called the <code>clearSelection</code> method (Dan Russell). 
 * <p>
 * For examples and further information on using button groups see
 * <a href="[URL unfurl="true"]http://java.sun.com/docs/books/tutorial/uiswing/components/button.html#radiobutton">How[/URL] to Use Radio Buttons</a>,
 * a section in <em>The Java Tutorial</em>.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @version 1.37 05/05/04
 * @author Jeff Dinkins
 */
public class JButtonGroup extends ButtonGroup implements Serializable {
	private static final long serialVersionUID = 1; 
	
	// the list of buttons participating in this group
	protected Vector<AbstractButton> buttons = new Vector<AbstractButton>();
	
	/**
	 * The current selection.
	 */
	ButtonModel selection = null;
	
	/**
	 * Creates a new <code>ButtonGroup</code>.
	 */
	public JButtonGroup() {}
	
	/**
	 * Adds the button to the group.
	 * @param b the button to be added
	 */ 
	public void add(AbstractButton b) {
		if(b == null) {
			return;
		}
		buttons.addElement(b);
		
		if (b.isSelected()) {
			if (selection == null) {
				selection = b.getModel();
			} else {
				b.setSelected(false);
			}
		}
		
		b.getModel().setGroup(this);
	}
	
	/**
	 * Removes the button from the group.
	 * @param b the button to be removed
	 */ 
	public void remove(AbstractButton b) {
		if(b == null) {
			return;
		}
		buttons.removeElement(b);
		if(b.getModel() == selection) {
			selection = null;
		}
		b.getModel().setGroup(null);
	}
	
	/**
	 * Returns all the buttons that are participating in
	 * this group.
	 * @return an <code>Enumeration</code> of the buttons in this group
	 */
	public Enumeration<AbstractButton> getElements() {
		return buttons.elements();
	}
	
	/**
	 * Returns the model of the selected button.
	 * @return the selected button model
	 */
	public ButtonModel getSelection() {
		return selection;
	}
	
	/**
	 * Sets the selected value for the <code>ButtonModel</code>.
	 * Only one button in the group may be selected at a time.
	 * If the  <code>ButtonModel</code> is null then all buttons
	 * are unselected (Dan Russell - added this implementation). However,
	 * you should use the <code>clearSelection</code> to unselect all
	 * buttons in the group.
	 * @param m the <code>ButtonModel</code>
	 * @param b <code>true</code> if this button is to be
	 *   selected, otherwise <code>false</code>
	 */
	public void setSelected(ButtonModel m, boolean b) {
		// if the button model is part of a group then
		// this method is used to set the button models state
		
		if(m == null) {
			ButtonModel oldSelection = selection;
			selection = null;
			if(oldSelection != null) {
				oldSelection.setSelected(false);
			}
		} else if (b && m != null && m != selection) {
			ButtonModel oldSelection = selection;
			selection = m;
			if (oldSelection != null) {
				oldSelection.setSelected(false);
			}
			m.setSelected(true);
		} 
		
	}
	
	/**
	 * Unselect all buttons in the group.
	 */
	public void clearSelection() {
		setSelected(null, false);
	}
	
	/**
	 * Returns whether a <code>ButtonModel</code> is selected.
	 * @return <code>true</code> if the button is selected,
	 *   otherwise returns <code>false</code>
	 */
	public boolean isSelected(ButtonModel m) {
		return (m == selection);
	}
	
	/**
	 * Returns the number of buttons in the group.
	 * @return the button count
	 * @since 1.3
	 */
	public int getButtonCount() {
		if (buttons == null) {
			return 0;
		} else {
			return buttons.size();
		}
	}
	
}
 
or use another ButtonModel which is not a member of the ButtonGroup.

// will deselect all other Buttons of the ButtonGroup
myButtonGroup.setSelected(new JButton("nothing selected").getModel(), true);
 
The idea of a radio-button-group is a collection of entries, of which exactly one is allways true. That is why one button has to be selected.

Of course, in reality there is a problem.
It's easy to claim 'a person has to be male or female' but perhaps we don't like to make a default-selection.
We could work-around with an 'unknown' Button, added to the group.

Another solution sometimes might be a Checkbox '[] evaluate sex button'.

Allowing a button-group to have no selected button seems like a constraint-violation to me, which might cause unforeseen compatibility problems.

Afaik it should be possible to generate a button-group which doesn't extend JRadioButton, and uses a new concept of 'zero or single button of group'.

seeking a job as java-programmer in Berlin:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top