提交 c46ecfe4 编写于 作者: M mcherkas

8167110: Windows peering issue

7155957: closed/java/awt/MenuBar/MenuBarStress1/MenuBarStress1.java hangs on win 64 bit with jdk8
8079595: Resizing dialog which is JWindow parent makes JVM crash
8147842: IME Composition Window is displayed at incorrect location
Reviewed-by: serb
上级 9b87a7f4
...@@ -411,9 +411,9 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -411,9 +411,9 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
items.removeElementAt(index); items.removeElementAt(index);
MenuPeer peer = (MenuPeer)this.peer; MenuPeer peer = (MenuPeer)this.peer;
if (peer != null) { if (peer != null) {
peer.delItem(index);
mi.removeNotify(); mi.removeNotify();
mi.parent = null; mi.parent = null;
peer.delItem(index);
} }
} }
} }
......
...@@ -222,7 +222,6 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -222,7 +222,6 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
if (m.parent != null) { if (m.parent != null) {
m.parent.remove(m); m.parent.remove(m);
} }
menus.addElement(m);
m.parent = this; m.parent = this;
MenuBarPeer peer = (MenuBarPeer)this.peer; MenuBarPeer peer = (MenuBarPeer)this.peer;
...@@ -232,6 +231,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -232,6 +231,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
} }
peer.addMenu(m); peer.addMenu(m);
} }
menus.addElement(m);
return m; return m;
} }
} }
...@@ -248,9 +248,9 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -248,9 +248,9 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
menus.removeElementAt(index); menus.removeElementAt(index);
MenuBarPeer peer = (MenuBarPeer)this.peer; MenuBarPeer peer = (MenuBarPeer)this.peer;
if (peer != null) { if (peer != null) {
peer.delMenu(index);
m.removeNotify(); m.removeNotify();
m.parent = null; m.parent = null;
peer.delMenu(index);
} }
if (helpMenu == m) { if (helpMenu == m) {
helpMenu = null; helpMenu = null;
......
...@@ -75,7 +75,7 @@ public abstract class MenuComponent implements java.io.Serializable { ...@@ -75,7 +75,7 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see #setFont(Font) * @see #setFont(Font)
* @see #getFont() * @see #getFont()
*/ */
Font font; volatile Font font;
/** /**
* The menu component's name, which defaults to <code>null</code>. * The menu component's name, which defaults to <code>null</code>.
...@@ -292,11 +292,13 @@ public abstract class MenuComponent implements java.io.Serializable { ...@@ -292,11 +292,13 @@ public abstract class MenuComponent implements java.io.Serializable {
* @see java.awt.font.TextAttribute * @see java.awt.font.TextAttribute
*/ */
public void setFont(Font f) { public void setFont(Font f) {
font = f; synchronized (getTreeLock()) {
//Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font) font = f;
MenuComponentPeer peer = this.peer; //Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
if (peer != null) { MenuComponentPeer peer = this.peer;
peer.setFont(f); if (peer != null) {
peer.setFont(f);
}
} }
} }
......
...@@ -71,7 +71,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer { ...@@ -71,7 +71,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer {
enable(false); enable(false);
} }
public void readShortcutLabel() { private void readShortcutLabel() {
//Fix for 6288578: PIT. Windows: Shortcuts displayed for the menuitems in a popup menu //Fix for 6288578: PIT. Windows: Shortcuts displayed for the menuitems in a popup menu
WMenuPeer ancestor = parent; WMenuPeer ancestor = parent;
while (ancestor != null && !(ancestor instanceof WMenuBarPeer)) { while (ancestor != null && !(ancestor instanceof WMenuBarPeer)) {
...@@ -115,7 +115,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer { ...@@ -115,7 +115,7 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer {
readShortcutLabel(); readShortcutLabel();
} }
protected void checkMenuCreation() void checkMenuCreation()
{ {
// fix for 5088782: check if menu peer is created successfully // fix for 5088782: check if menu peer is created successfully
if (pData == 0) if (pData == 0)
......
...@@ -34,16 +34,16 @@ abstract class WObjectPeer { ...@@ -34,16 +34,16 @@ abstract class WObjectPeer {
} }
// The Windows handle for the native widget. // The Windows handle for the native widget.
long pData; volatile long pData;
// if the native peer has been destroyed // if the native peer has been destroyed
boolean destroyed = false; private volatile boolean destroyed;
// The associated AWT object. // The associated AWT object.
Object target; volatile Object target;
private volatile boolean disposed; private volatile boolean disposed;
// set from JNI if any errors in creating the peer occur // set from JNI if any errors in creating the peer occur
protected Error createError = null; volatile Error createError = null;
// used to synchronize the state of this peer // used to synchronize the state of this peer
private final Object stateLock = new Object(); private final Object stateLock = new Object();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -3757,7 +3757,10 @@ void AwtComponent::OpenCandidateWindow(int x, int y) ...@@ -3757,7 +3757,10 @@ void AwtComponent::OpenCandidateWindow(int x, int y)
HWND hWnd = GetHWnd(); HWND hWnd = GetHWnd();
HWND hTop = GetTopLevelParentForWindow(hWnd); HWND hTop = GetTopLevelParentForWindow(hWnd);
::ClientToScreen(hTop, &p); ::ClientToScreen(hTop, &p);
if (!m_bitsCandType) {
SetCandidateWindow(m_bitsCandType, x - p.x, y - p.y);
return;
}
for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) { for (int iCandType=0; iCandType<32; iCandType++, bits<<=1) {
if ( m_bitsCandType & bits ) if ( m_bitsCandType & bits )
SetCandidateWindow(iCandType, x - p.x, y - p.y); SetCandidateWindow(iCandType, x - p.x, y - p.y);
...@@ -3775,7 +3778,7 @@ void AwtComponent::SetCandidateWindow(int iCandType, int x, int y) ...@@ -3775,7 +3778,7 @@ void AwtComponent::SetCandidateWindow(int iCandType, int x, int y)
HIMC hIMC = ImmGetContext(hwnd); HIMC hIMC = ImmGetContext(hwnd);
CANDIDATEFORM cf; CANDIDATEFORM cf;
cf.dwIndex = iCandType; cf.dwIndex = iCandType;
cf.dwStyle = CFS_CANDIDATEPOS; cf.dwStyle = CFS_POINT;
cf.ptCurrentPos.x = x; cf.ptCurrentPos.x = x;
cf.ptCurrentPos.y = y; cf.ptCurrentPos.y = y;
...@@ -3807,8 +3810,12 @@ MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam) ...@@ -3807,8 +3810,12 @@ MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)
MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType) MsgRouting AwtComponent::WmImeNotify(WPARAM subMsg, LPARAM bitsCandType)
{ {
if (!m_useNativeCompWindow && subMsg == IMN_OPENCANDIDATE) { if (!m_useNativeCompWindow) {
m_bitsCandType = bitsCandType; if (subMsg == IMN_OPENCANDIDATE) {
m_bitsCandType = subMsg;
} else if (subMsg != IMN_SETCANDIDATEPOS) {
m_bitsCandType = 0;
}
InquireCandidatePosition(); InquireCandidatePosition();
return mrConsume; return mrConsume;
} }
...@@ -4069,14 +4076,14 @@ HWND AwtComponent::GetProxyFocusOwner() ...@@ -4069,14 +4076,14 @@ HWND AwtComponent::GetProxyFocusOwner()
return (HWND)NULL; return (HWND)NULL;
} }
/* Call DefWindowProc for the focus proxy, if any */ /* Redirects message to the focus proxy, if any */
void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam, void AwtComponent::CallProxyDefWindowProc(UINT message, WPARAM wParam,
LPARAM lParam, LRESULT &retVal, MsgRouting &mr) LPARAM lParam, LRESULT &retVal, MsgRouting &mr)
{ {
if (mr != mrConsume) { if (mr != mrConsume) {
HWND proxy = GetProxyFocusOwner(); HWND proxy = GetProxyFocusOwner();
if (proxy != NULL && ::IsWindowEnabled(proxy)) { if (proxy != NULL && ::IsWindowEnabled(proxy)) {
retVal = ComCtl32Util::GetInstance().DefWindowProc(NULL, proxy, message, wParam, lParam); retVal = ::DefWindowProc(proxy, message, wParam, lParam);
mr = mrConsume; mr = mrConsume;
} }
} }
...@@ -4155,7 +4162,7 @@ MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo) ...@@ -4155,7 +4162,7 @@ MsgRouting AwtComponent::WmDrawItem(UINT ctrlId, DRAWITEMSTRUCT &drawInfo)
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (drawInfo.CtlType == ODT_MENU) { if (drawInfo.CtlType == ODT_MENU) {
if (drawInfo.itemData != 0) { if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) {
AwtMenu* menu = (AwtMenu*)(drawInfo.itemData); AwtMenu* menu = (AwtMenu*)(drawInfo.itemData);
menu->DrawItem(drawInfo); menu->DrawItem(drawInfo);
} }
......
...@@ -34,6 +34,13 @@ ...@@ -34,6 +34,13 @@
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/ */
/***********************************************************************/
// struct for _DelItem() method
struct DelItemStruct {
jobject menuitem;
jint index;
};
/************************************************************************ /************************************************************************
* AwtMenuItem fields * AwtMenuItem fields
*/ */
...@@ -64,7 +71,6 @@ void AwtMenu::Dispose() ...@@ -64,7 +71,6 @@ void AwtMenu::Dispose()
::DestroyMenu(m_hMenu); ::DestroyMenu(m_hMenu);
m_hMenu = NULL; m_hMenu = NULL;
} }
AwtMenuItem::Dispose(); AwtMenuItem::Dispose();
} }
...@@ -73,7 +79,7 @@ LPCTSTR AwtMenu::GetClassName() { ...@@ -73,7 +79,7 @@ LPCTSTR AwtMenu::GetClassName() {
} }
/* Create a new AwtMenu object and menu. */ /* Create a new AwtMenu object and menu. */
AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu) AwtMenu* AwtMenu::Create(jobject self, jobject parent)
{ {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -85,6 +91,9 @@ AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu) ...@@ -85,6 +91,9 @@ AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu)
return NULL; return NULL;
} }
JNI_CHECK_NULL_GOTO(parent, "peer", done);
AwtMenu* parentMenu = (AwtMenu*) JNI_GET_PDATA(parent);
target = env->GetObjectField(self, AwtObject::targetID); target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done); JNI_CHECK_NULL_GOTO(target, "null target", done);
...@@ -119,6 +128,46 @@ done: ...@@ -119,6 +128,46 @@ done:
return menu; return menu;
} }
void AwtMenu::_AddSeparator(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject self = (jobject)param;
AwtMenu *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenu *)pData;
m->AddSeparator();
ret:
env->DeleteGlobalRef(self);
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_AddSeparator, param);
}
}
void AwtMenu::_DelItem(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
DelItemStruct *dis = (DelItemStruct*) param;
jobject self = dis->menuitem;
jint index = dis->index;
AwtMenu *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenu *)pData;
m->DeleteItem(static_cast<UINT>(index));
ret:
env->DeleteGlobalRef(self);
delete dis;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_DelItem, param);
}
}
void AwtMenu::UpdateLayout() void AwtMenu::UpdateLayout()
{ {
UpdateLayout(GetHMenu()); UpdateLayout(GetHMenu());
...@@ -239,6 +288,7 @@ AwtMenuItem* AwtMenu::GetItem(jobject target, jint index) ...@@ -239,6 +288,7 @@ AwtMenuItem* AwtMenu::GetItem(jobject target, jint index)
} }
jobject menuItem = env->CallObjectMethod(target, AwtMenu::getItemMID, jobject menuItem = env->CallObjectMethod(target, AwtMenu::getItemMID,
index); index);
if (!menuItem) return NULL; // menu item was removed concurrently
DASSERT(!safe_ExceptionOccurred(env)); DASSERT(!safe_ExceptionOccurred(env));
jobject wMenuItemPeer = GetPeerForTarget(env, menuItem); jobject wMenuItemPeer = GetPeerForTarget(env, menuItem);
...@@ -264,9 +314,9 @@ void AwtMenu::DrawItems(DRAWITEMSTRUCT& drawInfo) ...@@ -264,9 +314,9 @@ void AwtMenu::DrawItems(DRAWITEMSTRUCT& drawInfo)
} }
/* target is a java.awt.Menu */ /* target is a java.awt.Menu */
jobject target = GetTarget(env); jobject target = GetTarget(env);
if(!target || env->ExceptionCheck()) return;
int nCount = CountItem(target); int nCount = CountItem(target);
for (int i = 0; i < nCount; i++) { for (int i = 0; i < nCount && !env->ExceptionCheck(); i++) {
AwtMenuItem* awtMenuItem = GetItem(target, i); AwtMenuItem* awtMenuItem = GetItem(target, i);
if (awtMenuItem != NULL) { if (awtMenuItem != NULL) {
SendDrawItem(awtMenuItem, drawInfo); SendDrawItem(awtMenuItem, drawInfo);
...@@ -294,8 +344,9 @@ void AwtMenu::MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo) ...@@ -294,8 +344,9 @@ void AwtMenu::MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo)
} }
/* target is a java.awt.Menu */ /* target is a java.awt.Menu */
jobject target = GetTarget(env); jobject target = GetTarget(env);
if(!target || env->ExceptionCheck()) return;
int nCount = CountItem(target); int nCount = CountItem(target);
for (int i = 0; i < nCount; i++) { for (int i = 0; i < nCount && !env->ExceptionCheck(); i++) {
AwtMenuItem* awtMenuItem = GetItem(target, i); AwtMenuItem* awtMenuItem = GetItem(target, i);
if (awtMenuItem != NULL) { if (awtMenuItem != NULL) {
SendMeasureItem(awtMenuItem, hDC, measureInfo); SendMeasureItem(awtMenuItem, hDC, measureInfo);
...@@ -321,24 +372,6 @@ BOOL AwtMenu::IsTopMenu() ...@@ -321,24 +372,6 @@ BOOL AwtMenu::IsTopMenu()
return (GetMenuBar() == GetMenuContainer()); return (GetMenuBar() == GetMenuContainer());
} }
LRESULT AwtMenu::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENU_ADDSEPARATOR:
this->AddSeparator();
break;
case MENU_DELITEM:
this->DeleteItem(static_cast<UINT>(args->param1));
break;
default:
AwtMenuItem::WinThreadExecProc(args);
break;
}
return 0L;
}
/************************************************************************ /************************************************************************
* WMenuPeer native methods * WMenuPeer native methods
*/ */
...@@ -380,15 +413,14 @@ Java_sun_awt_windows_WMenuPeer_addSeparator(JNIEnv *env, jobject self) ...@@ -380,15 +413,14 @@ Java_sun_awt_windows_WMenuPeer_addSeparator(JNIEnv *env, jobject self)
{ {
TRY; TRY;
PDATA pData; jobject selfGlobalRef = env->NewGlobalRef(self);
JNI_CHECK_PEER_RETURN(self);
AwtObject::WinThreadExec(self, AwtMenu::MENU_ADDSEPARATOR); AwtToolkit::GetInstance().SyncCall(AwtMenu::_AddSeparator, selfGlobalRef);
// selfGlobalRef is deleted in _AddSeparator
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
/* /*
* Class: sun_awt_windows_WMenuPeer * Class: sun_awt_windows_WMenuPeer
* Method: delItem * Method: delItem
...@@ -400,10 +432,12 @@ Java_sun_awt_windows_WMenuPeer_delItem(JNIEnv *env, jobject self, ...@@ -400,10 +432,12 @@ Java_sun_awt_windows_WMenuPeer_delItem(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; DelItemStruct *dis = new DelItemStruct;
JNI_CHECK_PEER_RETURN(self); dis->menuitem = env->NewGlobalRef(self);
dis->index = index;
AwtObject::WinThreadExec(self, AwtMenu::MENU_DELITEM, index); AwtToolkit::GetInstance().SyncCall(AwtMenu::_DelItem, dis);
// global refs and dis are deleted in _DelItem
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -419,13 +453,8 @@ Java_sun_awt_windows_WMenuPeer_createMenu(JNIEnv *env, jobject self, ...@@ -419,13 +453,8 @@ Java_sun_awt_windows_WMenuPeer_createMenu(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; AwtToolkit::CreateComponent(self, menuBar,
JNI_CHECK_PEER_RETURN(menuBar); (AwtToolkit::ComponentFactory)AwtMenu::Create);
AwtMenuBar* awtMenuBar = (AwtMenuBar *)pData;
AwtToolkit::CreateComponent(self, awtMenuBar,
(AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -441,13 +470,8 @@ Java_sun_awt_windows_WMenuPeer_createSubMenu(JNIEnv *env, jobject self, ...@@ -441,13 +470,8 @@ Java_sun_awt_windows_WMenuPeer_createSubMenu(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; AwtToolkit::CreateComponent(self, menu,
JNI_CHECK_PEER_RETURN(menu); (AwtToolkit::ComponentFactory)AwtMenu::Create);
AwtMenu* awtMenu = (AwtMenu *)pData;
AwtToolkit::CreateComponent(self, awtMenu,
(AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -42,13 +42,6 @@ class AwtMenuBar; ...@@ -42,13 +42,6 @@ class AwtMenuBar;
class AwtMenu : public AwtMenuItem { class AwtMenu : public AwtMenuItem {
public: public:
// id's for methods executed on toolkit thread
enum {
MENU_ADDSEPARATOR = MENUITEM_LAST+1,
MENU_DELITEM,
MENU_LAST
};
/* method ids for java.awt.Menu */ /* method ids for java.awt.Menu */
static jmethodID countItemsMID; static jmethodID countItemsMID;
static jmethodID getItemMID; static jmethodID getItemMID;
...@@ -61,7 +54,7 @@ public: ...@@ -61,7 +54,7 @@ public:
virtual LPCTSTR GetClassName(); virtual LPCTSTR GetClassName();
/* Create a new AwtMenu. This must be run on the main thread. */ /* Create a new AwtMenu. This must be run on the main thread. */
static AwtMenu* Create(jobject self, AwtMenu* parentMenu); static AwtMenu* Create(jobject self, jobject parent);
INLINE HMENU GetHMenu() { return m_hMenu; } INLINE HMENU GetHMenu() { return m_hMenu; }
INLINE void SetHMenu(HMENU hMenu) { INLINE void SetHMenu(HMENU hMenu) {
...@@ -94,9 +87,9 @@ public: ...@@ -94,9 +87,9 @@ public:
void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo); void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo); void MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
// invoked on Toolkit thread // invoked on Toolkit thread
static void _AddSeparator(void *param);
static void _DelItem(void *param);
static void _CreateMenu(void *param); static void _CreateMenu(void *param);
static void _CreateSubMenu(void *param); static void _CreateSubMenu(void *param);
virtual BOOL IsSeparator() { return FALSE; } virtual BOOL IsSeparator() { return FALSE; }
......
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
*/ */
/***********************************************************************/
// struct for _DelItem() method
struct DelItemStruct {
jobject menuitem;
jint index;
};
/***********************************************************************/ /***********************************************************************/
// struct for _AddMenu() method // struct for _AddMenu() method
struct AddMenuStruct { struct AddMenuStruct {
...@@ -130,18 +136,6 @@ HWND AwtMenuBar::GetOwnerHWnd() ...@@ -130,18 +136,6 @@ HWND AwtMenuBar::GetOwnerHWnd()
return myFrame->GetHWnd(); return myFrame->GetHWnd();
} }
void AwtMenuBar::SendDrawItem(AwtMenuItem* awtMenuItem,
DRAWITEMSTRUCT& drawInfo)
{
awtMenuItem->DrawItem(drawInfo);
}
void AwtMenuBar::SendMeasureItem(AwtMenuItem* awtMenuItem,
HDC hDC, MEASUREITEMSTRUCT& measureInfo)
{
awtMenuItem->MeasureItem(hDC, measureInfo);
}
int AwtMenuBar::CountItem(jobject menuBar) int AwtMenuBar::CountItem(jobject menuBar)
{ {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -159,13 +153,16 @@ AwtMenuItem* AwtMenuBar::GetItem(jobject target, long index) ...@@ -159,13 +153,16 @@ AwtMenuItem* AwtMenuBar::GetItem(jobject target, long index)
} }
jobject menu = env->CallObjectMethod(target, AwtMenuBar::getMenuMID,index); jobject menu = env->CallObjectMethod(target, AwtMenuBar::getMenuMID,index);
if (!menu) return NULL; // menu item was removed concurrently
DASSERT(!safe_ExceptionOccurred(env)); DASSERT(!safe_ExceptionOccurred(env));
jobject menuItemPeer = GetPeerForTarget(env, menu); jobject menuItemPeer = GetPeerForTarget(env, menu);
PDATA pData; PDATA pData;
JNI_CHECK_PEER_RETURN_NULL(menuItemPeer); AwtMenuItem* awtMenuItem = NULL;
AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData; JNI_CHECK_PEER_GOTO(menuItemPeer, done);
awtMenuItem = (AwtMenuItem*)pData;
done:
env->DeleteLocalRef(menu); env->DeleteLocalRef(menu);
env->DeleteLocalRef(menuItemPeer); env->DeleteLocalRef(menuItemPeer);
...@@ -212,20 +209,6 @@ void AwtMenuBar::RedrawMenuBar() { ...@@ -212,20 +209,6 @@ void AwtMenuBar::RedrawMenuBar() {
VERIFY(::DrawMenuBar(GetOwnerHWnd())); VERIFY(::DrawMenuBar(GetOwnerHWnd()));
} }
LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENUBAR_DELITEM:
this->DeleteItem(static_cast<UINT>(args->param1));
break;
default:
AwtMenu::WinThreadExecProc(args);
break;
}
return 0L;
}
void AwtMenuBar::_AddMenu(void *param) void AwtMenuBar::_AddMenu(void *param)
{ {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -254,6 +237,28 @@ ret: ...@@ -254,6 +237,28 @@ ret:
delete ams; delete ams;
} }
void AwtMenuBar::_DelItem(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
DelItemStruct *dis = (DelItemStruct*) param;
jobject self = dis->menuitem;
jint index = dis->index;
AwtMenuBar *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuBar *)pData;
m->DeleteItem(static_cast<UINT>(index));
ret:
env->DeleteGlobalRef(self);
delete dis;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuBar::_DelItem, param);
}
}
/************************************************************************ /************************************************************************
* MenuBar native methods * MenuBar native methods
*/ */
...@@ -322,9 +327,12 @@ Java_sun_awt_windows_WMenuBarPeer_delMenu(JNIEnv *env, jobject self, ...@@ -322,9 +327,12 @@ Java_sun_awt_windows_WMenuBarPeer_delMenu(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; DelItemStruct *dis = new DelItemStruct;
JNI_CHECK_PEER_RETURN(self); dis->menuitem = env->NewGlobalRef(self);
AwtObject::WinThreadExec(self, AwtMenuBar::MENUBAR_DELITEM, (LPARAM)index); dis->index = index;
AwtToolkit::GetInstance().SyncCall(AwtMenuBar::_DelItem, dis);
// global refs and dis are deleted in _DelItem
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -343,9 +351,6 @@ Java_sun_awt_windows_WMenuBarPeer_create(JNIEnv *env, jobject self, ...@@ -343,9 +351,6 @@ Java_sun_awt_windows_WMenuBarPeer_create(JNIEnv *env, jobject self,
AwtToolkit::CreateComponent(self, frame, AwtToolkit::CreateComponent(self, frame,
(AwtToolkit::ComponentFactory) (AwtToolkit::ComponentFactory)
AwtMenuBar::Create); AwtMenuBar::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -42,10 +42,6 @@ class AwtFrame; ...@@ -42,10 +42,6 @@ class AwtFrame;
class AwtMenuBar : public AwtMenu { class AwtMenuBar : public AwtMenu {
public: public:
// id's for methods executed on toolkit thread
enum MenuExecIds {
MENUBAR_DELITEM = MENU_LAST+1
};
/* java.awt.MenuBar method ids */ /* java.awt.MenuBar method ids */
static jmethodID getMenuCountMID; static jmethodID getMenuCountMID;
...@@ -73,20 +69,15 @@ public: ...@@ -73,20 +69,15 @@ public:
AwtMenuItem* GetItem(jobject target, long index); AwtMenuItem* GetItem(jobject target, long index);
int CountItem(jobject menuBar); int CountItem(jobject menuBar);
void SendDrawItem(AwtMenuItem* awtMenuItem,
DRAWITEMSTRUCT& drawInfo);
void SendMeasureItem(AwtMenuItem* awtMenuItem,
HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void DrawItem(DRAWITEMSTRUCT& drawInfo); void DrawItem(DRAWITEMSTRUCT& drawInfo);
void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo); void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
void AddItem(AwtMenuItem* item); void AddItem(AwtMenuItem* item);
void DeleteItem(UINT index); void DeleteItem(UINT index);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
// called on Toolkit thread // called on Toolkit thread
static void _AddMenu(void *param); static void _AddMenu(void *param);
static void _DelItem(void *param);
protected: protected:
AwtFrame* m_frame; AwtFrame* m_frame;
}; };
......
...@@ -50,6 +50,16 @@ struct SetLabelStruct { ...@@ -50,6 +50,16 @@ struct SetLabelStruct {
jobject menuitem; jobject menuitem;
jstring label; jstring label;
}; };
// struct for _SetEnable() method
struct SetEnableStruct {
jobject menuitem;
jboolean isEnabled;
};
// struct for _setState() method
struct SetStateStruct {
jobject menuitem;
jboolean isChecked;
};
/************************************************************************ /************************************************************************
* AwtMenuItem fields * AwtMenuItem fields
*/ */
...@@ -104,6 +114,7 @@ void AwtMenuItem::RemoveCmdID() ...@@ -104,6 +114,7 @@ void AwtMenuItem::RemoveCmdID()
{ {
if (m_freeId) { if (m_freeId) {
AwtToolkit::GetInstance().RemoveCmdID( GetID() ); AwtToolkit::GetInstance().RemoveCmdID( GetID() );
m_freeId = FALSE;
} }
} }
void AwtMenuItem::Dispose() void AwtMenuItem::Dispose()
...@@ -112,6 +123,7 @@ void AwtMenuItem::Dispose() ...@@ -112,6 +123,7 @@ void AwtMenuItem::Dispose()
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (m_peerObject != NULL) { if (m_peerObject != NULL) {
JNI_SET_DESTROYED(m_peerObject);
JNI_SET_PDATA(m_peerObject, NULL); JNI_SET_PDATA(m_peerObject, NULL);
env->DeleteGlobalRef(m_peerObject); env->DeleteGlobalRef(m_peerObject);
m_peerObject = NULL; m_peerObject = NULL;
...@@ -205,13 +217,12 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer) ...@@ -205,13 +217,12 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer)
if (env->EnsureLocalCapacity(1) < 0) { if (env->EnsureLocalCapacity(1) < 0) {
return NULL; return NULL;
} }
PDATA pData; JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
JNI_CHECK_PEER_RETURN_NULL(menuPeer);
/* target is a java.awt.MenuItem */ /* target is a java.awt.MenuItem */
target = env->GetObjectField(peer, AwtObject::targetID); target = env->GetObjectField(peer, AwtObject::targetID);
AwtMenu* menu = (AwtMenu *)pData; AwtMenu* menu = (AwtMenu *)JNI_GET_PDATA(menuPeer);
item = new AwtMenuItem(); item = new AwtMenuItem();
jboolean isCheckbox = jboolean isCheckbox =
(jboolean)env->GetBooleanField(peer, AwtMenuItem::isCheckboxID); (jboolean)env->GetBooleanField(peer, AwtMenuItem::isCheckboxID);
...@@ -222,7 +233,9 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer) ...@@ -222,7 +233,9 @@ AwtMenuItem* AwtMenuItem::Create(jobject peer, jobject menuPeer)
item->LinkObjects(env, peer); item->LinkObjects(env, peer);
item->SetMenuContainer(menu); item->SetMenuContainer(menu);
item->SetNewID(); item->SetNewID();
menu->AddItem(item); if (menu != NULL) {
menu->AddItem(item);
}
} catch (...) { } catch (...) {
env->DeleteLocalRef(target); env->DeleteLocalRef(target);
throw; throw;
...@@ -763,30 +776,6 @@ void AwtMenuItem::UpdateContainerLayout() { ...@@ -763,30 +776,6 @@ void AwtMenuItem::UpdateContainerLayout() {
} }
} }
LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENUITEM_ENABLE:
{
BOOL isEnabled = (BOOL)args->param1;
this->Enable(isEnabled);
}
break;
case MENUITEM_SETSTATE:
{
BOOL isChecked = (BOOL)args->param1;
this->SetState(isChecked);
}
break;
default:
AwtObject::WinThreadExecProc(args);
break;
}
return 0L;
}
void AwtMenuItem::_SetLabel(void *param) { void AwtMenuItem::_SetLabel(void *param) {
if (AwtToolkit::IsMainThread()) { if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -886,6 +875,53 @@ ret: ...@@ -886,6 +875,53 @@ ret:
} }
} }
void AwtMenuItem::_SetEnable(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetEnableStruct *ses = (SetEnableStruct*) param;
jobject self = ses->menuitem;
jboolean isEnabled = ses->isEnabled;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
m->Enable(isEnabled);
ret:
env->DeleteGlobalRef(self);
delete ses;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetEnable, param);
}
}
void AwtMenuItem::_SetState(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetStateStruct *sts = (SetStateStruct*) param;
jobject self = sts->menuitem;
jboolean isChecked = sts->isChecked;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
m->SetState(isChecked);
ret:
env->DeleteGlobalRef(self);
delete sts;
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetState, param);
}
}
BOOL AwtMenuItem::IsSeparator() { BOOL AwtMenuItem::IsSeparator() {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (env->EnsureLocalCapacity(2) < 0) { if (env->EnsureLocalCapacity(2) < 0) {
...@@ -1049,13 +1085,9 @@ Java_sun_awt_windows_WMenuItemPeer_create(JNIEnv *env, jobject self, ...@@ -1049,13 +1085,9 @@ Java_sun_awt_windows_WMenuItemPeer_create(JNIEnv *env, jobject self,
{ {
TRY; TRY;
JNI_CHECK_NULL_RETURN(menu, "null Menu");
AwtToolkit::CreateComponent(self, menu, AwtToolkit::CreateComponent(self, menu,
(AwtToolkit::ComponentFactory) (AwtToolkit::ComponentFactory)
AwtMenuItem::Create); AwtMenuItem::Create);
PDATA pData;
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -1070,9 +1102,12 @@ Java_sun_awt_windows_WMenuItemPeer_enable(JNIEnv *env, jobject self, ...@@ -1070,9 +1102,12 @@ Java_sun_awt_windows_WMenuItemPeer_enable(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; SetEnableStruct *ses = new SetEnableStruct;
JNI_CHECK_PEER_RETURN(self); ses->menuitem = env->NewGlobalRef(self);
AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_ENABLE, (LPARAM)on ); ses->isEnabled = on;
AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetEnable, ses);
// global refs and ses are deleted in _SetEnable
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
...@@ -1111,9 +1146,12 @@ Java_sun_awt_windows_WCheckboxMenuItemPeer_setState(JNIEnv *env, jobject self, ...@@ -1111,9 +1146,12 @@ Java_sun_awt_windows_WCheckboxMenuItemPeer_setState(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData; SetStateStruct *sts = new SetStateStruct;
JNI_CHECK_PEER_RETURN(self); sts->menuitem = env->NewGlobalRef(self);
AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_SETSTATE, (LPARAM)on); sts->isChecked = on;
AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetState, sts);
// global refs and sts are deleted in _SetState
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -45,13 +45,6 @@ class AwtMenu; ...@@ -45,13 +45,6 @@ class AwtMenu;
class AwtMenuItem : public AwtObject { class AwtMenuItem : public AwtObject {
public: public:
// id's for methods executed on toolkit thread
enum {
MENUITEM_ENABLE,
MENUITEM_SETSTATE,
MENUITEM_LAST
};
/* java.awt.MenuComponent fields */ /* java.awt.MenuComponent fields */
static jfieldID fontID; static jfieldID fontID;
static jfieldID appContextID; static jfieldID appContextID;
...@@ -154,13 +147,14 @@ public: ...@@ -154,13 +147,14 @@ public:
*/ */
MsgRouting WmNotify(UINT notifyCode); MsgRouting WmNotify(UINT notifyCode);
virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
virtual BOOL IsDisabledAndPopup() { virtual BOOL IsDisabledAndPopup() {
return FALSE; return FALSE;
} }
virtual BOOL IsSeparator(); virtual BOOL IsSeparator();
// invoked on Toolkit thread // invoked on Toolkit thread
static void _SetState(void *param);
static void _SetEnable(void *param);
static void _SetLabel(void *param); static void _SetLabel(void *param);
static void _UpdateLayout(void *param); static void _UpdateLayout(void *param);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,7 +65,7 @@ LPCTSTR AwtPopupMenu::GetClassName() { ...@@ -65,7 +65,7 @@ LPCTSTR AwtPopupMenu::GetClassName() {
} }
/* Create a new AwtPopupMenu object and menu. */ /* Create a new AwtPopupMenu object and menu. */
AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent) AwtPopupMenu* AwtPopupMenu::Create(jobject self, jobject parent)
{ {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...@@ -77,6 +77,9 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent) ...@@ -77,6 +77,9 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
return NULL; return NULL;
} }
JNI_CHECK_NULL_GOTO(parent, "peer", done);
AwtComponent* awtParent = (AwtComponent*) JNI_GET_PDATA(parent);
target = env->GetObjectField(self, AwtObject::targetID); target = env->GetObjectField(self, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done); JNI_CHECK_NULL_GOTO(target, "null target", done);
...@@ -94,7 +97,7 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent) ...@@ -94,7 +97,7 @@ AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
popupMenu->SetHMenu(hMenu); popupMenu->SetHMenu(hMenu);
popupMenu->LinkObjects(env, self); popupMenu->LinkObjects(env, self);
popupMenu->SetParent(parent); popupMenu->SetParent(awtParent);
} catch (...) { } catch (...) {
env->DeleteLocalRef(target); env->DeleteLocalRef(target);
throw; throw;
...@@ -274,12 +277,8 @@ Java_sun_awt_windows_WPopupMenuPeer_createMenu(JNIEnv *env, jobject self, ...@@ -274,12 +277,8 @@ Java_sun_awt_windows_WPopupMenuPeer_createMenu(JNIEnv *env, jobject self,
{ {
TRY; TRY;
PDATA pData;
JNI_CHECK_PEER_RETURN(parent);
AwtComponent* awtParent = (AwtComponent *)pData;
AwtToolkit::CreateComponent( AwtToolkit::CreateComponent(
self, awtParent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create, FALSE); self, parent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create);
JNI_CHECK_PEER_CREATION_RETURN(self);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -47,7 +47,7 @@ public: ...@@ -47,7 +47,7 @@ public:
virtual LPCTSTR GetClassName(); virtual LPCTSTR GetClassName();
/* Create a new AwtPopupMenu. This must be run on the main thread. */ /* Create a new AwtPopupMenu. This must be run on the main thread. */
static AwtPopupMenu* Create(jobject self, AwtComponent* parent); static AwtPopupMenu* Create(jobject self, jobject parent);
/* Display the popup modally. */ /* Display the popup modally. */
void Show(JNIEnv *env, jobject event, BOOL isTrayIconPopup); void Show(JNIEnv *env, jobject event, BOOL isTrayIconPopup);
......
...@@ -172,6 +172,9 @@ safe_ExceptionOccurred(JNIEnv *env) throw (std::bad_alloc) { ...@@ -172,6 +172,9 @@ safe_ExceptionOccurred(JNIEnv *env) throw (std::bad_alloc) {
env->ExceptionClear(); env->ExceptionClear();
// rethrow exception // rethrow exception
env->Throw(xcp); env->Throw(xcp);
// temp solution to reveal all concurrency issues in jtreg and JCK
// we will switch it back to silent mode before the release
env->ExceptionDescribe();
return xcp; return xcp;
} }
} }
......
/*
* Copyright (c) 2015 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 8079595
@summary Resizing dialog which is JWindow parent makes JVM crash
@author Semyon Sadetsky
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
public class ShowChildWhileResizingTest {
private static Window dialog;
private static Timer timer;
private static Point point;
public static void main(String[] args) throws Exception {
dialog = new Frame();
dialog.add(new JPanel());
dialog.setVisible(true);
dialog.setBounds(100, 100, 200, 200);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
final Window dependentWindow = new JWindow(dialog);
JPanel panel = new JPanel();
panel.add(new JButton("button"));
dependentWindow.add(panel);
dependentWindow.setVisible(true);
dependentWindow.setBounds(0, 0, 50, 50);
timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dependentWindow
.setVisible(!dependentWindow.isVisible());
}
});
timer.start();
}
});
Robot robot = new Robot();
robot.setAutoDelay(5);
robot.delay(300);
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
point = dialog.getLocationOnScreen();
}
});
robot.mouseMove(point.x + 200 - dialog.getInsets().right/2,
point.y + 200 - dialog.getInsets().bottom/2);
robot.mousePress(InputEvent.BUTTON1_MASK);
for(int i = 0; i < 100; i++) {
robot.mouseMove(point.x + 200 + i, point.y + 200 + i);
}
robot.mouseRelease(InputEvent.BUTTON1_MASK);
timer.stop();
dialog.dispose();
System.out.println("ok");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册