1 /******************************************************************************* 2 * Copyright (c) 2004, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.internal; 15 16 import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter; 17 18 import java.util.ArrayList; 19 import java.util.Iterator; 20 import java.util.List; 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.events.SelectionListener; 23 import org.eclipse.swt.widgets.Menu; 24 import org.eclipse.swt.widgets.MenuItem; 25 26 /** 27 * Represents a group of radio buttons in a menu. Each menu item is mapped onto 28 * a particular value. The RadioMenu reports its state using the attached Model 29 * object. That is, Model.getState() will return the value of the currently 30 * selected radio button and Model.setState(value) will select the radio button 31 * associated with the given value. 32 */ 33 public class RadioMenu implements IChangeListener { 34 35 private Model data; 36 37 private Menu parent; 38 39 private List items = new ArrayList(); 40 41 SelectionListener selectionAdapter = widgetSelectedAdapter(e -> { 42 Object newState = e.widget.getData(); 43 44 data.setState(newState, RadioMenu.this); 45 }); 46 47 /** 48 * Creates a set of radio menu items on the given menu. 49 * 50 * @param parent menu that will contain the menu items 51 * @param newData the model that will store the value of the currently selected 52 * item 53 */ RadioMenu(Menu parent, Model newData)54 public RadioMenu(Menu parent, Model newData) { 55 this.parent = parent; 56 this.data = newData; 57 58 newData.addChangeListener(this); 59 } 60 61 /** 62 * Returns true iff the given values are considered equal. 63 * 64 * @param value1 65 * @param value2 66 * @return 67 */ isEqual(Object value1, Object value2)68 private static boolean isEqual(Object value1, Object value2) { 69 if (value1 == null) { 70 return value2 == null; 71 } else if (value2 == null) { 72 return false; 73 } 74 75 return value1.equals(value2); 76 } 77 78 /** 79 * Creates a new menu item with the given text and value. When the item is 80 * selected, the state of the model will change to match the given value. 81 * 82 * @param text 83 * @param value 84 */ addMenuItem(String text, Object value)85 public void addMenuItem(String text, Object value) { 86 MenuItem newItem = new MenuItem(parent, SWT.RADIO); 87 88 newItem.setSelection(isEqual(data.getState(), value)); 89 newItem.setText(text); 90 newItem.setData(value); 91 items.add(newItem); 92 93 newItem.addSelectionListener(selectionAdapter); 94 } 95 96 /** 97 * Disposes all menu items 98 */ dispose()99 public void dispose() { 100 Iterator iter = items.iterator(); 101 while (iter.hasNext()) { 102 MenuItem next = (MenuItem) iter.next(); 103 104 if (!next.isDisposed()) { 105 next.removeSelectionListener(selectionAdapter); 106 next.dispose(); 107 } 108 } 109 110 items.clear(); 111 } 112 113 /** 114 * Refreshes the selected menu items to match the current state of the model. 115 */ refreshSelection()116 private void refreshSelection() { 117 Iterator iter = items.iterator(); 118 while (iter.hasNext()) { 119 MenuItem next = (MenuItem) iter.next(); 120 121 if (!next.isDisposed()) { 122 next.setSelection(isEqual(data.getState(), next.getData())); 123 } 124 } 125 } 126 127 @Override update(boolean changed)128 public void update(boolean changed) { 129 refreshSelection(); 130 } 131 132 } 133