1 /* 2 * Copyright (c) 1996, 2016, 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_Toolkit.h" 27 #include "awt_Label.h" 28 #include "awt_Canvas.h" 29 #include "awt_Win32GraphicsDevice.h" 30 31 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. 32 */ 33 34 /***********************************************************************/ 35 // Struct for _SetText() method 36 struct SetTextStruct { 37 jobject label; 38 jstring text; 39 }; 40 // Struct for _SetAlignment() method 41 struct SetAlignmentStruct { 42 jobject label; 43 jint alignment; 44 }; 45 /************************************************************************ 46 * AwtLabel fields 47 */ 48 49 jfieldID AwtLabel::textID; 50 jfieldID AwtLabel::alignmentID; 51 52 53 /************************************************************************ 54 * AwtLabel methods 55 */ 56 57 AwtLabel::AwtLabel() { 58 m_needPaint = FALSE; 59 } 60 61 LPCTSTR AwtLabel::GetClassName() { 62 return TEXT("SunAwtLabel"); 63 } 64 65 /* Create a new AwtLabel object and window. */ 66 AwtLabel* AwtLabel::Create(jobject labelPeer, jobject parent) 67 { 68 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 69 70 jobject target = NULL; 71 AwtLabel* awtLabel = NULL; 72 73 try { 74 if (env->EnsureLocalCapacity(1) < 0) { 75 return NULL; 76 } 77 78 PDATA pData; 79 AwtCanvas* awtParent; 80 81 JNI_CHECK_PEER_GOTO(parent, done); 82 awtParent = (AwtCanvas*)pData; 83 84 target = env->GetObjectField(labelPeer, AwtObject::targetID); 85 JNI_CHECK_NULL_GOTO(target, "target", done); 86 87 awtLabel = new AwtLabel(); 88 89 { 90 DWORD style = WS_CHILD | WS_CLIPSIBLINGS; 91 92 DWORD exStyle = 0; 93 if (GetRTLReadingOrder()) 94 exStyle |= WS_EX_RTLREADING; 95 96 jint x = env->GetIntField(target, AwtComponent::xID); 97 jint y = env->GetIntField(target, AwtComponent::yID); 98 jint width = env->GetIntField(target, AwtComponent::widthID); 99 jint height = env->GetIntField(target, AwtComponent::heightID); 100 awtLabel->CreateHWnd(env, L"", style, exStyle, 101 x, y, width, height, 102 awtParent->GetHWnd(), 103 NULL, 104 ::GetSysColor(COLOR_WINDOWTEXT), 105 ::GetSysColor(COLOR_BTNFACE), 106 labelPeer); 107 } 108 } catch (...) { 109 env->DeleteLocalRef(target); 110 throw; 111 } 112 113 done: 114 env->DeleteLocalRef(target); 115 return awtLabel; 116 } 117 118 void AwtLabel::DoPaint(HDC hDC, RECT& r) 119 { 120 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 121 122 if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 && 123 m_peerObject != NULL && m_callbacksEnabled) { 124 125 if (env->EnsureLocalCapacity(3) < 0) 126 return; 127 long x,y; 128 SIZE size; 129 130 /* self is sun.awt.windows.WLabelPeer */ 131 132 jobject self = GetPeer(env); 133 DASSERT(self); 134 135 /* target is java.awt.Label */ 136 jobject target = env->GetObjectField(self, AwtObject::targetID); 137 jobject font = GET_FONT(target, self); 138 jstring text = (jstring)env->GetObjectField(target, AwtLabel::textID); 139 140 size = AwtFont::getMFStringSize(hDC, font, text); 141 ::SetTextColor(hDC, GetColor()); 142 /* Redraw whole label to eliminate display noise during resizing. */ 143 VERIFY(::GetClientRect(GetHWnd(), &r)); 144 VERIFY(::FillRect (hDC, &r, GetBackgroundBrush())); 145 y = (r.top + r.bottom - size.cy) / 2; 146 147 jint alignment = env->GetIntField(target, AwtLabel::alignmentID); 148 switch (alignment) { 149 case java_awt_Label_CENTER: 150 x = (r.left + r.right - size.cx) / 2; 151 break; 152 case java_awt_Label_RIGHT: 153 x = r.right - 2 - size.cx; 154 break; 155 case java_awt_Label_LEFT: 156 default: 157 x = r.left + 2; 158 break; 159 } 160 /* draw string */ 161 if (isEnabled()) { 162 AwtComponent::DrawWindowText(hDC, font, text, x, y); 163 } else { 164 AwtComponent::DrawGrayText(hDC, font, text, x, y); 165 } 166 DoCallback("handlePaint", "(IIII)V", 167 r.left, r.top, r.right-r.left, r.bottom-r.top); 168 env->DeleteLocalRef(target); 169 env->DeleteLocalRef(font); 170 env->DeleteLocalRef(text); 171 } 172 } 173 174 void AwtLabel::LazyPaint() 175 { 176 if (m_callbacksEnabled && m_needPaint ) { 177 ::InvalidateRect(GetHWnd(), NULL, TRUE); 178 m_needPaint = FALSE; 179 } 180 } 181 182 void AwtLabel::Enable(BOOL bEnable) 183 { 184 ::EnableWindow(GetHWnd(), bEnable); 185 // Fix for Bug #4038881 Labels don't enable and disable properly 186 // Fix for Bug #4096745 disable()/enable() make AWT components blink 187 // This fix is moved from awt_Component.cpp for Bug #4096745 188 ::InvalidateRect(GetHWnd(), NULL, FALSE); 189 CriticalSection::Lock l(GetLock()); 190 VerifyState(); 191 } 192 193 194 MsgRouting AwtLabel::WmEraseBkgnd(HDC hDC, BOOL& didErase) 195 { 196 RECT r; 197 198 ::GetClipBox(hDC, &r); 199 ::FillRect(hDC, &r, this->GetBackgroundBrush()); 200 didErase = TRUE; 201 return mrConsume; 202 } 203 204 MsgRouting AwtLabel::WmPaint(HDC) 205 { 206 PAINTSTRUCT ps; 207 HDC hDC = ::BeginPaint(GetHWnd(), &ps);/* the passed-in HDC is ignored. */ 208 DASSERT(hDC); 209 210 /* fix for 4408606 - incorrect color palette used in 256 color mode */ 211 212 int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); 213 AwtWin32GraphicsDevice::SelectPalette(hDC, screen); 214 215 RECT& r = ps.rcPaint; 216 if (!m_callbacksEnabled) { 217 m_needPaint = TRUE; 218 } else { 219 DoPaint(hDC, r); 220 } 221 VERIFY(::EndPaint(GetHWnd(), &ps)); 222 return mrConsume; 223 } 224 225 MsgRouting AwtLabel::WmPrintClient(HDC hDC, LPARAM) 226 { 227 RECT r; 228 229 // obtain valid DC from GDI stack 230 ::RestoreDC(hDC, -1); 231 232 ::GetClipBox(hDC, &r); 233 DoPaint(hDC, r); 234 return mrConsume; 235 } 236 237 void AwtLabel::_SetText(void *param) 238 { 239 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 240 241 SetTextStruct *sts = (SetTextStruct *)param; 242 jobject self = sts->label; 243 jstring text = sts->text; 244 245 AwtLabel *l = NULL; 246 247 PDATA pData; 248 JNI_CHECK_PEER_GOTO(self, ret); 249 l = (AwtLabel *)pData; 250 if (::IsWindow(l->GetHWnd())) 251 { 252 l->SetText(JavaStringBuffer(env, text)); 253 VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE)); 254 } 255 ret: 256 env->DeleteGlobalRef(self); 257 env->DeleteGlobalRef(text); 258 259 delete sts; 260 } 261 262 void AwtLabel::_SetAlignment(void *param) 263 { 264 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 265 266 SetAlignmentStruct *sas = (SetAlignmentStruct *)param; 267 jobject self = sas->label; 268 jint alignment = sas->alignment; 269 270 AwtLabel *l = NULL; 271 272 PDATA pData; 273 JNI_CHECK_PEER_GOTO(self, ret); 274 l = (AwtLabel *)pData; 275 if (::IsWindow(l->GetHWnd())) 276 { 277 /* 278 * alignment argument of multifont label is referred to in 279 * WmDrawItem method 280 */ 281 282 VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE)); 283 } 284 ret: 285 env->DeleteGlobalRef(self); 286 287 delete sas; 288 } 289 290 void AwtLabel::_LazyPaint(void *param) 291 { 292 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 293 294 jobject self = (jobject)param; 295 296 AwtLabel *l = NULL; 297 298 PDATA pData; 299 JNI_CHECK_PEER_GOTO(self, ret); 300 l = (AwtLabel *)pData; 301 if (::IsWindow(l->GetHWnd())) 302 { 303 l->LazyPaint(); 304 } 305 ret: 306 env->DeleteGlobalRef(self); 307 } 308 309 310 /************************************************************************ 311 * Label native methods 312 */ 313 314 extern "C" { 315 316 JNIEXPORT void JNICALL 317 Java_java_awt_Label_initIDs(JNIEnv *env, jclass cls) 318 { 319 TRY; 320 321 /* init field ids */ 322 AwtLabel::textID = env->GetFieldID(cls, "text", "Ljava/lang/String;"); 323 DASSERT(AwtLabel::textID != NULL); 324 CHECK_NULL(AwtLabel::textID); 325 326 AwtLabel::alignmentID = env->GetFieldID(cls, "alignment", "I"); 327 DASSERT(AwtLabel::alignmentID != NULL); 328 CHECK_NULL(AwtLabel::alignmentID); 329 330 CATCH_BAD_ALLOC; 331 } 332 333 } /* extern "C" */ 334 335 336 /************************************************************************ 337 * WLabelPeer native methods 338 */ 339 340 extern "C" { 341 342 /* 343 * Class: sun_awt_windows_WLabelPeer 344 * Method: setText 345 * Signature: (Ljava/lang/String;)V 346 */ 347 JNIEXPORT void JNICALL 348 Java_sun_awt_windows_WLabelPeer_setText(JNIEnv *env, jobject self, 349 jstring text) 350 { 351 TRY; 352 353 SetTextStruct *sts = new SetTextStruct; 354 sts->label = env->NewGlobalRef(self); 355 sts->text = (jstring)env->NewGlobalRef(text); 356 357 AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetText, sts); 358 // global refs and sts are deleted in _SetText() 359 360 CATCH_BAD_ALLOC; 361 } 362 363 /* 364 * Class: sun_awt_windows_WLabelPeer 365 * Method: setAlignment 366 * Signature: (I)V 367 */ 368 JNIEXPORT void JNICALL 369 Java_sun_awt_windows_WLabelPeer_setAlignment(JNIEnv *env, jobject self, 370 jint alignment) 371 { 372 TRY; 373 374 SetAlignmentStruct *sas = new SetAlignmentStruct; 375 sas->label = env->NewGlobalRef(self); 376 sas->alignment = alignment; 377 378 AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetAlignment, sas); 379 // global ref and sas are deleted in _SetAlignment 380 381 CATCH_BAD_ALLOC; 382 } 383 384 /* 385 * Class: sun_awt_windows_WLabelPeer 386 * Method: create 387 * Signature: (Lsun/awt/windows/WComponentPeer;)V 388 */ 389 JNIEXPORT void JNICALL 390 Java_sun_awt_windows_WLabelPeer_create(JNIEnv *env, jobject self, 391 jobject parent) 392 { 393 TRY; 394 395 AwtToolkit::CreateComponent(self, parent, 396 (AwtToolkit::ComponentFactory) 397 AwtLabel::Create); 398 399 CATCH_BAD_ALLOC; 400 } 401 402 /* 403 * Class: sun_awt_windows_WLabelPeer 404 * Method: lazyPaint 405 * Signature: ()V 406 */ 407 JNIEXPORT void JNICALL 408 Java_sun_awt_windows_WLabelPeer_lazyPaint(JNIEnv *env, jobject self) 409 { 410 TRY; 411 412 jobject selfGlobalRef = env->NewGlobalRef(self); 413 414 AwtToolkit::GetInstance().SyncCall(AwtLabel::_LazyPaint, (void *)selfGlobalRef); 415 // selfGlobalRef is deleted in _LazyPaint 416 417 CATCH_BAD_ALLOC; 418 } 419 420 } /* export "C" */