blob: 0a7d69a3013a447ab859e82cc91e5bc95765e958 [file] [log] [blame]
/*
* Copyright (c) 1996, 2005, 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_LEFT:
x = r.left + 2;
break;
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;
}
/* 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;");
AwtLabel::alignmentID = env->GetFieldID(cls, "alignment", "I");
DASSERT(AwtLabel::textID != NULL);
DASSERT(AwtLabel::alignmentID != NULL);
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" */