1 /* 2 * Copyright (c) 1996, 2016, 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 package sun.awt.windows; 26 27 import java.awt.*; 28 import java.awt.peer.*; 29 30 import sun.awt.AWTAccessor; 31 32 final class WPopupMenuPeer extends WMenuPeer implements PopupMenuPeer { 33 // We can't use target.getParent() for TrayIcon popup 34 // because this method should return null for the TrayIcon 35 // popup regardless of that whether it has parent or not. 36 37 WPopupMenuPeer(PopupMenu target) { 38 this.target = target; 39 MenuContainer parent = null; 40 41 // We can't use target.getParent() for TrayIcon popup 42 // because this method should return null for the TrayIcon 43 // popup regardless of that whether it has parent or not. 44 boolean isTrayIconPopup = AWTAccessor.getPopupMenuAccessor().isTrayIconPopup(target); 45 if (isTrayIconPopup) { 46 parent = AWTAccessor.getMenuComponentAccessor().getParent(target); 47 } else { 48 parent = target.getParent(); 49 } 50 51 if (parent instanceof Component) { 52 WComponentPeer parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent); 53 if (parentPeer == null) { 54 // because the menu isn't a component (sigh) we first have to wait 55 // for a failure to map the peer which should only happen for a 56 // lightweight container, then find the actual native parent from 57 // that component. 58 parent = WToolkit.getNativeContainer((Component)parent); 59 parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent); 60 } 61 parentPeer.addChildPeer(this); 62 createMenu(parentPeer); 63 // fix for 5088782: check if menu object is created successfully 64 checkMenuCreation(); 65 } else { 66 throw new IllegalArgumentException( 67 "illegal popup menu container class"); 68 } 69 } 70 71 private native void createMenu(WComponentPeer parent); 72 73 public void show(Event e) { 74 Component origin = (Component)e.target; 75 WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin); 76 if (peer == null) { 77 // A failure to map the peer should only happen for a 78 // lightweight component, then find the actual native parent from 79 // that component. The event coorinates are going to have to be 80 // remapped as well. 81 Component nativeOrigin = WToolkit.getNativeContainer(origin); 82 e.target = nativeOrigin; 83 84 // remove the event coordinates 85 for (Component c = origin; c != nativeOrigin; c = c.getParent()) { 86 Point p = c.getLocation(); 87 e.x += p.x; 88 e.y += p.y; 89 } 90 } 91 _show(e); 92 } 93 94 /* 95 * This overloaded method is for TrayIcon. 96 * Its popup has special parent. 97 */ 98 void show(Component origin, Point p) { 99 WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin); 100 Event e = new Event(origin, 0, Event.MOUSE_DOWN, p.x, p.y, 0, 0); 101 if (peer == null) { 102 Component nativeOrigin = WToolkit.getNativeContainer(origin); 103 e.target = nativeOrigin; 104 } 105 e.x = p.x; 106 e.y = p.y; 107 _show(e); 108 } 109 110 private native void _show(Event e); 111 }