提交 ddefeddf 编写于 作者: S serb

4717864: setFont() does not update Fonts of Menus already on screen

Reviewed-by: art, bagiras
上级 5bb3779f
......@@ -183,7 +183,9 @@ class WMenuItemPeer extends WObjectPeer implements MenuItemPeer {
*/
private static native void initIDs();
// Needed for MenuComponentPeer.
public void setFont(Font f) {
private native void _setFont(Font f);
public void setFont(final Font f) {
_setFont(f);
}
}
......@@ -119,6 +119,41 @@ done:
return menu;
}
void AwtMenu::UpdateLayout()
{
UpdateLayout(GetHMenu());
RedrawMenuBar();
}
void AwtMenu::UpdateLayout(const HMENU hmenu)
{
const int nMenuItemCount = ::GetMenuItemCount(hmenu);
static MENUITEMINFO mii;
for (int idx = 0; idx < nMenuItemCount; ++idx) {
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID
| MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE;
if (::GetMenuItemInfo(hmenu, idx, TRUE, &mii)) {
VERIFY(::RemoveMenu(hmenu, idx, MF_BYPOSITION));
VERIFY(::InsertMenuItem(hmenu, idx, TRUE, &mii));
if (mii.hSubMenu != NULL) {
UpdateLayout(mii.hSubMenu);
}
}
}
}
void AwtMenu::UpdateContainerLayout()
{
AwtMenu* menu = GetMenuContainer();
if (menu != NULL) {
menu->UpdateLayout();
} else {
UpdateLayout();
}
}
AwtMenuBar* AwtMenu::GetMenuBar() {
return (GetMenuContainer() == NULL) ? NULL : GetMenuContainer()->GetMenuBar();
}
......
......@@ -72,6 +72,8 @@ public:
virtual AwtMenuBar* GetMenuBar();
void AddSeparator();
virtual void UpdateContainerLayout();
void UpdateLayout();
virtual void AddItem(AwtMenuItem *item);
virtual void DeleteItem(UINT index);
......@@ -103,6 +105,7 @@ protected:
virtual void RemoveCmdID() { /* do nothing */ }
private:
void UpdateLayout(const HMENU hmenu);
HMENU m_hMenu;
};
......
......@@ -198,7 +198,15 @@ void AwtMenuBar::DeleteItem(UINT index)
if (hOwnerWnd != NULL) {
VERIFY(::InvalidateRect(hOwnerWnd,0,TRUE));
}
::DrawMenuBar(GetOwnerHWnd());
RedrawMenuBar();
}
/**
* If the menu changes after the system has created the window,
* this function must be called to draw the changed menu bar.
*/
void AwtMenuBar::RedrawMenuBar() {
VERIFY(::DrawMenuBar(GetOwnerHWnd()));
}
LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args)
......@@ -232,7 +240,7 @@ void AwtMenuBar::_AddMenu(void *param)
if (::IsWindow(m->GetOwnerHWnd()))
{
/* The menu was already created and added during peer creation -- redraw */
::DrawMenuBar(m->GetOwnerHWnd());
m->RedrawMenuBar();
}
ret:
env->DeleteGlobalRef(self);
......
......@@ -65,6 +65,7 @@ public:
INLINE AwtFrame* GetFrame() { return m_frame; }
virtual HWND GetOwnerHWnd();
virtual void RedrawMenuBar();
AwtMenuItem* GetItem(jobject target, long index);
int CountItem(jobject menuBar);
......
......@@ -626,7 +626,7 @@ void AwtMenuItem::SetLabel(LPCTSTR sb)
mii.dwTypeData = (LPTSTR)(*sb);
// find index by menu item id
int nMenuItemCount = ::GetMenuItemCount(hMenu);;
int nMenuItemCount = ::GetMenuItemCount(hMenu);
int idx;
for (idx = 0; (idx < nMenuItemCount); idx++) {
memset(&mii1, 0, sizeof(MENUITEMINFO));
......@@ -639,10 +639,7 @@ void AwtMenuItem::SetLabel(LPCTSTR sb)
::RemoveMenu(hMenu, idx, MF_BYPOSITION);
::InsertMenuItem(hMenu, idx, TRUE, &mii);
// Redraw menu bar if it was affected.
if (menu->GetMenuBar() == menu) {
::DrawMenuBar(menu->GetOwnerHWnd());
}
RedrawMenuBar();
}
void AwtMenuItem::Enable(BOOL isEnabled)
......@@ -658,10 +655,7 @@ void AwtMenuItem::Enable(BOOL isEnabled)
MF_BYCOMMAND | (isEnabled ? MF_ENABLED : MF_GRAYED))
!= 0xFFFFFFFF);
// Redraw menu bar if it was affected.
if (menu->GetMenuBar() == menu) {
::DrawMenuBar(menu->GetOwnerHWnd());
}
RedrawMenuBar();
}
void AwtMenuItem::SetState(BOOL isChecked)
......@@ -676,23 +670,31 @@ void AwtMenuItem::SetState(BOOL isChecked)
MF_BYCOMMAND | (isChecked ? MF_CHECKED : MF_UNCHECKED))
!= 0xFFFFFFFF);
// Redraw menu bar if it was affected.
if (menu->GetMenuBar() == menu) {
::DrawMenuBar(menu->GetOwnerHWnd());
RedrawMenuBar();
}
/**
* If the menu changes after the system has created the window,
* this function must be called to draw the changed menu bar.
*/
void AwtMenuItem::RedrawMenuBar() {
AwtMenu* menu = GetMenuContainer();
if (menu != NULL && menu->GetMenuBar() == menu){
menu->RedrawMenuBar();
}
}
void AwtMenuItem::UpdateContainerLayout() {
AwtMenu* menu = GetMenuContainer();
if (menu != NULL) {
DASSERT(menu != NULL && GetID() >= 0);
menu->UpdateLayout();
}
}
LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args)
{
switch( args->cmdId ) {
case MENUITEM_SETLABEL:
{
LPCTSTR sb = (LPCTSTR)args->param1;
DASSERT(!IsBadStringPtr(sb, 20));
this->SetLabel(sb);
}
break;
case MENUITEM_ENABLE:
{
BOOL isEnabled = (BOOL)args->param1;
......@@ -714,75 +716,98 @@ LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args)
return 0L;
}
void AwtMenuItem::_SetLabel(void *param)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
void AwtMenuItem::_SetLabel(void *param) {
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
SetLabelStruct *sls = (SetLabelStruct *)param;
jobject self = sls->menuitem;
jstring label = sls->label;
SetLabelStruct *sls = (SetLabelStruct *)param;
jobject self = sls->menuitem;
jstring label = sls->label;
int badAlloc = 0;
AwtMenuItem *m = NULL;
int badAlloc = 0;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
// if (::IsWindow(m->GetOwnerHWnd()))
{
// fix for bug 4251036 MenuItem setLabel(null/"") behaves differently
// under Win32 and Solaris
jstring empty = NULL;
if (JNU_IsNull(env, label))
{
empty = JNU_NewStringPlatform(env, TEXT(""));
}
LPCTSTR labelPtr;
if (empty != NULL)
{
labelPtr = JNU_GetStringPlatformChars(env, empty, 0);
}
else
{
labelPtr = JNU_GetStringPlatformChars(env, label, 0);
}
if (labelPtr == NULL)
{
badAlloc = 1;
}
else
{
ExecuteArgs args;
args.cmdId = MENUITEM_SETLABEL;
args.param1 = (LPARAM)labelPtr;
m->WinThreadExecProc(&args);
// fix for bug 4251036 MenuItem setLabel(null/"") behaves differently
// under Win32 and Solaris
jstring empty = NULL;
if (JNU_IsNull(env, label))
{
empty = JNU_NewStringPlatform(env, TEXT(""));
}
LPCTSTR labelPtr;
if (empty != NULL)
{
JNU_ReleaseStringPlatformChars(env, empty, labelPtr);
labelPtr = JNU_GetStringPlatformChars(env, empty, 0);
}
else
{
labelPtr = JNU_GetStringPlatformChars(env, label, 0);
}
if (labelPtr == NULL)
{
badAlloc = 1;
}
else
{
JNU_ReleaseStringPlatformChars(env, label, labelPtr);
DASSERT(!IsBadStringPtr(labelPtr, 20));
m->SetLabel(labelPtr);
if (empty != NULL)
{
JNU_ReleaseStringPlatformChars(env, empty, labelPtr);
}
else
{
JNU_ReleaseStringPlatformChars(env, label, labelPtr);
}
}
if (empty != NULL)
{
env->DeleteLocalRef(empty);
}
}
if (empty != NULL)
ret:
env->DeleteGlobalRef(self);
if (label != NULL)
{
env->DeleteLocalRef(empty);
env->DeleteGlobalRef(label);
}
}
ret:
env->DeleteGlobalRef(self);
if (label != NULL)
{
env->DeleteGlobalRef(label);
delete sls;
if (badAlloc)
{
throw std::bad_alloc();
}
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetLabel, param);
}
}
delete sls;
void AwtMenuItem::_UpdateLayout(void *param)
{
if (AwtToolkit::IsMainThread()) {
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
if (badAlloc)
{
throw std::bad_alloc();
jobject self = (jobject)param;
AwtMenuItem *m = NULL;
PDATA pData;
JNI_CHECK_PEER_GOTO(self, ret);
m = (AwtMenuItem *)pData;
m->UpdateContainerLayout();
ret:
env->DeleteGlobalRef(self);
} else {
AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_UpdateLayout, param);
}
}
......@@ -883,8 +908,8 @@ extern "C" {
/*
* Class: sun_awt_windows_WMenuItemPeer
* Method: _setLabel
* Signature: (Ljava/lang/String;)V
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WMenuItemPeer_initIDs(JNIEnv *env, jclass cls)
......@@ -925,6 +950,26 @@ Java_sun_awt_windows_WMenuItemPeer__1setLabel(JNIEnv *env, jobject self,
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WMenuItemPeer
* Method: _setFont
* Signature: (Ljava/awt/Font;)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WMenuItemPeer__1setFont(JNIEnv *env, jobject self, jobject)
{
TRY;
jobject selfGlobalRef = env->NewGlobalRef(self);
// Current implementation of AwtMenuItem get font attribute from the peer
// directly, so we ignore it here, but update current menu layout.
AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_UpdateLayout, selfGlobalRef);
// selfGlobalRef is deleted in _UpdateLayout
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WMenuItemPeer
* Method: create
......
......@@ -48,7 +48,6 @@ class AwtMenuItem : public AwtObject {
public:
// id's for methods executed on toolkit thread
enum {
MENUITEM_SETLABEL,
MENUITEM_ENABLE,
MENUITEM_SETSTATE,
MENUITEM_LAST
......@@ -78,7 +77,6 @@ public:
virtual LPCTSTR GetClassName();
void AwtMenuItem::LinkObjects(jobject peer);
static AwtMenuItem* Create(jobject self, jobject menu);
INLINE AwtMenu* GetMenuContainer() { return m_menuContainer; }
......@@ -148,6 +146,8 @@ public:
void SetLabel(LPCTSTR sb);
virtual void Enable(BOOL isEnabled);
virtual void UpdateContainerLayout();
virtual void RedrawMenuBar();
void SetState(BOOL isChecked);
/*
......@@ -163,6 +163,7 @@ public:
// invoked on Toolkit thread
static void _SetLabel(void *param);
static void _UpdateLayout(void *param);
protected:
AwtMenu* m_menuContainer; /* The menu object containing this item */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册