// $Id: UMLRadioButtonPanel.java 41 2010-04-03 20:04:12Z marcusvnac $ // Copyright (c) 1996-2007 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.uml.ui; import java.awt.Font; import java.awt.GridLayout; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Map; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.ButtonGroup; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.border.TitledBorder; import org.argouml.model.Model; import org.argouml.i18n.Translator; import org.argouml.ui.LookAndFeelMgr; import org.argouml.ui.targetmanager.TargetEvent; import org.argouml.ui.targetmanager.TargetListener; import org.tigris.gef.presentation.Fig; /** * A panel that shows a group of radiobuttons. An action can be added * to the panel which will be executed when one of the radiobuttons is * pressed. Via the name of the button (settext), the action can find * out which button is pressed. * * @author jaap.branderhorst@xs4all.nl * @since Jan 4, 2003 */ public abstract class UMLRadioButtonPanel extends JPanel implements TargetListener, PropertyChangeListener { private static Font stdFont = LookAndFeelMgr.getInstance().getStandardFont(); /** * The target object of which some attribute is shown via this panel. */ private Object panelTarget; /** * The name of the event that is fired when the target object has changed * the attribute that is shown here. */ private String propertySetName; /** * The group of buttons */ private ButtonGroup buttonGroup = new ButtonGroup(); /** * Constructs a new UMLRadioButtonPanel. * * @param isDoubleBuffered see {@link JPanel}. * @param title * The title of the titledborder around the buttons. If the title * is null, there is no border shown. * @param labeltextsActioncommands * A map of keys containing the texts for the buttons and values * containing the actioncommand that permits the setAction to * logically recognize the button. * @param thePropertySetName * the name of the MEvent that is fired when the property that it * shows changes value. * @param setAction * the action that should be registered with the buttons and * that's executed when one of the buttons is pressed. * @param horizontal * when true the buttons should be laid out horizontally. */ public UMLRadioButtonPanel( boolean isDoubleBuffered, String title, List<String[]> labeltextsActioncommands, String thePropertySetName, Action setAction, boolean horizontal) { super(isDoubleBuffered); setLayout(horizontal ? new GridLayout() : new GridLayout(0, 1)); setDoubleBuffered(true); if (Translator.localize(title) != null) { TitledBorder border = new TitledBorder(Translator.localize(title)); border.setTitleFont(stdFont); setBorder(border); } setButtons(labeltextsActioncommands, setAction); setPropertySetName(thePropertySetName); } /** * Constructs a new UMLRadioButtonPanel. * * @param title * The title of the titledborder around the buttons. * @param labeltextsActioncommands * A map of keys containing the texts for the buttons and values * containing the actioncommand that permits the setAction to * logically recognize the button. * @param thePropertySetName * the name of the MEvent that is fired when the property that is * shown changes value. * @param setAction * the action that should be registered with the buttons and * that's executed when one of the buttons is pressed * @param horizontal * when true the buttons should be laid out horizontally. */ public UMLRadioButtonPanel(String title, List<String[]> labeltextsActioncommands, String thePropertySetName, Action setAction, boolean horizontal) { this(true, title, labeltextsActioncommands, thePropertySetName, setAction, horizontal); } private static List<String[]> toList(Map<String, String> map) { List<String[]> list = new ArrayList<String[]>(); for (Map.Entry<String, String> entry : map.entrySet()) { list.add(new String[] {entry.getKey(), entry.getValue()}); } return list; } /** * Construct the buttons and place them in the panel as well as the button * group. * * @param labeltextsActioncommands * A list of string arrays containing a pair of strings with the * texts for the buttons (already localized) and string value for * the actioncommand that permits the setAction to logically * recognize the button. * @param setAction * the action that should be registered with the buttons and * that's executed when one of the buttons is pressed */ private void setButtons(List<String[]> labeltextsActioncommands, Action setAction) { Enumeration en = buttonGroup.getElements(); while (en.hasMoreElements()) { AbstractButton button = (AbstractButton) en.nextElement(); buttonGroup.remove(button); } removeAll(); // Add an invisible button to be used when everything is off buttonGroup.add(new JRadioButton()); for (String[] keyAndLabelX : labeltextsActioncommands) { JRadioButton button = new JRadioButton(keyAndLabelX[0]); button.addActionListener(setAction); String actionCommand = keyAndLabelX[1]; button.setActionCommand(actionCommand); button.setFont(LookAndFeelMgr.getInstance().getStandardFont()); buttonGroup.add(button); add(button); } } /* * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent e) { if (e.getPropertyName().equals(propertySetName)) { buildModel(); } } /** * Returns the target. * @return Object */ public Object getTarget() { return panelTarget; } /** * Sets the target and removes/adds this as a listener to the target. * @param target The target to set */ public void setTarget(Object target) { target = target instanceof Fig ? ((Fig) target).getOwner() : target; if (Model.getFacade().isAModelElement(panelTarget)) { Model.getPump().removeModelEventListener(this, panelTarget, propertySetName); } panelTarget = target; if (Model.getFacade().isAModelElement(panelTarget)) { Model.getPump().addModelEventListener(this, panelTarget, propertySetName); } if (panelTarget != null) { buildModel(); } } /** * Returns the propertySetName. * @return String */ public String getPropertySetName() { return propertySetName; } /** * Sets the propertySetName. * @param name The propertySetName to set */ public void setPropertySetName(String name) { propertySetName = name; } /** * Builds the model. That is: it selects the radiobutton showing the value * of the attribute shown. The name of this method is chosen to be * compliant with for example UMLModelElementListModel2 */ public abstract void buildModel(); /** * Selects the radiobutton with the given actionCommand. If a null parameter * is passed, all buttons in the group will be deselected. * * @param actionCommand * The actionCommand of the button that should be selected or * null to deselect all buttons. */ public void setSelected(String actionCommand) { Enumeration<AbstractButton> en = buttonGroup.getElements(); if (actionCommand == null) { // Our first button is invisible. // Selecting it deselects all visible buttons. en.nextElement().setSelected(true); return; } while (en.hasMoreElements()) { AbstractButton b = en.nextElement(); if (actionCommand.equals(b.getModel().getActionCommand())) { b.setSelected(true); break; } } } /* * @see org.argouml.ui.targetmanager.TargetListener#targetAdded(org.argouml.ui.targetmanager.TargetEvent) */ public void targetAdded(TargetEvent e) { setTarget(e.getNewTarget()); } /* * @see org.argouml.ui.targetmanager.TargetListener#targetRemoved(org.argouml.ui.targetmanager.TargetEvent) */ public void targetRemoved(TargetEvent e) { setTarget(e.getNewTarget()); } /* * @see org.argouml.ui.targetmanager.TargetListener#targetSet(org.argouml.ui.targetmanager.TargetEvent) */ public void targetSet(TargetEvent e) { setTarget(e.getNewTarget()); } }