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
AwtLabel()57 AwtLabel::AwtLabel() {
58 m_needPaint = FALSE;
59 }
60
GetClassName()61 LPCTSTR AwtLabel::GetClassName() {
62 return TEXT("SunAwtLabel");
63 }
64
65 /* Create a new AwtLabel object and window. */
Create(jobject labelPeer,jobject parent)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
DoPaint(HDC hDC,RECT & r)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
LazyPaint()174 void AwtLabel::LazyPaint()
175 {
176 if (m_callbacksEnabled && m_needPaint ) {
177 ::InvalidateRect(GetHWnd(), NULL, TRUE);
178 m_needPaint = FALSE;
179 }
180 }
181
Enable(BOOL bEnable)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
WmEraseBkgnd(HDC hDC,BOOL & didErase)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
WmPaint(HDC)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
WmPrintClient(HDC hDC,LPARAM)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
_SetText(void * param)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
_SetAlignment(void * param)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
_LazyPaint(void * param)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
Java_java_awt_Label_initIDs(JNIEnv * env,jclass cls)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
Java_sun_awt_windows_WLabelPeer_setText(JNIEnv * env,jobject self,jstring text)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
Java_sun_awt_windows_WLabelPeer_setAlignment(JNIEnv * env,jobject self,jint alignment)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
Java_sun_awt_windows_WLabelPeer_create(JNIEnv * env,jobject self,jobject parent)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
Java_sun_awt_windows_WLabelPeer_lazyPaint(JNIEnv * env,jobject self)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" */
421