1 /*
   2  * Copyright (c) 1996, 2014, 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         VERIFY(::DrawFocusRect(hDC, &focusRect));
 294     }
 295     /*  erase focus rect */
 296     else if (!(drawInfo.itemState & ODS_FOCUS) &&
 297              (drawInfo.itemAction & ODA_FOCUS)) {
 298         VERIFY(::DrawFocusRect(hDC, &focusRect));
 299     }
 300 
 301     /*  Notify any subclasses */
 302     rect = drawInfo.rcItem;
 303     DoCallback("handlePaint", "(IIII)V", rect.left, rect.top,
 304                rect.right-rect.left, rect.bottom-rect.top);
 305 
 306     env->DeleteLocalRef(target);
 307     env->DeleteLocalRef(font);
 308     env->DeleteLocalRef(str);
 309     env->DeleteLocalRef(group);
 310 
 311     return mrConsume;
 312 }
 313 
 314 MsgRouting AwtCheckbox::WmPaint(HDC)
 315 {
 316     /*  Suppress peer notification, because it's handled in WmDrawItem. */
 317     return mrDoDefault;
 318 }
 319 
 320 BOOL AwtCheckbox::IsFocusingMouseMessage(MSG *pMsg) {
 321     return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP;
 322 }
 323 
 324 BOOL AwtCheckbox::IsFocusingKeyMessage(MSG *pMsg) {
 325     return (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP) &&
 326             pMsg->wParam == VK_SPACE;
 327 }
 328 
 329 MsgRouting AwtCheckbox::HandleEvent(MSG *msg, BOOL synthetic)
 330 {
 331     if (IsFocusingMouseMessage(msg)) {
 332         SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_LBUTTONDOWN ? TRUE : FALSE));
 333         delete msg;
 334         return mrConsume;
 335     }
 336     if (IsFocusingKeyMessage(msg)) {
 337         SendMessage(BM_SETSTATE, (WPARAM)(msg->message == WM_KEYDOWN ? TRUE : FALSE));
 338         if (msg->message == WM_KEYDOWN) {
 339             m_fLButtonDowned = TRUE;
 340         } else if (m_fLButtonDowned == TRUE) {
 341             WmNotify(BN_CLICKED);
 342             m_fLButtonDowned = TRUE;
 343         }
 344         delete msg;
 345         return mrConsume;
 346     }
 347     return AwtComponent::HandleEvent(msg, synthetic);
 348 }
 349 
 350 void AwtCheckbox::_SetLabel(void *param)
 351 {
 352     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 353 
 354     SetLabelStruct *sls = (SetLabelStruct *)param;
 355     jobject checkbox = sls->checkbox;
 356     jstring label = sls->label;
 357 
 358     int badAlloc = 0;
 359     AwtCheckbox *c = NULL;
 360 
 361     PDATA pData;
 362     JNI_CHECK_PEER_GOTO(checkbox, done);
 363 
 364     c = (AwtCheckbox *)pData;
 365     if (::IsWindow(c->GetHWnd()))
 366     {
 367         LPCTSTR labelStr = NULL;
 368 
 369         // By convension null label means empty string
 370         if (label == NULL)
 371         {
 372             labelStr = TEXT("");
 373         }
 374         else
 375         {
 376             labelStr = JNU_GetStringPlatformChars(env, label, JNI_FALSE);
 377         }
 378 
 379         if (labelStr == NULL)
 380         {
 381             badAlloc = 1;
 382         }
 383         else
 384         {
 385             c->SetText(labelStr);
 386             c->VerifyState();
 387             if (label != NULL) {
 388                 JNU_ReleaseStringPlatformChars(env, label, labelStr);
 389             }
 390         }
 391     }
 392 
 393 done:
 394     env->DeleteGlobalRef(checkbox);
 395     if (label != NULL)
 396     {
 397         env->DeleteGlobalRef(label);
 398     }
 399 
 400     delete sls;
 401 
 402     if (badAlloc) {
 403         throw std::bad_alloc();
 404     }
 405 }
 406 
 407 void AwtCheckbox::_SetCheckboxGroup(void *param)
 408 {
 409     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 410 
 411     jobject *jos = (jobject *)param;
 412     jobject checkbox = jos[0];
 413     jobject group = jos[1];
 414 
 415     AwtCheckbox *c = NULL;
 416 
 417     PDATA pData;
 418     JNI_CHECK_PEER_GOTO(checkbox, done);
 419 
 420     c = (AwtCheckbox *)pData;
 421     if (::IsWindow(c->GetHWnd()))
 422     {
 423 /*
 424 #ifdef DEBUG
 425         if (group != NULL) {
 426             DASSERT(IsInstanceOf((HObject*)group, "java/awt/CheckboxGroup"));
 427         }
 428 #endif
 429 */
 430         long style = c->GetStyle();
 431         if (group == NULL) {
 432             style = style & ~BS_AUTORADIOBUTTON;
 433             style = style | BS_AUTOCHECKBOX;
 434         } else {
 435             style = style & ~BS_AUTOCHECKBOX;
 436             style = style | BS_AUTORADIOBUTTON;
 437         }
 438         c->SetStyle(style);
 439         c->SendMessage(BM_SETSTYLE, (WPARAM)BS_OWNERDRAW, (LPARAM)TRUE);
 440         c->VerifyState();
 441     }
 442 
 443 done:
 444     env->DeleteGlobalRef(checkbox);
 445     if (group != NULL) {
 446       env->DeleteGlobalRef(group);
 447     }
 448 
 449     delete[] jos;
 450 }
 451 
 452 void AwtCheckbox::_SetState(void *param)
 453 {
 454     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 455 
 456     SetStateStruct *sss = (SetStateStruct *)param;
 457     jobject checkbox = sss->checkbox;
 458     jboolean state = sss->state;
 459 
 460     AwtCheckbox *c = NULL;
 461 
 462     PDATA pData;
 463     JNI_CHECK_PEER_GOTO(checkbox, done);
 464 
 465     c = (AwtCheckbox *)pData;
 466     if (::IsWindow(c->GetHWnd()))
 467     {
 468         /*
 469          * when multifont and group checkbox receive setState native
 470          * method, it must be redraw to display correct check mark
 471          */
 472         jobject target = env->GetObjectField(checkbox, AwtObject::targetID);
 473         jobject group = env->GetObjectField(target, AwtCheckbox::groupID);
 474         HWND hWnd = c->GetHWnd();
 475         if (group != NULL) {
 476             RECT rect;
 477             VERIFY(::GetWindowRect(hWnd, &rect));
 478             VERIFY(::ScreenToClient(hWnd, (LPPOINT)&rect));
 479             VERIFY(::ScreenToClient(hWnd, ((LPPOINT)&rect) + 1));
 480             VERIFY(::InvalidateRect(hWnd, &rect,TRUE));
 481             VERIFY(::UpdateWindow(hWnd));
 482         } else {
 483             c->SendMessage(BM_SETCHECK, (WPARAM)(state ? BST_CHECKED : BST_UNCHECKED));
 484             VERIFY(::InvalidateRect(hWnd, NULL, FALSE));
 485         }
 486         c->VerifyState();
 487         env->DeleteLocalRef(target);
 488         env->DeleteLocalRef(group);
 489     }
 490 
 491 done:
 492     env->DeleteGlobalRef(checkbox);
 493 
 494     delete sss;
 495 }
 496 
 497 #ifdef DEBUG
 498 void AwtCheckbox::VerifyState()
 499 {
 500     if (AwtToolkit::GetInstance().VerifyComponents() == FALSE) {
 501         return;
 502     }
 503 
 504     if (m_callbacksEnabled == FALSE) {
 505         /*  Component is not fully setup yet. */
 506         return;
 507     }
 508 
 509     AwtComponent::VerifyState();
 510     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 511 
 512     if (env->EnsureLocalCapacity(2) < 0) {
 513         return;
 514     }
 515 
 516     jobject target = GetTarget(env);
 517 
 518     /*  Check button style */
 519     DWORD style = ::GetWindowLong(GetHWnd(), GWL_STYLE);
 520     DASSERT(style & BS_OWNERDRAW);
 521 
 522     /*  Check label */
 523     int len = ::GetWindowTextLength(GetHWnd());
 524     LPTSTR peerStr;
 525     try {
 526         peerStr = new TCHAR[len+1];
 527     } catch (std::bad_alloc&) {
 528         env->DeleteLocalRef(target);
 529         throw;
 530     }
 531 
 532     GetText(peerStr, len+1);
 533     jstring label = (jstring)env->GetObjectField(target, AwtCheckbox::labelID);
 534     DASSERT(_tcscmp(peerStr, JavaStringBuffer(env, label)) == 0);
 535     delete [] peerStr;
 536 
 537     env->DeleteLocalRef(target);
 538     env->DeleteLocalRef(label);
 539 }
 540 #endif
 541 
 542 
 543 /************************************************************************
 544  * Checkbox native methods
 545  */
 546 
 547 extern "C" {
 548 
 549 /*
 550  * Class:     sun_awt_windows_WButtonPeer
 551  * Method:    initIDs
 552  * Signature: ()V
 553  */
 554 JNIEXPORT void JNICALL
 555 Java_java_awt_Checkbox_initIDs(JNIEnv *env, jclass cls)
 556 {
 557     TRY;
 558 
 559     AwtCheckbox::labelID =
 560       env->GetFieldID(cls, "label", "Ljava/lang/String;");
 561     DASSERT(AwtCheckbox::labelID != NULL);
 562     CHECK_NULL(AwtCheckbox::labelID);
 563 
 564     AwtCheckbox::groupID =
 565       env->GetFieldID(cls, "group", "Ljava/awt/CheckboxGroup;");
 566     DASSERT(AwtCheckbox::groupID != NULL);
 567     CHECK_NULL(AwtCheckbox::groupID);
 568 
 569     AwtCheckbox::stateID = env->GetFieldID(cls, "state", "Z");
 570     DASSERT(AwtCheckbox::stateID != NULL);
 571 
 572     CATCH_BAD_ALLOC;
 573 }
 574 
 575 } /* extern "C" */
 576 
 577 
 578 /************************************************************************
 579  * WCheckboxPeer native methods
 580  */
 581 
 582 extern "C" {
 583 
 584 /*
 585  * Class:     sun_awt_windows_WCheckboxPeer
 586  * Method:    getCheckMarkSize
 587  * Signature: ()I
 588  */
 589 JNIEXPORT jint JNICALL
 590 Java_sun_awt_windows_WCheckboxPeer_getCheckMarkSize(JNIEnv *env,
 591                                                           jclass cls)
 592 {
 593     return (jint)AwtCheckbox::GetCheckSize();
 594 }
 595 
 596 /*
 597  * Class:     sun_awt_windows_WCheckboxPeer
 598  * Method:    setState
 599  * Signature: (Z)V
 600  */
 601 JNIEXPORT void JNICALL
 602 Java_sun_awt_windows_WCheckboxPeer_setState(JNIEnv *env, jobject self,
 603                                             jboolean state)
 604 {
 605     TRY;
 606 
 607     SetStateStruct *sss = new SetStateStruct;
 608     sss->checkbox = env->NewGlobalRef(self);
 609     sss->state = state;
 610 
 611     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetState, sss);
 612     // global refs and sss are deleted in _SetState()
 613 
 614     CATCH_BAD_ALLOC;
 615 }
 616 
 617 /*
 618  * Class:     sun_awt_windows_WCheckboxPeer
 619  * Method:    setCheckboxGroup
 620  * Signature: (Ljava/awt/CheckboxGroup;)V
 621  */
 622 JNIEXPORT void JNICALL
 623 Java_sun_awt_windows_WCheckboxPeer_setCheckboxGroup(JNIEnv *env, jobject self,
 624                                                     jobject group)
 625 {
 626     TRY;
 627 
 628     jobject *jos = new jobject[2];
 629     jos[0] = env->NewGlobalRef(self);
 630     jos[1] = env->NewGlobalRef(group);
 631 
 632     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetCheckboxGroup, jos);
 633     // global refs and jos are deleted in _SetLabel()
 634 
 635     CATCH_BAD_ALLOC;
 636 }
 637 
 638 /*
 639  * Class:     sun_awt_windows_WCheckboxPeer
 640  * Method:    setLabel
 641  * Signature: (Ljava/lang/String;)V
 642  */
 643 JNIEXPORT void JNICALL
 644 Java_sun_awt_windows_WCheckboxPeer_setLabel(JNIEnv *env, jobject self,
 645                                             jstring label)
 646 {
 647     TRY;
 648 
 649     SetLabelStruct *sls = new SetLabelStruct;
 650     sls->checkbox = env->NewGlobalRef(self);
 651     sls->label = (label != NULL) ? (jstring)env->NewGlobalRef(label) : NULL;
 652 
 653     AwtToolkit::GetInstance().SyncCall(AwtCheckbox::_SetLabel, sls);
 654     // global refs and sls are deleted in _SetLabel()
 655 
 656     CATCH_BAD_ALLOC;
 657 }
 658 
 659 /*
 660  * Class:     sun_awt_windows_WCheckboxPeer
 661  * Method:    create
 662  * Signature: (Lsun/awt/windows/WComponentPeer;)V
 663  */
 664 JNIEXPORT void JNICALL
 665 Java_sun_awt_windows_WCheckboxPeer_create(JNIEnv *env, jobject self,
 666                                           jobject parent)
 667 {
 668     TRY;
 669 
 670     PDATA pData;
 671     JNI_CHECK_PEER_RETURN(parent);
 672     AwtToolkit::CreateComponent(self, parent,
 673                                 (AwtToolkit::ComponentFactory)
 674                                 AwtCheckbox::Create);
 675     JNI_CHECK_PEER_CREATION_RETURN(self);
 676 
 677 #ifdef DEBUG
 678     ((AwtComponent*)JNI_GET_PDATA(self))->VerifyState();
 679 #endif
 680 
 681     CATCH_BAD_ALLOC;
 682 }
 683 
 684 } /* extern "C" */