提交 976a400d 编写于 作者: S serb

8021275: Better screening for ScreenMenu

Reviewed-by: art
上级 becc0ce2
...@@ -36,7 +36,10 @@ import sun.awt.SunToolkit; ...@@ -36,7 +36,10 @@ import sun.awt.SunToolkit;
import sun.lwawt.LWToolkit; import sun.lwawt.LWToolkit;
import sun.lwawt.macosx.*; import sun.lwawt.macosx.*;
class ScreenMenu extends Menu implements ContainerListener, ComponentListener, ScreenMenuPropertyHandler { final class ScreenMenu extends Menu
implements ContainerListener, ComponentListener,
ScreenMenuPropertyHandler {
static { static {
java.security.AccessController.doPrivileged( java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() { new java.security.PrivilegedAction<Void>() {
...@@ -48,20 +51,22 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -48,20 +51,22 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
} }
// screen menu stuff // screen menu stuff
public static native long addMenuListeners(ScreenMenu listener, long nativeMenu); private static native long addMenuListeners(ScreenMenu listener, long nativeMenu);
public static native void removeMenuListeners(long modelPtr); private static native void removeMenuListeners(long modelPtr);
long fModelPtr = 0; private transient long fModelPtr;
Hashtable<Component, MenuItem> fItems; private final Hashtable<Component, MenuItem> fItems;
JMenu fInvoker; private final JMenu fInvoker;
Component fLastMouseEventTarget; private Component fLastMouseEventTarget;
Rectangle fLastTargetRect; private Rectangle fLastTargetRect;
private volatile Rectangle[] fItemBounds; private volatile Rectangle[] fItemBounds;
private ScreenMenuPropertyListener fPropertyListener;
// Array of child hashes used to see if we need to recreate the Menu. // Array of child hashes used to see if we need to recreate the Menu.
int childHashArray[]; private int childHashArray[];
ScreenMenu(final JMenu invoker) { ScreenMenu(final JMenu invoker) {
super(invoker.getText()); super(invoker.getText());
...@@ -74,25 +79,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -74,25 +79,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
updateItems(); 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 * 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 * 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. * 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) { if (items == null || childHashArray == null) {
return true; return true;
} }
...@@ -112,7 +104,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -112,7 +104,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
* Used to recreate the AWT based Menu structure that implements the Screen Menu. * 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. * 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 int count = fInvoker.getMenuComponentCount();
final Component[] items = fInvoker.getMenuComponents(); final Component[] items = fInvoker.getMenuComponents();
if (needsUpdate(items, childHashArray)) { if (needsUpdate(items, childHashArray)) {
...@@ -163,16 +155,14 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -163,16 +155,14 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
LWCToolkit.invokeAndWait(new Runnable() { LWCToolkit.invokeAndWait(new Runnable() {
public void run() { public void run() {
invoker.setSelected(false); invoker.setSelected(false);
// Null out the tracking rectangles and the array.
// Null out the tracking rectangles and the array.
if (fItemBounds != null) { if (fItemBounds != null) {
for (int i = 0; i < fItemBounds.length; i++) { for (int i = 0; i < fItemBounds.length; i++) {
fItemBounds[i] = null; fItemBounds[i] = null;
} }
} }
fItemBounds = null;
fItemBounds = null; }
}
}, invoker); }, invoker);
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); e.printStackTrace();
...@@ -237,49 +227,56 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -237,49 +227,56 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
}); });
} }
ScreenMenuPropertyListener fPropertyListener; @Override
public void addNotify() { public void addNotify() {
super.addNotify(); synchronized (getTreeLock()) {
if (fModelPtr == 0) { super.addNotify();
fInvoker.addContainerListener(this); if (fModelPtr == 0) {
fInvoker.addComponentListener(this); fInvoker.addContainerListener(this);
fPropertyListener = new ScreenMenuPropertyListener(this); fInvoker.addComponentListener(this);
fInvoker.addPropertyChangeListener(fPropertyListener); fPropertyListener = new ScreenMenuPropertyListener(this);
fInvoker.addPropertyChangeListener(fPropertyListener);
final Icon icon = fInvoker.getIcon();
if (icon != null) { final Icon icon = fInvoker.getIcon();
this.setIcon(icon); if (icon != null) {
} setIcon(icon);
}
final String tooltipText = fInvoker.getToolTipText(); final String tooltipText = fInvoker.getToolTipText();
if (tooltipText != null) { if (tooltipText != null) {
this.setToolTipText(tooltipText); setToolTipText(tooltipText);
} }
final MenuComponentPeer peer = getPeer(); final MenuComponentPeer peer = getPeer();
if (peer instanceof CMenu) { if (peer instanceof CMenu) {
final CMenu menu = (CMenu)peer; final CMenu menu = (CMenu) peer;
final long nativeMenu = menu.getNativeMenu(); final long nativeMenu = menu.getNativeMenu();
fModelPtr = addMenuListeners(this, nativeMenu); fModelPtr = addMenuListeners(this, nativeMenu);
}
} }
} }
} }
@Override
public void removeNotify() { public void removeNotify() {
// Call super so that the NSMenu has been removed, before we release the delegate in removeMenuListeners synchronized (getTreeLock()) {
super.removeNotify(); // Call super so that the NSMenu has been removed, before we release
fItems.clear(); // the delegate in removeMenuListeners
if (fModelPtr != 0) { super.removeNotify();
removeMenuListeners(fModelPtr); fItems.clear();
fModelPtr = 0; if (fModelPtr != 0) {
fInvoker.removeContainerListener(this); removeMenuListeners(fModelPtr);
fInvoker.removeComponentListener(this); fModelPtr = 0;
fInvoker.removePropertyChangeListener(fPropertyListener); fInvoker.removeContainerListener(this);
fInvoker.removeComponentListener(this);
fInvoker.removePropertyChangeListener(fPropertyListener);
}
} }
} }
/** /**
* Invoked when a component has been added to the container. * Invoked when a component has been added to the container.
*/ */
@Override
public void componentAdded(final ContainerEvent e) { public void componentAdded(final ContainerEvent e) {
addItem(e.getChild()); addItem(e.getChild());
} }
...@@ -287,23 +284,26 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -287,23 +284,26 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
/** /**
* Invoked when a component has been removed from the container. * Invoked when a component has been removed from the container.
*/ */
@Override
public void componentRemoved(final ContainerEvent e) { public void componentRemoved(final ContainerEvent e) {
final Component child = e.getChild(); final Component child = e.getChild();
final MenuItem sm = fItems.get(child); final MenuItem sm = fItems.get(child);
if (sm == null) return; if (sm == null) return;
remove(sm); remove(sm);
fItems.remove(sm); fItems.remove(sm);
} }
/** /**
* Invoked when the component's size changes. * Invoked when the component's size changes.
*/ */
@Override
public void componentResized(final ComponentEvent e) {} public void componentResized(final ComponentEvent e) {}
/** /**
* Invoked when the component's position changes. * Invoked when the component's position changes.
*/ */
@Override
public void componentMoved(final ComponentEvent e) {} public void componentMoved(final ComponentEvent e) {}
/** /**
...@@ -311,6 +311,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -311,6 +311,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
* See componentHidden - we should still have a MenuItem * See componentHidden - we should still have a MenuItem
* it just isn't inserted * it just isn't inserted
*/ */
@Override
public void componentShown(final ComponentEvent e) { public void componentShown(final ComponentEvent e) {
setVisible(true); setVisible(true);
} }
...@@ -321,11 +322,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -321,11 +322,12 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
* so we remove the ScreenMenuItem from the ScreenMenu * so we remove the ScreenMenuItem from the ScreenMenu
* but leave it in fItems * but leave it in fItems
*/ */
@Override
public void componentHidden(final ComponentEvent e) { public void componentHidden(final ComponentEvent e) {
setVisible(false); setVisible(false);
} }
public void setVisible(final boolean b) { private void setVisible(final boolean b) {
// Tell our parent to add/remove us // Tell our parent to add/remove us
final MenuContainer parent = getParent(); final MenuContainer parent = getParent();
...@@ -333,20 +335,24 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -333,20 +335,24 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
if (parent instanceof ScreenMenu) { if (parent instanceof ScreenMenu) {
final ScreenMenu sm = (ScreenMenu)parent; final ScreenMenu sm = (ScreenMenu)parent;
sm.setChildVisible(fInvoker, b); sm.setChildVisible(fInvoker, b);
} }
} }
} }
@Override
public void setChildVisible(final JMenuItem child, final boolean b) { public void setChildVisible(final JMenuItem child, final boolean b) {
fItems.remove(child); fItems.remove(child);
updateItems(); updateItems();
} }
@Override
public void setAccelerator(final KeyStroke ks) {} public void setAccelerator(final KeyStroke ks) {}
// only check and radio items can be indeterminate // only check and radio items can be indeterminate
@Override
public void setIndeterminate(boolean indeterminate) { } public void setIndeterminate(boolean indeterminate) { }
@Override
public void setToolTipText(final String text) { public void setToolTipText(final String text) {
final MenuComponentPeer peer = getPeer(); final MenuComponentPeer peer = getPeer();
if (!(peer instanceof CMenuItem)) return; if (!(peer instanceof CMenuItem)) return;
...@@ -355,6 +361,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -355,6 +361,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
cmi.setToolTipText(text); cmi.setToolTipText(text);
} }
@Override
public void setIcon(final Icon i) { public void setIcon(final Icon i) {
final MenuComponentPeer peer = getPeer(); final MenuComponentPeer peer = getPeer();
if (!(peer instanceof CMenuItem)) return; if (!(peer instanceof CMenuItem)) return;
...@@ -374,9 +381,8 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -374,9 +381,8 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
/** /**
* Gets a hashCode for a JMenu or JMenuItem or subclass so that we can compare for * Gets a hashCode for a JMenu or JMenuItem or subclass so that we can compare for
* changes in the Menu. * changes in the Menu.
*
*/ */
static int getHashCode(final Component m) { private static int getHashCode(final Component m) {
int hashCode = m.hashCode(); int hashCode = m.hashCode();
if (m instanceof JMenuItem) { if (m instanceof JMenuItem) {
...@@ -408,7 +414,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S ...@@ -408,7 +414,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S
return hashCode; return hashCode;
} }
void addItem(final Component m) { private void addItem(final Component m) {
if (!m.isVisible()) return; if (!m.isVisible()) return;
MenuItem sm = fItems.get(m); MenuItem sm = fItems.get(m);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册