1 /* 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.laf; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.awt.peer.MenuComponentPeer; 31 32 import javax.swing.*; 33 import javax.swing.plaf.ButtonUI; 34 35 import com.apple.laf.AquaMenuItemUI.IndeterminateListener; 36 37 import sun.lwawt.macosx.*; 38 39 final class ScreenMenuItemCheckbox extends CheckboxMenuItem implements ActionListener, ComponentListener, ScreenMenuPropertyHandler, ItemListener { 40 JMenuItem fMenuItem; 41 MenuContainer fParent; 42 43 ScreenMenuItemCheckbox(final JCheckBoxMenuItem mi) { 44 super(mi.getText(), mi.getState()); 45 init(mi); 46 } 47 48 ScreenMenuItemCheckbox(final JRadioButtonMenuItem mi) { 49 super(mi.getText(), mi.getModel().isSelected()); 50 init(mi); 51 } 52 53 public void init(final JMenuItem mi) { 54 fMenuItem = mi; 55 setEnabled(fMenuItem.isEnabled()); 56 } 57 58 ScreenMenuPropertyListener fPropertyListener; 59 public void addNotify() { 60 super.addNotify(); 61 62 // Avoid the Auto toggle behavior of AWT CheckBoxMenuItem 63 CCheckboxMenuItem ccb = (CCheckboxMenuItem) getPeer(); 64 ccb.setAutoToggle(false); 65 66 fMenuItem.addComponentListener(this); 67 fPropertyListener = new ScreenMenuPropertyListener(this); 68 fMenuItem.addPropertyChangeListener(fPropertyListener); 69 addActionListener(this); 70 addItemListener(this); 71 fMenuItem.addItemListener(this); 72 setIndeterminate(IndeterminateListener.isIndeterminate(fMenuItem)); 73 74 // can't setState or setAccelerator or setIcon till we have a peer 75 setAccelerator(fMenuItem.getAccelerator()); 76 77 final Icon icon = fMenuItem.getIcon(); 78 if (icon != null) { 79 this.setIcon(icon); 80 } 81 82 final String tooltipText = fMenuItem.getToolTipText(); 83 if (tooltipText != null) { 84 this.setToolTipText(tooltipText); 85 } 86 87 // sja fix is this needed? 88 fMenuItem.addItemListener(this); 89 90 final ButtonUI ui = fMenuItem.getUI(); 91 if (ui instanceof ScreenMenuItemUI) { 92 ((ScreenMenuItemUI)ui).updateListenersForScreenMenuItem(); 93 } 94 95 if (fMenuItem instanceof JCheckBoxMenuItem) { 96 setState(((JCheckBoxMenuItem)fMenuItem).isSelected()); 97 } else { 98 setState(fMenuItem.getModel().isSelected()); 99 } 100 } 101 102 public void removeNotify() { 103 fMenuItem.removeComponentListener(this); 104 fMenuItem.removePropertyChangeListener(fPropertyListener); 105 fPropertyListener = null; 106 removeActionListener(this); 107 removeItemListener(this); 108 fMenuItem.removeItemListener(this); 109 110 super.removeNotify(); 111 } 112 113 @Override 114 public synchronized void setLabel(final String label) { 115 ScreenMenuItem.syncLabelAndKS(this, label, fMenuItem.getAccelerator()); 116 } 117 118 @Override 119 public void setAccelerator(final KeyStroke ks) { 120 // We call CMenuItem.setLabel(..,..,..) directly and does not initialize 121 // shortcut property. So shortcut property should not be used from the 122 // peers code directly or indirectly. 123 ScreenMenuItem.syncLabelAndKS(this, fMenuItem.getText(), ks); 124 } 125 126 public void actionPerformed(final ActionEvent e) { 127 fMenuItem.doClick(0); // This takes care of all the different events 128 } 129 130 /** 131 * Invoked when the component's size changes. 132 */ 133 public void componentResized(final ComponentEvent e) {} 134 135 /** 136 * Invoked when the component's position changes. 137 */ 138 public void componentMoved(final ComponentEvent e) {} 139 140 /** 141 * Invoked when the component has been made visible. 142 * See componentHidden - we should still have a MenuItem 143 * it just isn't inserted 144 */ 145 public void componentShown(final ComponentEvent e) { 146 setVisible(true); 147 } 148 149 /** 150 * Invoked when the component has been made invisible. 151 * MenuComponent.setVisible does nothing, 152 * so we remove the ScreenMenuItem from the ScreenMenu 153 * but leave it in fItems 154 */ 155 public void componentHidden(final ComponentEvent e) { 156 setVisible(false); 157 } 158 159 public void setToolTipText(final String text) { 160 final MenuComponentPeer peer = getPeer(); 161 if (!(peer instanceof CMenuItem)) return; 162 163 ((CMenuItem)peer).setToolTipText(text); 164 } 165 166 public void setIcon(final Icon i) { 167 final MenuComponentPeer peer = getPeer(); 168 if (!(peer instanceof CMenuItem)) return; 169 170 final CMenuItem cmi = (CMenuItem)peer; 171 Image img = null; 172 173 if (i != null) { 174 if (i.getIconWidth() > 0 && i.getIconHeight() > 0) { 175 img = AquaIcon.getImageForIcon(i); 176 } 177 } 178 cmi.setImage(img); 179 } 180 181 public void setVisible(final boolean b) { 182 // Tell our parent to add/remove us 183 // Hang on to our parent 184 if (fParent == null) fParent = getParent(); 185 ((ScreenMenuPropertyHandler)fParent).setChildVisible(fMenuItem, b); 186 } 187 188 // we have no children 189 public void setChildVisible(final JMenuItem child, final boolean b) {} 190 191 /** 192 * Invoked when an item's state has been changed. 193 */ 194 public void itemStateChanged(final ItemEvent e) { 195 if (e.getSource() == this) { 196 fMenuItem.doClick(0); 197 return; 198 } 199 200 switch (e.getStateChange()) { 201 case ItemEvent.SELECTED: 202 setState(true); 203 break; 204 case ItemEvent.DESELECTED: 205 setState(false); 206 break; 207 } 208 } 209 210 public void setIndeterminate(final boolean indeterminate) { 211 final MenuComponentPeer peer = getPeer(); 212 if (peer instanceof CCheckboxMenuItem) { 213 ((CCheckboxMenuItem)peer).setIsIndeterminate(indeterminate); 214 } 215 } 216 }