1 /*
   2  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "awt.h"
  27 #include "awt_Toolkit.h"
  28 #include "awt_Checkbox.h"
  29 #include "awt_Canvas.h"
  30 #include "awt_Window.h"
  31 
  32 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
  33  */
  34 
  35 /***********************************************************************/
  36 // Struct for _SetLabel() method
  37 struct SetLabelStruct {
  38     jobject checkbox;
  39     jstring label;
  40 };
  41 // Struct for _SetState() method
  42 struct SetStateStruct {
  43     jobject checkbox;
  44     jboolean state;
  45 };
  46 
  47 /************************************************************************
  48  * AwtCheckbox fields
  49  */
  50 
  51 /* java.awt.Checkbox field IDs */
  52 jfieldID AwtCheckbox::labelID;
  53 jfieldID AwtCheckbox::groupID;
  54 jfieldID AwtCheckbox::stateID;
  55 
  56 const int AwtCheckbox::CHECK_SIZE = 13;
  57 
  58 /************************************************************************
  59  * AwtCheckbox methods
  60  */
  61 
  62 AwtCheckbox::AwtCheckbox() {
  63 
  64     m_fLButtonDowned = FALSE;
  65 }
  66 
  67 LPCTSTR AwtCheckbox::GetClassName() {
  68     return TEXT("BUTTON");  /* System provided checkbox class (a type of button) */
  69 }
  70 
  71 AwtCheckbox* AwtCheckbox::Create(jobject peer, jobject parent)
  72 {
  73     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
  74 
  75     jstring label = NULL;
  76     jobject target = NULL;
  77     AwtCheckbox *checkbox = NULL;
  78 
  79     try {
  80         if (env->EnsureLocalCapacity(2) < 0) {
  81             return NULL;
  82         }
  83 
  84         AwtComponent* awtParent;
  85         JNI_CHECK_NULL_GOTO(parent, "null parent", done);
  86 
  87         awtParent = (AwtComponent*)JNI_GET_PDATA(parent);
  88         JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
  89 
  90         target = env->GetObjectField(peer, AwtObject::targetID);
  91         JNI_CHECK_NULL_GOTO(target, "null target", done);
  92 
  93         checkbox = new AwtCheckbox();
  94 
  95         {
  96             DWORD style = WS_CHILD | WS_CLIPSIBLINGS | BS_OWNERDRAW;
  97             LPCWSTR defaultLabelStr = L"";
  98             LPCWSTR labelStr = defaultLabelStr;
  99             DWORD exStyle = 0;
 100 
 101             if (GetRTL()) {
 102                 exStyle |= WS_EX_RIGHT;
 103                 if (GetRTLReadingOrder())
 104                     exStyle |= WS_EX_RTLREADING;
 105             }
 106 
 107             label = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
 108             if (label != NULL) {
 109                 labelStr = JNU_GetStringPlatformChars(env, label, 0);
 110             }
 111             if (labelStr != 0) {
 112                 jint x = env->GetIntField(target, AwtComponent::xID);
 113                 jint y = env->GetIntField(target, AwtComponent::yID);
 114                 jint width = env->GetIntField(target, AwtComponent::widthID);
 115                 jint height = env->GetIntField(target, AwtComponent::heightID);
 116                 checkbox->CreateHWnd(env, labelStr, style, exStyle,
 117                                      x, y, width, height,
 118                                      awtParent->GetHWnd(),
 119                                      reinterpret_cast<HMENU>(static_cast<INT_PTR>(
 120                          awtParent->CreateControlID())),
 121                                      ::GetSysColor(COLOR_WINDOWTEXT),
 122                                      ::GetSysColor(COLOR_BTNFACE),
 123                                      peer);
 124 
 125                 if (labelStr != defaultLabelStr) {
 126                     JNU_ReleaseStringPlatformChars(env, label, labelStr);
 127                 }
 128             } else {
 129                 throw std::bad_alloc();
 130             }
 131         }
 132     } catch (...) {
 133         env->DeleteLocalRef(label);
 134         env->DeleteLocalRef(target);
 135         throw;
 136     }
 137 
 138 done:
 139     env->DeleteLocalRef(label);
 140     env->DeleteLocalRef(target);
 141 
 142     return checkbox;
 143 }
 144 
 145 MsgRouting
 146 AwtCheckbox::WmMouseUp(UINT flags, int x, int y, int button)
 147 {
 148     MsgRouting mrResult = AwtComponent::WmMouseUp(flags, x, y, button);
 149 
 150     if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd()))))
 151     {
 152         return mrConsume;
 153     }
 154 
 155     POINT p = {x, y};
 156     RECT rect;
 157     ::GetClientRect(GetHWnd(), &rect);
 158 
 159     if (::PtInRect(&rect, p) && button == LEFT_BUTTON && m_fLButtonDowned) {
 160         WmNotify(BN_CLICKED);
 161     }
 162     m_fLButtonDowned = FALSE;
 163     return mrResult;
 164 }
 165 
 166 MsgRouting
 167 AwtCheckbox::WmMouseDown(UINT flags, int x, int y, int button)
 168 {
 169     m_fLButtonDowned = TRUE;
 170     return AwtComponent::WmMouseDown(flags, x, y, button);
 171 }
 172 
 173 MsgRouting
 174 AwtCheckbox::WmNotify(UINT notifyCode)
 175 {
 176     if (notifyCode == BN_CLICKED) {
 177         BOOL fChecked = !GetState();
 178         DoCallback("handleAction", "(Z)V", fChecked);
 179     }
 180     return mrDoDefault;
 181 }
 182 
 183 BOOL AwtCheckbox::GetState()
 184 {
 185     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 186 
 187     if (env->EnsureLocalCapacity(2) < 0) {
 188         return NULL;
 189     }
 190     jobject target = GetTarget(env);
 191     jboolean result = JNI_FALSE;
 192     if (target != NULL) {
 193         result = env->GetBooleanField(target, AwtCheckbox::stateID);
 194     }
 195 
 196     env->DeleteLocalRef(target);
 197 
 198     return (BOOL)result;
 199 }
 200 
 201 int AwtCheckbox::GetCheckSize()
 202 {
 203     /* using height of small icon for check mark size */
 204     return CHECK_SIZE;
 205 }
 206 
 207 MsgRouting
 208 AwtCheckbox::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo)
 209 {
 210     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 211 
 212     if (env->EnsureLocalCapacity(4) < 0) {
 213         return mrConsume;
 214     }
 215 
 216     jobject self = GetPeer(env);
 217     jobject target = env->GetObjectField(self, AwtObject::targetID);
 218 
 219     HDC hDC = drawInfo.hDC;
 220     RECT rect = drawInfo.rcItem;
 221     int checkSize;
 222     UINT nState;
 223     SIZE size;
 224 
 225     jobject font = GET_FONT(target, self);
 226     jstring str = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
 227     size = AwtFont::getMFStringSize(hDC, font, str);
 228 
 229     jobject group = env->GetObjectField(target, AwtCheckbox::groupID);
 230     if (group != NULL)
 231         nState = DFCS_BUTTONRADIO;
 232     else
 233         nState = DFCS_BUTTONCHECK;
 234 
 235     if (GetState())
 236         nState |= DFCS_CHECKED;
 237     else
 238         nState &= ~DFCS_CHECKED;
 239 
 240     if (drawInfo.itemState & ODS_SELECTED)
 241         nState |= DFCS_PUSHED;
 242 
 243     if (drawInfo.itemAction & ODA_DRAWENTIRE) {
 244         VERIFY(::FillRect (hDC, &rect, GetBackgroundBrush()));
 245     }
 246 
 247     /* draw check mark */
 248     checkSize = GetCheckSize();
 249     RECT boxRect;
 250 
 251     boxRect.left = (GetRTL()) ? rect.right - checkSize : rect.left;
 252     boxRect.top = (rect.bottom - rect.top - checkSize)/2;
 253     boxRect.right = boxRect.left + checkSize;
 254     boxRect.bottom = boxRect.top + checkSize;
 255     ::DrawFrameControl(hDC, &boxRect, DFC_BUTTON, nState);
 256 
 257     /*
 258      * draw string
 259      *
 260      * 4 is a heuristic number
 261      */
 262     rect.left = rect.left + checkSize + checkSize/4;
 263     if (drawInfo.itemAction & ODA_DRAWENTIRE) {
 264         BOOL bEnabled = isEnabled();
 265 
 266         int x = (GetRTL()) ? rect.right - (checkSize + checkSize / 4 + size.cx)
 267                            : rect.left;
 268         int y = (rect.top + rect.bottom - size.cy) / 2;
 269         if (bEnabled) {
 270             AwtComponent::DrawWindowText(hDC, font, str, x, y);
 271         } else {
 272             AwtComponent::DrawGrayText(hDC, font, str, x, y);
 273         }
 274     }
 275 
 276     /* Draw focus rect */
 277     RECT focusRect;
 278     const int margin = 2; /*  2 is a heuristic number */
 279 
 280     focusRect.left = (GetRTL()) ? rect.right - checkSize - checkSize / 4 -
 281                                       2 * margin - size.cx
 282                                 : rect.left - margin;
 283     focusRect.top = (rect.top+rect.bottom-size.cy)/2;
 284     focusRect.right = (GetRTL()) ? rect.right - checkSize - checkSize / 4 +
 285                                       margin
 286                                  : focusRect.left + size.cx + 2 * margin;
 287     focusRect.bottom = focusRect.top + size.cy;
 288 
 289     /*  draw focus rect */
 290     if ((drawInfo.itemState & ODS_FOCUS) &&
 291         ((drawInfo.itemAction & ODA_FOCUS)||
 292          (drawInfo.itemAction &ODA_DRAWENTIRE))) {
 293         if(::DrawFocusRect(hDC, &focusRect) == 0)
 294             VERIFY(::GetLastError() == 0);
 295     }
 296     /*  erase focus rect */
 297     else if (!(drawInfo.itemState & ODS_FOCUS) &&
 298              (drawInfo.itemAction & ODA_FOCUS)) {
 299         if(::DrawFocusRect(hDC, &focusRect) == 0)
 300             VERIFY(::GetLastError() == 0);
 301     }
 302 
 303     /*  Notify any subclasses */
 304     rect = drawInfo.rcItem;
 305     DoCallback("handlePaint", "(IIII)V", rect.left, rect.top,
 306                rect.right-rect.left, rect.bottom-rect.top);
 307 
 308     env->DeleteLocalRef(target);
 309     env->DeleteLocalRef(font);
 310     env->DeleteLocalRef(str);
 311     env->DeleteLocalRef(group);
 312 
 313     return mrConsume;
 314 }
 315 
 316 MsgRouting AwtCheckbox::WmPaint(HDC)
 317 {
 318     /*  Suppress peer notification, because it's handled in WmDrawItem. */
 319     return mrDoDefault;
 320 }
 321 
 322 BOOL AwtCheckbox::IsFocusingMouseMessage(MSG *pMsg) {
 323     return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP;
 324 }
 325 
 326 BOOL AwtCheckbox::IsFocusingKeyMessage(MSG *pMsg) {
 327     return (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) &&
 328             pMsg->wParam == VK_SPACE;
 329 }
 330 
 331 MsgRouting AwtCheckbox::HandleEvent(MSG *msg, BOOL synthetic)
 332 {
 333     if (IsFocusingMouseMessage(msg)) {
 334         SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_LBUTTONDOWN ? TRUE : FALSE));
 335         delete msg;
 336         return mrConsume;
 337     }
 338     if (IsFocusingKeyMessage(msg)) {
 339         SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_KEYDOWN ? TRUE : FALSE));
 340         if (msg->message == WM_KEYDOWN) {
 341             m_fLButtonDowned = TRUE;
 342         } else if (m_fLButtonDowned == TRUE) {
 343             WmNotify(BN_CLICKED);
 344             m_fLButtonDowned = TRUE;
 345         }
 346         delete msg;
 347         return mrConsume;
 348     }
 349     return AwtComponent::HandleEvent(msg, synthetic);
 350 }
 351 
 352 void AwtCheckbox::_SetLabel(void *param)
 353 {
 354     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 355 
 356     SetLabelStruct *sls = (SetLabelStruct *)param;
 357     jobject checkbox = sls->checkbox;
 358     jstring label = sls->label;
 359 
 360     int badAlloc = 0;
 361     AwtCheckbox *c = NULL;
 362 
 363     PDATA pData;
 364     JNI_CHECK_PEER_GOTO(checkbox, done);
 365 
 366     c = (AwtCheckbox *)pData;
 367     if (::IsWindow(c->GetHWnd()))
 368     {
 369         LPCTSTR labelStr = NULL;
 370 
 371         // By convension null label means empty string
 372         if (label == NULL)
 373         {
 374             labelStr = TEXT("");
 375         }
 376         else
 377         {
 378             labelStr = JNU_GetStringPlatformChars(env, label, JNI_FALSE);
 379         }
 380 
 381         if (labelStr == NULL)
 382         {
 383             badAlloc = 1;
 384         }
 385         else
 386         {
 387             c->SetText(labelStr);
 388             c->VerifyState();
 389             if (label != NULL) {
 390                 JNU_ReleaseStringPlatformChars(env, label, labelStr);
 391             }
 392         }
 393     }
 394 
 395 done:
 396     env->DeleteGlobalRef(checkbox);
 397     if (label != NULL)
 398     {
 399         env->DeleteGlobalRef(label);
 400     }
 401 
 402     delete sls;
 403 
 404     if (badAlloc) {
 405         throw std::bad_alloc();
 406     }
 407 }
 408 
 409 void AwtCheckbox::_SetCheckboxGroup(void *param)
 410 {
 411     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 412 
 413     jobject *jos = (jobject *)param;
 414     jobject checkbox = jos[0];
 415     jobject group = jos[1];
 416 
 417     AwtCheckbox *c = NULL;
 418 
 419     PDATA pData;
 420     JNI_CHECK_PEER_GOTO(checkbox, done);
 421 
 422     c = (AwtCheckbox *)pData;
 423     if (::IsWindow(c->GetHWnd()))
 424     {
 425 /*
 426 #ifdef DEBUG
 427         if (group != NULL) {
 428             DASSERT(IsInstanceOf((HObject*)group, "java/awt/CheckboxGroup"));
 429         }
 430 #endif
 431 */
 432         long style = c->GetStyle();
 433         if (group == NULL) {
 434             style = style & ~BS_AUTORADIOBUTTON;
 435             style = style | BS_AUTOCHECKBOX;
 436         } else {
 437             style = style & ~BS_AUTOCHECKBOX;
 438             style = style | BS_AUTORADIOBUTTON;
 439         }
 440         c->SetStyle(style);
 441         c->SendMessage(BM_SETSTYLE, (WPARAM)BS_OWNERDRAW, (LPARAM)TRUE);
 442         c->VerifyState();
 443     }
 444 
 445 done:
 446     env->DeleteGlobalRef(checkbox);
 447     if (group != NULL) {
 448       env->DeleteGlobalRef(group);
 449     }
 450 
 451     delete[] jos;
 452 }
 453 
 454 void AwtCheckbox::_SetState(void *param)
 455 {
 456     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 457 
 458     SetStateStruct *sss = (SetStateStruct *)param;
 459     jobject checkbox = sss->checkbox;
 460     jboolean state = sss->state;
 461 
 462     AwtCheckbox *c = NULL;
 463 
 464     PDATA pData;
 465     JNI_CHECK_PEER_GOTO(checkbox, done);
 466 
 467     c = (AwtCheckbox *)pData;
 468     if (::IsWindow(c->GetHWnd()))
 469     {
 470         /*
 471          * when multifont and group checkbox receive setState native
 472          * method, it must be redraw to display correct check mark
 473          */
 474         jobject target = env->GetObjectField(checkbox, AwtObject::targetID);
 475         jobject group = env->GetObjectField(target, AwtCheckbox::groupID);
 476         HWND hWnd = c->GetHWnd();
 477         if (group != NULL) {
 478             RECT rect;
 479             VERIFY(::GetWindowRect(hWnd, &rect));
 480             VERIFY(::ScreenToClient(hWnd, (LPPOINT)&rect));
 481             VERIFY(::ScreenToClient(hWnd, ((LPPOINT)&rect) + 1));
 482             VERIFY(::InvalidateRect(hWnd, &rect,TRUE));
 483             VERIFY(::UpdateWindow(hWnd));
 484         } else {
 485             c->SendMessage(BM_SETCHECK, (WPARAM)(state ? BST_CHECKED : BST_UNCHECKED));
 486             VERIFY(::InvalidateRect(hWnd, NULL, FALSE));
 487         }
 488         c->VerifyState();
 489         env->DeleteLocalRef(target);
 490         env->DeleteLocalRef(group);
 491     }
 492 
 493 done:
 494     env->DeleteGlobalRef(checkbox);
 495 
 496     delete sss;
 497 }
 498 
 499 #ifdef DEBUG
 500 void AwtCheckbox::VerifyState()
 501 {
 502     if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {
 503         return;
 504     }
 505 
 506     if (m_callbacksEnabled == FALSE) {
 507         /*  Component is not fully setup yet. */
 508         return;
 509     }
 510 
 511     AwtComponent::VerifyState();
 512     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 513 
 514     if (env->EnsureLocalCapacity(2) < 0) {
 515         return;
 516     }
 517 
 518     jobject target = GetTarget(env);
 519 
 520     /*  Check button style */
 521     DWORD style = ::GetWindowLong(GetHWnd(), GWL_STYLE);
 522     DASSERT(style & BS_OWNERDRAW);
 523 
 524     /*  Check label */
 525     int len = ::GetWindowTextLength(GetHWnd());
 526     LPTSTR peerStr;
 527     try {
 528         peerStr = new TCHAR[len+1];
 529     } catch (std::bad_alloc&) {
 530         env->DeleteLocalRef(target);
 531         throw;
 532     }
 533 
 534     GetText(peerStr, len+1);
 535     jstring label = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
 536     DASSERT(_tcscmp(peerStr, JavaStringBuffer(env, label)) == 0);
 537     delete [] peerStr;
 538 
 539     env->DeleteLocalRef(target);
 540     env->DeleteLocalRef(label);
 541 }
 542 #endif
 543 
 544 
 545 /************************************************************************
 546  * Checkbox native methods
 547  */
 548 
 549 extern "C" {
 550 
 551 /*
 552  * Class:     sun_awt_windows_WButtonPeer
 553  * Method:    initIDs
 554  * Signature: ()V
 555  */
 556 JNIEXPORT void JNICALL
 557 Java_java_awt_Checkbox_initIDs(JNIEnv *env, jclass cls)
 558 {
 559     TRY;
 560 
 561     AwtCheckbox::labelID =
 562       env->GetFieldID(cls, "label", "Ljava/lang/String;");
 563     DASSERT(AwtCheckbox::labelID != NULL);
 564     CHECK_NULL(AwtCheckbox::labelID);
 565 
 566     AwtCheckbox::groupID =
 567       env->GetFieldID(cls, "group", "Ljava/awt/CheckboxGroup;");
 568     DASSERT(AwtCheckbox::groupID != NULL);
 569     CHECK_NULL(AwtCheckbox::groupID);
 570 
 571     AwtCheckbox::stateID = env->GetFieldID(cls, "state", "Z");
 572     DASSERT(AwtCheckbox::stateID != NULL);
 573 
 574     CATCH_BAD_ALLOC;
 575 }
 576 
 577 } /* extern "C" */
 578 
 579 
 580 /************************************************************************
 581  * WCheckboxPeer native methods
 582  */
 583 
 584 extern "C" {
 585 
 586 /*
 587  * Class:     sun_awt_windows_WCheckboxPeer
 588  * Method:    getCheckMarkSize
 589  * Signature: ()I
 590  */
 591 JNIEXPORT jint JNICALL
 592 Java_sun_awt_windows_WCheckboxPeer_getCheckMarkSize(JNIEnv *env,
 593                                                           jclass cls)
 594 {
 595     return (jint)AwtCheckbox::GetCheckSize();
 596 }
 597 
 598 /*
 599  * Class:     sun_awt_windows_WCheckboxPeer
 600  * Method:    setState
 601  * Signature: (Z)V
 602  */
 603 JNIEXPORT void JNICALL
 604 Java_sun_awt_windows_WCheckboxPeer_setState(JNIEnv *env, jobject self,
 605                                             jboolean state)
 606 {
 607     TRY;
 608 
 609     SetStateStruct *sss = new SetStateStruct;
 610     sss->checkbox = env->NewGlobalRef(self);
 611     sss->state = state;
 612 
 613     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetState, sss);
 614     // global refs and sss are deleted in _SetState()
 615 
 616     CATCH_BAD_ALLOC;
 617 }
 618 
 619 /*
 620  * Class:     sun_awt_windows_WCheckboxPeer
 621  * Method:    setCheckboxGroup
 622  * Signature: (Ljava/awt/CheckboxGroup;)V
 623  */
 624 JNIEXPORT void JNICALL
 625 Java_sun_awt_windows_WCheckboxPeer_setCheckboxGroup(JNIEnv *env, jobject self,
 626                                                     jobject group)
 627 {
 628     TRY;
 629 
 630     jobject *jos = new jobject[2];
 631     jos[0] = env->NewGlobalRef(self);
 632     jos[1] = env->NewGlobalRef(group);
 633 
 634     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetCheckboxGroup, jos);
 635     // global refs and jos are deleted in _SetLabel()
 636 
 637     CATCH_BAD_ALLOC;
 638 }
 639 
 640 /*
 641  * Class:     sun_awt_windows_WCheckboxPeer
 642  * Method:    setLabel
 643  * Signature: (Ljava/lang/String;)V
 644  */
 645 JNIEXPORT void JNICALL
 646 Java_sun_awt_windows_WCheckboxPeer_setLabel(JNIEnv *env, jobject self,
 647                                             jstring label)
 648 {
 649     TRY;
 650 
 651     SetLabelStruct *sls = new SetLabelStruct;
 652     sls->checkbox = env->NewGlobalRef(self);
 653     sls->label = (label != NULL) ? (jstring)env->NewGlobalRef(label) : NULL;
 654 
 655     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetLabel, sls);
 656     // global refs and sls are deleted in _SetLabel()
 657 
 658     CATCH_BAD_ALLOC;
 659 }
 660 
 661 /*
 662  * Class:     sun_awt_windows_WCheckboxPeer
 663  * Method:    create
 664  * Signature: (Lsun/awt/windows/WComponentPeer;)V
 665  */
 666 JNIEXPORT void JNICALL
 667 Java_sun_awt_windows_WCheckboxPeer_create(JNIEnv *env, jobject self,
 668                                           jobject parent)
 669 {
 670     TRY;
 671 
 672     PDATA pData;
 673     JNI_CHECK_PEER_RETURN(parent);
 674     AwtToolkit::CreateComponent(self, parent,
 675                                 (AwtToolkit::ComponentFactory)
 676                                 AwtCheckbox::Create);
 677     JNI_CHECK_PEER_CREATION_RETURN(self);
 678 
 679 #ifdef DEBUG
 680     ((AwtComponent*)JNI_GET_PDATA(self))->VerifyState();
 681 #endif
 682 
 683     CATCH_BAD_ALLOC;
 684 }
 685 
 686 } /* extern "C" */