8161342: Service Menu services
authorssadetsky
Mon, 11 Jul 2016 21:46:07 +0300
changeset 41574 7d3cca7fc05d
parent 41573 3771d7eaab2c
child 41575 12390e0aabc4
8161342: Service Menu services Reviewed-by: prr, mschoene
jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java
jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -107,6 +107,7 @@
         this.target = target;
         this.parent = (WMenuPeer) WToolkit.targetToPeer(target.getParent());
         this.isCheckbox = isCheckbox;
+        parent.addChildPeer(this);
         create(parent);
         // fix for 5088782: check if menu object is created successfully
         checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -51,10 +51,12 @@
         if (parent instanceof MenuBar) {
             WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(parent);
             this.parent = mbPeer;
+            mbPeer.addChildPeer(this);
             createMenu(mbPeer);
         }
         else if (parent instanceof Menu) {
             this.parent = (WMenuPeer) WToolkit.targetToPeer(parent);
+            this.parent.addChildPeer(this);
             createSubMenu(this.parent);
         }
         else {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -24,6 +24,9 @@
  */
 package sun.awt.windows;
 
+import java.util.Map;
+import java.util.WeakHashMap;
+
 abstract class WObjectPeer {
 
     static {
@@ -45,6 +48,8 @@
     // used to synchronize the state of this peer
     private final Object stateLock = new Object();
 
+    private volatile Map<WObjectPeer, WObjectPeer> childPeers;
+
     public static WObjectPeer getPeerForTarget(Object t) {
         WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
         return peer;
@@ -77,6 +82,9 @@
         }
 
         if (call_disposeImpl) {
+            if (childPeers != null) {
+                disposeChildPeers();
+            }
             disposeImpl();
         }
     }
@@ -88,4 +96,33 @@
      * Initialize JNI field and method IDs
      */
     private static native void initIDs();
+
+    // if a child peer existence depends on this peer, add it to this collection
+    final void addChildPeer(WObjectPeer child) {
+        synchronized (getStateLock()) {
+            if (childPeers == null) {
+                childPeers = new WeakHashMap<>();
+            }
+            if (isDisposed()) {
+                throw new IllegalStateException("Parent peer is disposed");
+            }
+            childPeers.put(child, this);
+        }
+    }
+
+    // called to dispose dependent child peers
+    private void disposeChildPeers() {
+        synchronized (getStateLock()) {
+            for (WObjectPeer child : childPeers.keySet()) {
+                if (child != null) {
+                    try {
+                        child.dispose();
+                    }
+                    catch (Exception e) {
+                        // ignored
+                    }
+                }
+            }
+        }
+    }
 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -58,6 +58,7 @@
                 parent = WToolkit.getNativeContainer((Component)parent);
                 parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
             }
+            parentPeer.addChildPeer(this);
             createMenu(parentPeer);
             // fix for 5088782: check if menu object is created successfully
             checkMenuCreation();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1113,11 +1113,19 @@
 
 void AwtFrame::SetMenuBar(AwtMenuBar* mb)
 {
+    if (menuBar) {
+        menuBar->SetFrame(NULL);
+    }
     menuBar = mb;
     if (mb == NULL) {
         // Remove existing menu bar, if any.
         ::SetMenu(GetHWnd(), NULL);
     } else {
+        AwtFrame* oldFrame = menuBar->GetFrame();
+        if (oldFrame && oldFrame != this) {
+            oldFrame->SetMenuBar(NULL);
+        }
+        menuBar->SetFrame(this);
         if (menuBar->GetHMenu() != NULL) {
             ::SetMenu(GetHWnd(), menuBar->GetHMenu());
         }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -58,6 +58,9 @@
 
 void AwtMenuBar::Dispose()
 {
+    if (m_frame != NULL && m_frame->GetMenuBar() == this) {
+        m_frame->SetMenuBar(NULL);
+    }
     m_frame = NULL;
 
     AwtMenu::Dispose();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h	Tue Jul 05 13:08:37 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h	Mon Jul 11 21:46:07 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -63,6 +63,9 @@
 
     virtual AwtMenuBar* GetMenuBar() { return this; }
     INLINE AwtFrame* GetFrame() { return m_frame; }
+    INLINE void SetFrame(AwtFrame* frame) {
+        m_frame = frame;
+    }
 
     virtual HWND GetOwnerHWnd();
     virtual void RedrawMenuBar();