| /* |
| * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include "awt_Toolkit.h" |
| #include "awt_Label.h" |
| #include "awt_Canvas.h" |
| #include "awt_Win32GraphicsDevice.h" |
| |
| /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code. |
| */ |
| |
| /***********************************************************************/ |
| // Struct for _SetText() method |
| struct SetTextStruct { |
| jobject label; |
| jstring text; |
| }; |
| // Struct for _SetAlignment() method |
| struct SetAlignmentStruct { |
| jobject label; |
| jint alignment; |
| }; |
| /************************************************************************ |
| * AwtLabel fields |
| */ |
| |
| jfieldID AwtLabel::textID; |
| jfieldID AwtLabel::alignmentID; |
| |
| |
| /************************************************************************ |
| * AwtLabel methods |
| */ |
| |
| AwtLabel::AwtLabel() { |
| m_needPaint = FALSE; |
| } |
| |
| LPCTSTR AwtLabel::GetClassName() { |
| return TEXT("SunAwtLabel"); |
| } |
| |
| /* Create a new AwtLabel object and window. */ |
| AwtLabel* AwtLabel::Create(jobject labelPeer, jobject parent) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject target = NULL; |
| AwtLabel* awtLabel = NULL; |
| |
| try { |
| if (env->EnsureLocalCapacity(1) < 0) { |
| return NULL; |
| } |
| |
| PDATA pData; |
| AwtCanvas* awtParent; |
| |
| JNI_CHECK_PEER_GOTO(parent, done); |
| awtParent = (AwtCanvas*)pData; |
| JNI_CHECK_NULL_GOTO(awtParent, "awtParent", done); |
| target = env->GetObjectField(labelPeer, AwtObject::targetID); |
| JNI_CHECK_NULL_GOTO(target, "target", done); |
| |
| awtLabel = new AwtLabel(); |
| |
| { |
| DWORD style = WS_CHILD | WS_CLIPSIBLINGS; |
| |
| DWORD exStyle = 0; |
| if (GetRTLReadingOrder()) |
| exStyle |= WS_EX_RTLREADING; |
| |
| jint x = env->GetIntField(target, AwtComponent::xID); |
| jint y = env->GetIntField(target, AwtComponent::yID); |
| jint width = env->GetIntField(target, AwtComponent::widthID); |
| jint height = env->GetIntField(target, AwtComponent::heightID); |
| awtLabel->CreateHWnd(env, L"", style, exStyle, |
| x, y, width, height, |
| awtParent->GetHWnd(), |
| NULL, |
| ::GetSysColor(COLOR_WINDOWTEXT), |
| ::GetSysColor(COLOR_BTNFACE), |
| labelPeer); |
| } |
| } catch (...) { |
| env->DeleteLocalRef(target); |
| throw; |
| } |
| |
| done: |
| env->DeleteLocalRef(target); |
| return awtLabel; |
| } |
| |
| void AwtLabel::DoPaint(HDC hDC, RECT& r) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| if ((r.right-r.left) > 0 && (r.bottom-r.top) > 0 && |
| m_peerObject != NULL && m_callbacksEnabled) { |
| |
| if (env->EnsureLocalCapacity(3) < 0) |
| return; |
| long x,y; |
| SIZE size; |
| |
| /* self is sun.awt.windows.WLabelPeer */ |
| |
| jobject self = GetPeer(env); |
| DASSERT(self); |
| |
| /* target is java.awt.Label */ |
| jobject target = env->GetObjectField(self, AwtObject::targetID); |
| jobject font = GET_FONT(target, self); |
| jstring text = (jstring)env->GetObjectField(target, AwtLabel::textID); |
| |
| size = AwtFont::getMFStringSize(hDC, font, text); |
| ::SetTextColor(hDC, GetColor()); |
| /* Redraw whole label to eliminate display noise during resizing. */ |
| VERIFY(::GetClientRect(GetHWnd(), &r)); |
| VERIFY(::FillRect (hDC, &r, GetBackgroundBrush())); |
| y = (r.top + r.bottom - size.cy) / 2; |
| |
| jint alignment = env->GetIntField(target, AwtLabel::alignmentID); |
| switch (alignment) { |
| case java_awt_Label_CENTER: |
| x = (r.left + r.right - size.cx) / 2; |
| break; |
| case java_awt_Label_RIGHT: |
| x = r.right - 2 - size.cx; |
| break; |
| case java_awt_Label_LEFT: |
| default: |
| x = r.left + 2; |
| break; |
| } |
| /* draw string */ |
| if (isEnabled()) { |
| AwtComponent::DrawWindowText(hDC, font, text, x, y); |
| } else { |
| AwtComponent::DrawGrayText(hDC, font, text, x, y); |
| } |
| DoCallback("handlePaint", "(IIII)V", |
| r.left, r.top, r.right-r.left, r.bottom-r.top); |
| env->DeleteLocalRef(target); |
| env->DeleteLocalRef(font); |
| env->DeleteLocalRef(text); |
| } |
| } |
| |
| void AwtLabel::LazyPaint() |
| { |
| if (m_callbacksEnabled && m_needPaint ) { |
| ::InvalidateRect(GetHWnd(), NULL, TRUE); |
| m_needPaint = FALSE; |
| } |
| } |
| |
| void AwtLabel::Enable(BOOL bEnable) |
| { |
| ::EnableWindow(GetHWnd(), bEnable); |
| // Fix for Bug #4038881 Labels don't enable and disable properly |
| // Fix for Bug #4096745 disable()/enable() make AWT components blink |
| // This fix is moved from awt_Component.cpp for Bug #4096745 |
| ::InvalidateRect(GetHWnd(), NULL, FALSE); |
| CriticalSection::Lock l(GetLock()); |
| VerifyState(); |
| } |
| |
| |
| MsgRouting AwtLabel::WmEraseBkgnd(HDC hDC, BOOL& didErase) |
| { |
| RECT r; |
| |
| ::GetClipBox(hDC, &r); |
| ::FillRect(hDC, &r, this->GetBackgroundBrush()); |
| didErase = TRUE; |
| return mrConsume; |
| } |
| |
| MsgRouting AwtLabel::WmPaint(HDC) |
| { |
| PAINTSTRUCT ps; |
| HDC hDC = ::BeginPaint(GetHWnd(), &ps);/* the passed-in HDC is ignored. */ |
| DASSERT(hDC); |
| |
| /* fix for 4408606 - incorrect color palette used in 256 color mode */ |
| |
| int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()); |
| AwtWin32GraphicsDevice::SelectPalette(hDC, screen); |
| |
| RECT& r = ps.rcPaint; |
| if (!m_callbacksEnabled) { |
| m_needPaint = TRUE; |
| } else { |
| DoPaint(hDC, r); |
| } |
| VERIFY(::EndPaint(GetHWnd(), &ps)); |
| return mrConsume; |
| } |
| |
| MsgRouting AwtLabel::WmPrintClient(HDC hDC, LPARAM) |
| { |
| RECT r; |
| |
| // obtain valid DC from GDI stack |
| ::RestoreDC(hDC, -1); |
| |
| ::GetClipBox(hDC, &r); |
| DoPaint(hDC, r); |
| return mrConsume; |
| } |
| |
| void AwtLabel::_SetText(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SetTextStruct *sts = (SetTextStruct *)param; |
| jobject self = sts->label; |
| jstring text = sts->text; |
| |
| AwtLabel *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtLabel *)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->SetText(JavaStringBuffer(env, text)); |
| VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE)); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| env->DeleteGlobalRef(text); |
| |
| delete sts; |
| } |
| |
| void AwtLabel::_SetAlignment(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| SetAlignmentStruct *sas = (SetAlignmentStruct *)param; |
| jobject self = sas->label; |
| jint alignment = sas->alignment; |
| |
| AwtLabel *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtLabel *)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| /* |
| * alignment argument of multifont label is referred to in |
| * WmDrawItem method |
| */ |
| |
| VERIFY(::InvalidateRect(l->GetHWnd(), NULL, TRUE)); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| |
| delete sas; |
| } |
| |
| void AwtLabel::_LazyPaint(void *param) |
| { |
| JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); |
| |
| jobject self = (jobject)param; |
| |
| AwtLabel *l = NULL; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_GOTO(self, ret); |
| l = (AwtLabel *)pData; |
| if (::IsWindow(l->GetHWnd())) |
| { |
| l->LazyPaint(); |
| } |
| ret: |
| env->DeleteGlobalRef(self); |
| } |
| |
| |
| /************************************************************************ |
| * Label native methods |
| */ |
| |
| extern "C" { |
| |
| JNIEXPORT void JNICALL |
| Java_java_awt_Label_initIDs(JNIEnv *env, jclass cls) |
| { |
| TRY; |
| |
| /* init field ids */ |
| AwtLabel::textID = env->GetFieldID(cls, "text", "Ljava/lang/String;"); |
| DASSERT(AwtLabel::textID != NULL); |
| CHECK_NULL(AwtLabel::textID); |
| |
| AwtLabel::alignmentID = env->GetFieldID(cls, "alignment", "I"); |
| DASSERT(AwtLabel::alignmentID != NULL); |
| CHECK_NULL(AwtLabel::alignmentID); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| } /* extern "C" */ |
| |
| |
| /************************************************************************ |
| * WLabelPeer native methods |
| */ |
| |
| extern "C" { |
| |
| /* |
| * Class: sun_awt_windows_WLabelPeer |
| * Method: setText |
| * Signature: (Ljava/lang/String;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WLabelPeer_setText(JNIEnv *env, jobject self, |
| jstring text) |
| { |
| TRY; |
| |
| SetTextStruct *sts = new SetTextStruct; |
| sts->label = env->NewGlobalRef(self); |
| sts->text = (jstring)env->NewGlobalRef(text); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetText, sts); |
| // global refs and sts are deleted in _SetText() |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WLabelPeer |
| * Method: setAlignment |
| * Signature: (I)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WLabelPeer_setAlignment(JNIEnv *env, jobject self, |
| jint alignment) |
| { |
| TRY; |
| |
| SetAlignmentStruct *sas = new SetAlignmentStruct; |
| sas->label = env->NewGlobalRef(self); |
| sas->alignment = alignment; |
| |
| AwtToolkit::GetInstance().SyncCall(AwtLabel::_SetAlignment, sas); |
| // global ref and sas are deleted in _SetAlignment |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WLabelPeer |
| * Method: create |
| * Signature: (Lsun/awt/windows/WComponentPeer;)V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WLabelPeer_create(JNIEnv *env, jobject self, |
| jobject parent) |
| { |
| TRY; |
| |
| PDATA pData; |
| JNI_CHECK_PEER_RETURN(parent); |
| AwtToolkit::CreateComponent(self, parent, |
| (AwtToolkit::ComponentFactory) |
| AwtLabel::Create); |
| JNI_CHECK_PEER_CREATION_RETURN(self); |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| /* |
| * Class: sun_awt_windows_WLabelPeer |
| * Method: lazyPaint |
| * Signature: ()V |
| */ |
| JNIEXPORT void JNICALL |
| Java_sun_awt_windows_WLabelPeer_lazyPaint(JNIEnv *env, jobject self) |
| { |
| TRY; |
| |
| jobject selfGlobalRef = env->NewGlobalRef(self); |
| |
| AwtToolkit::GetInstance().SyncCall(AwtLabel::_LazyPaint, (void *)selfGlobalRef); |
| // selfGlobalRef is deleted in _LazyPaint |
| |
| CATCH_BAD_ALLOC; |
| } |
| |
| } /* export "C" */ |