Mercurial > hg > release > icedtea7-forest-2.3 > jdk
changeset 6360:e6dbd26e20c2
8021275: Better screening for ScreenMenu
Reviewed-by: art
author | serb |
---|---|
date | Thu, 10 Oct 2013 16:07:40 +0100 |
parents | 664dbef2bca9 |
children | 17829ce31387 |
files | src/macosx/classes/com/apple/laf/ScreenMenu.java |
diffstat | 1 files changed, 69 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/src/macosx/classes/com/apple/laf/ScreenMenu.java Mon Jul 22 14:06:39 2013 -0700 +++ b/src/macosx/classes/com/apple/laf/ScreenMenu.java Thu Oct 10 16:07:40 2013 +0100 @@ -36,26 +36,31 @@ import sun.lwawt.LWToolkit; import sun.lwawt.macosx.*; -class ScreenMenu extends Menu implements ContainerListener, ComponentListener, ScreenMenuPropertyHandler { +final class ScreenMenu extends Menu + implements ContainerListener, ComponentListener, + ScreenMenuPropertyHandler { + static { java.security.AccessController.doPrivileged((PrivilegedAction<?>)new sun.security.action.LoadLibraryAction("awt")); } // screen menu stuff - public static native long addMenuListeners(ScreenMenu listener, long nativeMenu); - public static native void removeMenuListeners(long modelPtr); + private static native long addMenuListeners(ScreenMenu listener, long nativeMenu); + private static native void removeMenuListeners(long modelPtr); - long fModelPtr = 0; + private transient long fModelPtr; - Hashtable<Component, MenuItem> fItems; - JMenu fInvoker; + private final Hashtable<Component, MenuItem> fItems; + private final JMenu fInvoker; - Component fLastMouseEventTarget; - Rectangle fLastTargetRect; + private Component fLastMouseEventTarget; + private Rectangle fLastTargetRect; private volatile Rectangle[] fItemBounds; + private ScreenMenuPropertyListener fPropertyListener; + // Array of child hashes used to see if we need to recreate the Menu. - int childHashArray[]; + private int childHashArray[]; ScreenMenu(final JMenu invoker) { super(invoker.getText()); @@ -68,25 +73,12 @@ updateItems(); } - // I'm always 'visible', but never on screen - static class ScreenMenuComponent extends Container { - public boolean isVisible() { return true; } - public boolean isShowing() { return true; } - public void setVisible(final boolean b) {} - public void show() {} - } - - ScreenMenuComponent makeScreenMenuComponent() { - return new ScreenMenuComponent(); - } - - /** * Determine if we need to tear down the Menu and re-create it, since the contents may have changed in the Menu opened listener and * we do not get notified of it, because EDT is busy in our code. We only need to update if the menu contents have changed in some * way, such as the number of menu items, the text of the menuitems, icon, shortcut etc. */ - static boolean needsUpdate(final Component items[], final int childHashArray[]) { + private static boolean needsUpdate(final Component items[], final int childHashArray[]) { if (items == null || childHashArray == null) { return true; } @@ -106,7 +98,7 @@ * Used to recreate the AWT based Menu structure that implements the Screen Menu. * Also computes hashcode and stores them so that we can compare them later in needsUpdate. */ - void updateItems() { + private void updateItems() { final int count = fInvoker.getMenuComponentCount(); final Component[] items = fInvoker.getMenuComponents(); if (needsUpdate(items, childHashArray)) { @@ -231,49 +223,56 @@ }); } - ScreenMenuPropertyListener fPropertyListener; + @Override public void addNotify() { - super.addNotify(); - if (fModelPtr == 0) { - fInvoker.addContainerListener(this); - fInvoker.addComponentListener(this); - fPropertyListener = new ScreenMenuPropertyListener(this); - fInvoker.addPropertyChangeListener(fPropertyListener); + synchronized (getTreeLock()) { + super.addNotify(); + if (fModelPtr == 0) { + fInvoker.addContainerListener(this); + fInvoker.addComponentListener(this); + fPropertyListener = new ScreenMenuPropertyListener(this); + fInvoker.addPropertyChangeListener(fPropertyListener); - final Icon icon = fInvoker.getIcon(); - if (icon != null) { - this.setIcon(icon); - } + final Icon icon = fInvoker.getIcon(); + if (icon != null) { + setIcon(icon); + } - final String tooltipText = fInvoker.getToolTipText(); - if (tooltipText != null) { - this.setToolTipText(tooltipText); - } - final MenuComponentPeer peer = getPeer(); - if (peer instanceof CMenu) { - final CMenu menu = (CMenu)peer; - final long nativeMenu = menu.getNativeMenu(); - fModelPtr = addMenuListeners(this, nativeMenu); + final String tooltipText = fInvoker.getToolTipText(); + if (tooltipText != null) { + setToolTipText(tooltipText); + } + final MenuComponentPeer peer = getPeer(); + if (peer instanceof CMenu) { + final CMenu menu = (CMenu) peer; + final long nativeMenu = menu.getNativeMenu(); + fModelPtr = addMenuListeners(this, nativeMenu); + } } } } + @Override public void removeNotify() { - // Call super so that the NSMenu has been removed, before we release the delegate in removeMenuListeners - super.removeNotify(); - fItems.clear(); - if (fModelPtr != 0) { - removeMenuListeners(fModelPtr); - fModelPtr = 0; - fInvoker.removeContainerListener(this); - fInvoker.removeComponentListener(this); - fInvoker.removePropertyChangeListener(fPropertyListener); + synchronized (getTreeLock()) { + // Call super so that the NSMenu has been removed, before we release + // the delegate in removeMenuListeners + super.removeNotify(); + fItems.clear(); + if (fModelPtr != 0) { + removeMenuListeners(fModelPtr); + fModelPtr = 0; + fInvoker.removeContainerListener(this); + fInvoker.removeComponentListener(this); + fInvoker.removePropertyChangeListener(fPropertyListener); + } } } /** * Invoked when a component has been added to the container. */ + @Override public void componentAdded(final ContainerEvent e) { addItem(e.getChild()); } @@ -281,23 +280,26 @@ /** * Invoked when a component has been removed from the container. */ + @Override public void componentRemoved(final ContainerEvent e) { final Component child = e.getChild(); final MenuItem sm = fItems.get(child); if (sm == null) return; - remove(sm); - fItems.remove(sm); - } + remove(sm); + fItems.remove(sm); + } /** * Invoked when the component's size changes. */ + @Override public void componentResized(final ComponentEvent e) {} /** * Invoked when the component's position changes. */ + @Override public void componentMoved(final ComponentEvent e) {} /** @@ -305,6 +307,7 @@ * See componentHidden - we should still have a MenuItem * it just isn't inserted */ + @Override public void componentShown(final ComponentEvent e) { setVisible(true); } @@ -315,11 +318,12 @@ * so we remove the ScreenMenuItem from the ScreenMenu * but leave it in fItems */ + @Override public void componentHidden(final ComponentEvent e) { setVisible(false); } - public void setVisible(final boolean b) { + private void setVisible(final boolean b) { // Tell our parent to add/remove us final MenuContainer parent = getParent(); @@ -327,20 +331,24 @@ if (parent instanceof ScreenMenu) { final ScreenMenu sm = (ScreenMenu)parent; sm.setChildVisible(fInvoker, b); - } + } } } + @Override public void setChildVisible(final JMenuItem child, final boolean b) { fItems.remove(child); updateItems(); } + @Override public void setAccelerator(final KeyStroke ks) {} // only check and radio items can be indeterminate + @Override public void setIndeterminate(boolean indeterminate) { } + @Override public void setToolTipText(final String text) { final MenuComponentPeer peer = getPeer(); if (!(peer instanceof CMenuItem)) return; @@ -349,6 +357,7 @@ cmi.setToolTipText(text); } + @Override public void setIcon(final Icon i) { final MenuComponentPeer peer = getPeer(); if (!(peer instanceof CMenuItem)) return; @@ -368,9 +377,8 @@ /** * Gets a hashCode for a JMenu or JMenuItem or subclass so that we can compare for * changes in the Menu. - * */ - static int getHashCode(final Component m) { + private static int getHashCode(final Component m) { int hashCode = m.hashCode(); if (m instanceof JMenuItem) { @@ -402,7 +410,7 @@ return hashCode; } - void addItem(final Component m) { + private void addItem(final Component m) { if (!m.isVisible()) return; MenuItem sm = fItems.get(m);