1 /* 2 * Copyright (c) 2011, 2013, 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 sun.lwawt.macosx; 27 28 import sun.awt.SunToolkit; 29 import sun.lwawt.LWToolkit; 30 31 import java.awt.MenuContainer; 32 import java.awt.MenuItem; 33 import java.awt.MenuShortcut; 34 import java.awt.event.*; 35 import java.awt.peer.MenuItemPeer; 36 import java.util.concurrent.atomic.AtomicBoolean; 37 38 public class CMenuItem extends CMenuComponent implements MenuItemPeer { 39 40 private final AtomicBoolean enabled = new AtomicBoolean(true); 41 42 public CMenuItem(MenuItem target) { 43 super(target); 44 initialize(target); 45 } 46 47 // This way we avoiding invocation of the setters twice 48 protected void initialize(MenuItem target) { 49 if (!isSeparator()) { 50 setLabel(target.getLabel()); 51 setEnabled(target.isEnabled()); 52 } 53 } 54 55 private boolean isSeparator() { 56 String label = ((MenuItem)getTarget()).getLabel(); 57 return (label != null && label.equals("-")); 58 } 59 60 @Override 61 protected long createModel() { 62 CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent()); 63 return nativeCreate(parent.getModel(), isSeparator()); 64 } 65 66 public void setLabel(String label, char keyChar, int keyCode, int modifiers) { 67 int keyMask = modifiers; 68 if (keyCode == KeyEvent.VK_UNDEFINED) { 69 MenuShortcut shortcut = ((MenuItem)getTarget()).getShortcut(); 70 71 if (shortcut != null) { 72 keyCode = shortcut.getKey(); 73 keyMask |= InputEvent.META_MASK; 74 75 if (shortcut.usesShiftModifier()) { 76 keyMask |= InputEvent.SHIFT_MASK; 77 } 78 } 79 } 80 81 if (label == null) { 82 label = ""; 83 } 84 85 // <rdar://problem/3654824> 86 // Native code uses a keyChar of 0 to indicate that the 87 // keyCode should be used to generate the shortcut. Translate 88 // CHAR_UNDEFINED into 0. 89 if (keyChar == KeyEvent.CHAR_UNDEFINED) { 90 keyChar = 0; 91 } 92 93 nativeSetLabel(getModel(), label, keyChar, keyCode, keyMask); 94 } 95 96 @Override 97 public void setLabel(String label) { 98 setLabel(label, (char)0, KeyEvent.VK_UNDEFINED, 0); 99 } 100 101 /** 102 * This is new API that we've added to AWT menu items 103 * because AWT menu items are used for Swing screen menu bars 104 * and we want to support the NSMenuItem image apis. 105 * There isn't a need to expose this except in a instanceof because 106 * it isn't defined in the peer api. 107 */ 108 public void setImage(java.awt.Image img) { 109 CImage cimg = CImage.getCreator().createFromImage(img); 110 nativeSetImage(getModel(), cimg == null ? 0L : cimg.ptr); 111 } 112 113 /** 114 * New API for tooltips 115 */ 116 public void setToolTipText(String text) { 117 nativeSetTooltip(getModel(), text); 118 } 119 120 // @Override 121 public void enable() { 122 setEnabled(true); 123 } 124 125 // @Override 126 public void disable() { 127 setEnabled(false); 128 } 129 130 public final boolean isEnabled() { 131 return enabled.get(); 132 } 133 134 @Override 135 public void setEnabled(boolean b) { 136 final Object parent = LWToolkit.targetToPeer(getTarget().getParent()); 137 if (parent instanceof CMenuItem) { 138 b &= ((CMenuItem) parent).isEnabled(); 139 } 140 if (enabled.compareAndSet(!b, b)) { 141 nativeSetEnabled(getModel(), b); 142 } 143 } 144 145 private native long nativeCreate(long parentMenu, boolean isSeparator); 146 private native void nativeSetLabel(long modelPtr, String label, char keyChar, int keyCode, int modifiers); 147 private native void nativeSetImage(long modelPtr, long image); 148 private native void nativeSetTooltip(long modelPtr, String text); 149 private native void nativeSetEnabled(long modelPtr, boolean b); 150 151 // native callbacks 152 void handleAction(final long when, final int modifiers) { 153 SunToolkit.executeOnEventHandlerThread(getTarget(), new Runnable() { 154 public void run() { 155 final String cmd = ((MenuItem)getTarget()).getActionCommand(); 156 final ActionEvent event = new ActionEvent(getTarget(), ActionEvent.ACTION_PERFORMED, cmd, when, modifiers); 157 SunToolkit.postEvent(SunToolkit.targetToAppContext(getTarget()), event); 158 } 159 }); 160 } 161 }