From efbded9571738bf0ffdefe91f01569bbaae97819 Mon Sep 17 00:00:00 2001 From: mcherkas Date: Mon, 3 Oct 2016 20:27:39 +0300 Subject: [PATCH] 8164143: Improve components for menu items Reviewed-by: ssadetsky, prr, ddehaven --- .../com/apple/eawt/_AppMenuBarHandler.java | 2 +- .../sun/lwawt/macosx/CCheckboxMenuItem.java | 15 ++-- .../sun/lwawt/macosx/CFRetainedResource.java | 68 ++++++++++++++++++- .../classes/sun/lwawt/macosx/CMenu.java | 44 ++++++------ .../classes/sun/lwawt/macosx/CMenuBar.java | 21 +++--- .../sun/lwawt/macosx/CMenuComponent.java | 32 ++++----- .../classes/sun/lwawt/macosx/CMenuItem.java | 35 ++++++---- .../sun/lwawt/macosx/CPlatformWindow.java | 2 +- .../classes/sun/lwawt/macosx/CPopupMenu.java | 14 ++-- .../classes/sun/lwawt/macosx/CTrayIcon.java | 7 +- src/macosx/native/sun/awt/CMenu.m | 15 ++-- src/macosx/native/sun/awt/CMenuBar.m | 19 ++---- src/macosx/native/sun/awt/CMenuComponent.m | 2 +- src/macosx/native/sun/awt/CMenuItem.h | 4 +- src/macosx/native/sun/awt/CMenuItem.m | 39 +++-------- src/share/classes/java/awt/MenuComponent.java | 4 ++ src/share/classes/sun/awt/AWTAccessor.java | 6 ++ 17 files changed, 194 insertions(+), 135 deletions(-) diff --git a/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java b/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java index f63441ba2..94b5429cc 100644 --- a/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java +++ b/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java @@ -121,7 +121,7 @@ class _AppMenuBarHandler { } // grab the pointer to the CMenuBar, and retain it in native - nativeSetDefaultMenuBar(((CMenuBar)peer).getModel()); + ((CMenuBar) peer).execute(_AppMenuBarHandler::nativeSetDefaultMenuBar); } void setAboutMenuItemVisible(final boolean present) { diff --git a/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java b/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java index da53c302a..d21de341f 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java +++ b/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,29 +26,28 @@ package sun.lwawt.macosx; import java.awt.CheckboxMenuItem; -import java.awt.EventQueue; import java.awt.event.ItemEvent; import java.awt.peer.CheckboxMenuItemPeer; import sun.awt.SunToolkit; public class CCheckboxMenuItem extends CMenuItem implements CheckboxMenuItemPeer { - boolean fAutoToggle = true; - boolean fIsIndeterminate = false; + volatile boolean fAutoToggle = true; + volatile boolean fIsIndeterminate = false; private native void nativeSetState(long modelPtr, boolean state); private native void nativeSetIsCheckbox(long modelPtr); - CCheckboxMenuItem(CheckboxMenuItem target) { + CCheckboxMenuItem(final CheckboxMenuItem target) { super(target); - nativeSetIsCheckbox(getModel()); + execute(this::nativeSetIsCheckbox); setState(target.getState()); } // MenuItemPeer implementation @Override - public void setState(boolean state) { - nativeSetState(getModel(), state); + public void setState(final boolean state) { + execute(ptr -> nativeSetState(ptr, state)); } public void handleAction(final boolean state) { diff --git a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java index cec76f5c8..f69ad201e 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java +++ b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java @@ -23,7 +23,6 @@ * questions. */ - package sun.lwawt.macosx; /** @@ -34,6 +33,7 @@ public class CFRetainedResource { private static native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread); private final boolean disposeOnAppKitThread; + // TODO this pointer should be private and accessed via CFNativeAction class protected volatile long ptr; /** @@ -70,8 +70,72 @@ public class CFRetainedResource { nativeCFRelease(oldPtr, disposeOnAppKitThread); // perform outside of the synchronized block } + /** + * The interface which allows to execute some native operations with + * assumption that the native pointer will be valid till the end. + */ + public interface CFNativeAction { + + /** + * The native operation should be called from this method. + * + * @param ptr the pointer to the native data + */ + void run(long ptr); + } + + /** + * The interface which allows to execute some native operations and get a + * result with assumption that the native pointer will be valid till the + * end. + */ + interface CFNativeActionGet { + + /** + * The native operation should be called from this method. + * + * @param ptr the pointer to the native data + * @return result of the native operation + */ + long run(long ptr); + } + + /** + * This is utility method which should be used instead of the direct access + * to the {@link #ptr}, because this method guaranteed that the pointer will + * not be zero and will be valid till the end of the operation.It is highly + * recomended to not use any external lock in action. If the current + * {@link #ptr} is {@code 0} then action will be ignored. + * + * @param action The native operation + */ + public final synchronized void execute(final CFNativeAction action) { + if (ptr != 0) { + action.run(ptr); + } + } + + /** + * This is utility method which should be used instead of the direct access + * to the {@link #ptr}, because this method guaranteed that the pointer will + * not be zero and will be valid till the end of the operation. It is highly + * recomended to not use any external lock in action. If the current + * {@link #ptr} is {@code 0} then action will be ignored and {@code} is + * returned. + * + * @param action the native operation + * @return result of the native operation, usually the native pointer to + * some other data + */ + final synchronized long executeGet(final CFNativeActionGet action) { + if (ptr != 0) { + return action.run(ptr); + } + return 0; + } + @Override - protected void finalize() throws Throwable { + protected final void finalize() throws Throwable { dispose(); } } diff --git a/src/macosx/classes/sun/lwawt/macosx/CMenu.java b/src/macosx/classes/sun/lwawt/macosx/CMenu.java index 9e1499b8d..4f2fc96ad 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CMenu.java +++ b/src/macosx/classes/sun/lwawt/macosx/CMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,9 @@ package sun.lwawt.macosx; -import java.awt.*; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; import java.awt.peer.MenuItemPeer; import java.awt.peer.MenuPeer; @@ -37,7 +39,7 @@ public class CMenu extends CMenuItem implements MenuPeer { // This way we avoiding invocation of the setters twice @Override - protected void initialize(MenuItem target) { + protected final void initialize(MenuItem target) { setLabel(target.getLabel()); setEnabled(target.isEnabled()); } @@ -57,52 +59,50 @@ public class CMenu extends CMenuItem implements MenuPeer { } @Override - protected long createModel() { + long createModel() { CMenuComponent parent = (CMenuComponent) LWCToolkit.targetToPeer(getTarget().getParent()); - if (parent instanceof CMenu || - parent instanceof CPopupMenu) - { - return nativeCreateSubMenu(parent.getModel()); - } else if (parent instanceof CMenuBar) { + if (parent instanceof CMenu) { + return parent.executeGet(this::nativeCreateSubMenu); + } + if (parent instanceof CMenuBar) { MenuBar parentContainer = (MenuBar)getTarget().getParent(); boolean isHelpMenu = parentContainer.getHelpMenu() == getTarget(); int insertionLocation = ((CMenuBar)parent).getNextInsertionIndex(); - return nativeCreateMenu(parent.getModel(), - isHelpMenu, insertionLocation); - } else { - throw new InternalError("Parent must be CMenu or CMenuBar"); + return parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu, + insertionLocation)); } + throw new InternalError("Parent must be CMenu or CMenuBar"); } @Override - public void addItem(MenuItem item) { + public final void addItem(MenuItem item) { // Nothing to do here -- we added it when we created the // menu item's peer. } @Override - public void delItem(int index) { - nativeDeleteItem(getModel(), index); + public final void delItem(final int index) { + execute(ptr -> nativeDeleteItem(ptr, index)); } @Override - public void setLabel(String label) { - nativeSetMenuTitle(getModel(), label); + public final void setLabel(final String label) { + execute(ptr->nativeSetMenuTitle(ptr, label)); super.setLabel(label); } // Note that addSeparator is never called directly from java.awt.Menu, // though it is required in the MenuPeer interface. @Override - public void addSeparator() { - nativeAddSeparator(getModel()); + public final void addSeparator() { + execute(this::nativeAddSeparator); } // Used by ScreenMenuBar to get to the native menu for event handling. - public long getNativeMenu() { - return nativeGetNSMenu(getModel()); + public final long getNativeMenu() { + return executeGet(this::nativeGetNSMenu); } private native long nativeCreateMenu(long parentMenuPtr, diff --git a/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java b/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java index 0bed715e0..6e80370f7 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java +++ b/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,9 @@ import java.awt.Menu; import java.awt.MenuBar; import java.awt.peer.MenuBarPeer; -public class CMenuBar extends CMenuComponent implements MenuBarPeer { +import sun.awt.AWTAccessor; + +public final class CMenuBar extends CMenuComponent implements MenuBarPeer { private int nextInsertionIndex = -1; @@ -38,15 +40,16 @@ public class CMenuBar extends CMenuComponent implements MenuBarPeer { } @Override - protected long createModel() { + long createModel() { return nativeCreateMenuBar(); } @Override - public void addHelpMenu(Menu m) { - CMenu cMenu = (CMenu)m.getPeer(); - nativeSetHelpMenu(getModel(), cMenu.getModel()); - } + public void addHelpMenu(final Menu m) { + final CMenu cMenu = AWTAccessor.getMenuComponentAccessor().getPeer(m); + execute(parentPtr -> cMenu.execute( + menuPtr -> nativeSetHelpMenu(parentPtr, menuPtr))); + } public int getNextInsertionIndex() { return nextInsertionIndex; @@ -63,8 +66,8 @@ public class CMenuBar extends CMenuComponent implements MenuBarPeer { } @Override - public void delMenu(int index) { - nativeDelMenu(getModel(), index); + public void delMenu(final int index) { + execute(ptr -> nativeDelMenu(ptr, index)); } private native long nativeCreateMenuBar(); diff --git a/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java b/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java index 2dbc92385..6100916be 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java +++ b/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,36 +29,32 @@ import java.awt.Font; import java.awt.MenuComponent; import java.awt.peer.MenuComponentPeer; -public abstract class CMenuComponent implements MenuComponentPeer { +abstract class CMenuComponent extends CFRetainedResource + implements MenuComponentPeer { - private MenuComponent target; - private long modelPtr; + private final MenuComponent target; - CMenuComponent(MenuComponent target) { + CMenuComponent(final MenuComponent target) { + super(0, true); this.target = target; - this.modelPtr = createModel(); + setPtr(createModel()); } - MenuComponent getTarget() { + final MenuComponent getTarget() { return target; } - public long getModel() { - return modelPtr; - } - - protected abstract long createModel(); + abstract long createModel(); - public void dispose() { + @Override + public final void dispose() { + super.dispose(); LWCToolkit.targetDisposedPeer(target, this); - nativeDispose(modelPtr); - target = null; } - private native void nativeDispose(long modelPtr); - // 1.5 peer method - public void setFont(Font f) { + @Override + public final void setFont(final Font f) { // no-op, as we don't currently support menu fonts // c.f. radar 4032912 } diff --git a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java index dbe6a8c8b..01427dbb3 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java +++ b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,17 @@ package sun.lwawt.macosx; -import sun.awt.SunToolkit; -import sun.lwawt.LWToolkit; - -import java.awt.MenuContainer; import java.awt.MenuItem; import java.awt.MenuShortcut; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.awt.peer.MenuItemPeer; import java.util.concurrent.atomic.AtomicBoolean; +import sun.awt.SunToolkit; +import sun.lwawt.LWToolkit; + public class CMenuItem extends CMenuComponent implements MenuItemPeer { private final AtomicBoolean enabled = new AtomicBoolean(true); @@ -58,9 +59,9 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { } @Override - protected long createModel() { + long createModel() { CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent()); - return nativeCreate(parent.getModel(), isSeparator()); + return parent.executeGet(ptr->nativeCreate(ptr, isSeparator())); } public void setLabel(String label, char keyChar, int keyCode, int modifiers) { @@ -90,7 +91,12 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { keyChar = 0; } - nativeSetLabel(getModel(), label, keyChar, keyCode, keyMask); + final String finalLabel = label; + final char finalKeyChar = keyChar; + final int finalKeyCode = keyCode; + final int finalKeyMask = keyMask; + execute(ptr -> nativeSetLabel(ptr, finalLabel, finalKeyChar, + finalKeyCode, finalKeyMask)); } @Override @@ -105,16 +111,16 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { * There isn't a need to expose this except in a instanceof because * it isn't defined in the peer api. */ - public void setImage(java.awt.Image img) { + public final void setImage(final java.awt.Image img) { CImage cimg = CImage.getCreator().createFromImage(img); - nativeSetImage(getModel(), cimg == null ? 0L : cimg.ptr); + execute(ptr -> nativeSetImage(ptr, cimg == null ? 0L : cimg.ptr)); } /** * New API for tooltips */ - public void setToolTipText(String text) { - nativeSetTooltip(getModel(), text); + public final void setToolTipText(final String text) { + execute(ptr -> nativeSetTooltip(ptr, text)); } // @Override @@ -138,7 +144,8 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer { b &= ((CMenuItem) parent).isEnabled(); } if (enabled.compareAndSet(!b, b)) { - nativeSetEnabled(getModel(), b); + final boolean finalB = b; + execute(ptr->nativeSetEnabled(ptr, finalB)); } } diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index cdaae4790..640a0deac 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -419,7 +419,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo final long nsWindowPtr = getNSWindowPtr(); CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb); if (mbPeer != null) { - nativeSetNSWindowMenuBar(nsWindowPtr, mbPeer.getModel()); + mbPeer.execute(ptr -> nativeSetNSWindowMenuBar(nsWindowPtr, ptr)); } else { nativeSetNSWindowMenuBar(nsWindowPtr, 0); } diff --git a/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java b/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java index 67ddf9147..b73f67a0f 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,18 +25,20 @@ package sun.lwawt.macosx; -import java.awt.*; +import java.awt.Component; +import java.awt.Event; +import java.awt.Point; +import java.awt.PopupMenu; import java.awt.peer.PopupMenuPeer; -import sun.lwawt.LWWindowPeer; +final class CPopupMenu extends CMenu implements PopupMenuPeer { -public class CPopupMenu extends CMenu implements PopupMenuPeer { CPopupMenu(PopupMenu target) { super(target); } @Override - protected long createModel() { + long createModel() { return nativeCreatePopupMenu(); } @@ -50,7 +52,7 @@ public class CPopupMenu extends CMenu implements PopupMenuPeer { Point loc = origin.getLocationOnScreen(); e.x += loc.x; e.y += loc.y; - nativeShowPopupMenu(getModel(), e.x, e.y); + execute(ptr -> nativeShowPopupMenu(ptr, e.x, e.y)); } } } diff --git a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java index 8e2a18fc1..ff1648dba 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java +++ b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,10 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { return 0L; } } - return checkAndCreatePopupPeer().getModel(); + // This method is executed on Appkit, so if ptr is not zero means that, + // it is still not deallocated(even if we call NSApp postRunnableEvent) + // and sent CFRelease to the native queue + return checkAndCreatePopupPeer().ptr; } /** diff --git a/src/macosx/native/sun/awt/CMenu.m b/src/macosx/native/sun/awt/CMenu.m index e2db11c10..2cfbc0c63 100644 --- a/src/macosx/native/sun/awt/CMenu.m +++ b/src/macosx/native/sun/awt/CMenu.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ - (id)initWithPeer:(jobject)peer { AWT_ASSERT_APPKIT_THREAD; // Create the new NSMenu - self = [super initWithPeer:peer asSeparator:[NSNumber numberWithBool:NO]]; + self = [super initWithPeer:peer asSeparator:NO]; if (self) { fMenu = [NSMenu javaMenuWithTitle:@""]; [fMenu retain]; @@ -134,14 +134,13 @@ AWT_ASSERT_APPKIT_THREAD; CMenu * createCMenu (jobject cPeerObjGlobal) { - CMenu *aCMenu = nil; - - // We use an array here only to be able to get a return value - NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil]; + __block CMenu *aCMenu = nil; - [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenu alloc] withObject:args waitUntilDone:YES]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - aCMenu = (CMenu *)[args objectAtIndex: 0]; + aCMenu = [[CMenu alloc] initWithPeer:cPeerObjGlobal]; + // the aCMenu is released in CMenuComponent.dispose() + }]; if (aCMenu == nil) { return 0L; diff --git a/src/macosx/native/sun/awt/CMenuBar.m b/src/macosx/native/sun/awt/CMenuBar.m index 3bf4f779f..202900b95 100644 --- a/src/macosx/native/sun/awt/CMenuBar.m +++ b/src/macosx/native/sun/awt/CMenuBar.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -383,27 +383,20 @@ JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar (JNIEnv *env, jobject peer) { - CMenuBar *aCMenuBar = nil; + __block CMenuBar *aCMenuBar = nil; JNF_COCOA_ENTER(env); jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer); - // We use an array here only to be able to get a return value - NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil]; - - [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenuBar alloc] withObject:args waitUntilDone:YES]; - - aCMenuBar = (CMenuBar *)[args objectAtIndex: 0]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + aCMenuBar = [[CMenuBar alloc] initWithPeer:cPeerObjGlobal]; + // the aCMenuBar is released in CMenuComponent.dispose() + }]; if (aCMenuBar == nil) { return 0L; } - // [args release]; - - // A strange memory managment after that. - - JNF_COCOA_EXIT(env); if (aCMenuBar) { CFRetain(aCMenuBar); // GC diff --git a/src/macosx/native/sun/awt/CMenuComponent.m b/src/macosx/native/sun/awt/CMenuComponent.m index c8b3766ad..fe325074a 100644 --- a/src/macosx/native/sun/awt/CMenuComponent.m +++ b/src/macosx/native/sun/awt/CMenuComponent.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/macosx/native/sun/awt/CMenuItem.h b/src/macosx/native/sun/awt/CMenuItem.h index 60a0565f3..e2c72f2e5 100644 --- a/src/macosx/native/sun/awt/CMenuItem.h +++ b/src/macosx/native/sun/awt/CMenuItem.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ } // Setup -- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator; +- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator; - (void) setIsCheckbox; // Events diff --git a/src/macosx/native/sun/awt/CMenuItem.m b/src/macosx/native/sun/awt/CMenuItem.m index 219cc5bb9..40c4241bf 100644 --- a/src/macosx/native/sun/awt/CMenuItem.m +++ b/src/macosx/native/sun/awt/CMenuItem.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,11 +39,11 @@ @implementation CMenuItem -- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{ +- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator{ AWT_ASSERT_APPKIT_THREAD; self = [super initWithPeer:peer]; if (self) { - if ([asSeparator boolValue]) { + if (asSeparator) { fMenuItem = (NSMenuItem*)[NSMenuItem separatorItem]; [fMenuItem retain]; } else { @@ -199,12 +199,9 @@ JNF_COCOA_EXIT(env); }]; } -- (void)cleanup { +- (void)dealloc { [fMenuItem setAction:NULL]; [fMenuItem setTarget:nil]; -} - -- (void)dealloc { [fMenuItem release]; fMenuItem = nil; @@ -223,14 +220,6 @@ JNF_COCOA_EXIT(env); fIsCheckbox = YES; } -- (void) _createMenuItem_OnAppKitThread: (NSMutableArray *)argValue { - jobject cPeerObjGlobal = (jobject)[[argValue objectAtIndex: 0] pointerValue]; - NSNumber * asSeparator = (NSNumber *)[argValue objectAtIndex: 1]; - CMenuItem *aCMenuItem = [self initWithPeer: cPeerObjGlobal asSeparator: asSeparator]; - [argValue removeAllObjects]; - [argValue addObject: aCMenuItem]; -} - - (NSString *)description { return [NSString stringWithFormat:@"CMenuItem[ %@ ]", fMenuItem]; } @@ -392,24 +381,18 @@ Java_sun_lwawt_macosx_CMenuItem_nativeCreate (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator) { - CMenuItem *aCMenuItem = nil; + __block CMenuItem *aCMenuItem = nil; + BOOL asSeparator = (isSeparator == JNI_TRUE) ? YES: NO; CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj); JNF_COCOA_ENTER(env); jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer); - NSMutableArray *args = nil; - - // Create a new item.... - if (isSeparator == JNI_TRUE) { - args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES], nil]; - } else { - args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO], nil]; - } - - [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES]; - - aCMenuItem = (CMenuItem *)[args objectAtIndex: 0]; + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + aCMenuItem = [[CMenuItem alloc] initWithPeer: cPeerObjGlobal + asSeparator: asSeparator]; + // the CMenuItem is released in CMenuComponent.dispose() + }]; if (aCMenuItem == nil) { return 0L; diff --git a/src/share/classes/java/awt/MenuComponent.java b/src/share/classes/java/awt/MenuComponent.java index b65c843bf..e1b3a7d6f 100644 --- a/src/share/classes/java/awt/MenuComponent.java +++ b/src/share/classes/java/awt/MenuComponent.java @@ -145,6 +145,10 @@ public abstract class MenuComponent implements java.io.Serializable { public Font getFont_NoClientCode(MenuComponent menuComp) { return menuComp.getFont_NoClientCode(); } + @SuppressWarnings("unchecked") + public T getPeer(MenuComponent menuComp) { + return (T) menuComp.peer; + } }); } diff --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java index d491ebef2..c5ac08a99 100644 --- a/src/share/classes/sun/awt/AWTAccessor.java +++ b/src/share/classes/sun/awt/AWTAccessor.java @@ -36,6 +36,7 @@ import java.awt.event.InvocationEvent; import java.awt.event.KeyEvent; import java.awt.geom.Point2D; import java.awt.peer.ComponentPeer; +import java.awt.peer.MenuComponentPeer; import java.lang.reflect.InvocationTargetException; import java.security.AccessControlContext; @@ -463,6 +464,11 @@ public final class AWTAccessor { * Gets the font used for this menu component. */ Font getFont_NoClientCode(MenuComponent menuComp); + + /** + * Returns the peer of the menu component. + */ + T getPeer(MenuComponent menuComp); } /** -- GitLab