alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (awt_List.cpp)

This example Java source code file (awt_List.cpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awtlist, iswindow, jni_check_peer_goto, jni_version_1_2, jnicall, jnienv, jniexport, jnu_getenv, msgrouting, null, pdata, selectelementstruct, sendlistmessage, try

The awt_List.cpp Java example source code

/*
 * Copyright (c) 1996, 2009, 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_List.h"
#include "awt_Canvas.h"
#include "awt_Dimension.h"
#include "awt_Toolkit.h"
#include "awt_Window.h"

#include "ComCtl32Util.h"

/* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
 */

/***********************************************************************/
// struct for _AddItems() method
struct AddItemsStruct {
    jobject list;
    jobjectArray items;
    jint index;
    jint width;
};
// struct for _DelItems() method
struct DelItemsStruct {
    jobject list;
    jint start, end;
};
// struct for _IsSelected(), _Select(), _Deselect() and _MakeVisible() methods
struct SelectElementStruct {
    jobject list;
    jint index;
};
// struct for _SetMultipleSelections() method
struct SetMultipleSelectionsStruct {
    jobject list;
    jboolean on;
};
/************************************************************************
 * AwtList methods
 */

AwtList::AwtList() {
    isMultiSelect = FALSE;
    isWrapperPrint = FALSE;
}

AwtList::~AwtList()
{
}

LPCTSTR AwtList::GetClassName() {
    return TEXT("LISTBOX");
}

/* Create a new AwtList object and window.   */
AwtList* AwtList::Create(jobject peer, jobject parent)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject target = NULL;
    AwtList* c = 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, "null awtParent", done);

        /* target is Hjava_awt_List * */
        target = env->GetObjectField(peer, AwtObject::targetID);
        JNI_CHECK_NULL_GOTO(target, "null target", done);

        c = new AwtList();

        {

            /*
             * NOTE: WS_CLIPCHILDREN is excluded so that repaint requests
             * from Java will pass through the wrap to the native listbox.
             */
            DWORD wrapStyle = WS_CHILD | WS_CLIPSIBLINGS;
            DWORD wrapExStyle = 0;

            DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL |
                LBS_NOINTEGRALHEIGHT | LBS_NOTIFY | LBS_OWNERDRAWFIXED;
            DWORD exStyle = WS_EX_CLIENTEDGE;

            /*
             * NOTE: WS_VISIBLE is always set for the listbox. Listbox
             * visibility is controlled by toggling the wrap's WS_VISIBLE bit.
             */
            style |= WS_VISIBLE;

            if (GetRTL()) {
                exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
                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);

            c->CreateHWnd(env, L"", style, exStyle,
                          x, y, width, height,
                          awtParent->GetHWnd(),
                          NULL,
                          ::GetSysColor(COLOR_WINDOWTEXT),
                          ::GetSysColor(COLOR_WINDOW),
                          peer
                          );

            /* suppress inheriting awtParent's color. */
            c->m_backgroundColorSet = TRUE;
            c->UpdateBackground(env, target);
        }
    } catch (...) {
        env->DeleteLocalRef(target);
        throw;
    }

done:
    env->DeleteLocalRef(target);
    return c;
}

void AwtList::SetDragCapture(UINT flags)
{
    // don't want to interfere with other controls
    if (::GetCapture() == NULL) {
        ::SetCapture(GetListHandle());
    }
}

void AwtList::ReleaseDragCapture(UINT flags)
{
    if ((::GetCapture() == GetListHandle()) && ((flags & ALL_MK_BUTTONS) == 0)) {
        ::ReleaseCapture();
    }
}

void AwtList::Reshape(int x, int y, int w, int h)
{
    AwtComponent::Reshape(x, y, w, h);

/*
    HWND hList = GetListHandle();
    if (hList != NULL) {
        long flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS;
        /*
         * Fix for bug 4046446.
         * /
        SetWindowPos(hList, 0, 0, 0, w, h, flags);
    }
*/
}

//Netscape : Override the AwtComponent method so we can set the item height
//for each item in the list.  Modified by echawkes to avoid race condition.

void AwtList::SetFont(AwtFont* font)
{
    DASSERT(font != NULL);
    if (font->GetAscent() < 0)
    {
        AwtFont::SetupAscent(font);
    }
    HANDLE hFont = font->GetHFont();
    SendListMessage(WM_SETFONT, (WPARAM)hFont, MAKELPARAM(FALSE, 0));

    HDC hDC = ::GetDC(GetHWnd());

    TEXTMETRIC tm;
    VERIFY(::SelectObject(hDC, hFont) != NULL);
    VERIFY(::GetTextMetrics(hDC, &tm));

    ::ReleaseDC(GetHWnd(), hDC);

    long h = tm.tmHeight + tm.tmExternalLeading;
    // Listbox is LBS_OWNERDRAWFIXED so the items have the same height
    VERIFY(SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(h, 0)) != LB_ERR);
    VERIFY(::RedrawWindow(GetHWnd(), NULL, NULL, RDW_INVALIDATE |RDW_FRAME |RDW_ERASE));
}

void AwtList::SetMultiSelect(BOOL ms) {
    if (ms == isMultiSelect) {
        return;
    }

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    /* Copy current box's contents to string array */
    int nCount = GetCount();
    LPTSTR * strings = new LPTSTR[nCount];
    int i;

    for(i = 0; i < nCount; i++) {
        LRESULT len = SendListMessage(LB_GETTEXTLEN, i);
        LPTSTR text = NULL;
        try {
            text = new TCHAR[len + 1];
        } catch (std::bad_alloc&) {
            // free char * already allocated
            for (int j = 0; j < i; j++) {
                delete [] strings[j];
            }
            delete [] strings;
            throw;
        }

        VERIFY(SendListMessage(LB_GETTEXT, i, (LPARAM)text) != LB_ERR);
        strings[i] = text;
    }

    // index for selected item after multi-select mode change
    int toSelect = SendListMessage(LB_GETCURSEL);
    if (!isMultiSelect)
    {
        // MSDN: for single-select lists LB_GETCURSEL returns
        // index of selected item or LB_ERR if no item is selected
        if (toSelect == LB_ERR)
        {
            toSelect = -1;
        }
    }
    else
    {
        // MSDN: for multi-select lists LB_GETCURSEL returns index
        // of the focused item or 0 if no items are selected; if
        // some item has focus and is not selected then LB_GETCURSEL
        // return its index, so we need IsItemSelected too
        if ((toSelect == LB_ERR) ||
            (SendListMessage(LB_GETSELCOUNT) == 0) ||
            (IsItemSelected(toSelect) == 0))
        {
            toSelect = -1;
        }
    }

    isMultiSelect = ms;

    HWND parentHWnd = GetParent()->GetHWnd();

    /* Save old list box's attributes */
    RECT rect;
    GetWindowRect(GetListHandle(), &rect);
    MapWindowPoints(0, parentHWnd, (LPPOINT)&rect, 2);

    HANDLE font = (HANDLE)SendListMessage(WM_GETFONT);
    LRESULT itemHeight = SendListMessage(LB_GETITEMHEIGHT, 0);
    DWORD style = ::GetWindowLong(GetListHandle(), GWL_STYLE) | WS_VSCROLL | WS_HSCROLL;
    if (isMultiSelect) {
        style |= LBS_MULTIPLESEL;
    } else {
        style &= ~LBS_MULTIPLESEL;
    }
    DWORD exStyle = ::GetWindowLong(GetListHandle(), GWL_EXSTYLE);

    jobject peer = GetPeer(env);

    UnsubclassHWND();
    AwtToolkit::DestroyComponentHWND(m_hwnd);
    CreateHWnd(env, L"", style, exStyle,
               rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
               parentHWnd,
               NULL,
               ::GetSysColor(COLOR_WINDOWTEXT),
               ::GetSysColor(COLOR_WINDOW),
               peer);

    SendListMessage(WM_SETFONT, (WPARAM)font, (LPARAM)FALSE);
    SendListMessage(LB_SETITEMHEIGHT, 0, MAKELPARAM(itemHeight, 0));
    SendListMessage(LB_RESETCONTENT);
    for (i = 0; i < nCount; i++) {
        InsertString(i, strings[i]);
        delete [] strings[i];
    }
    delete[] strings;
    if (toSelect != -1) {
        Select(toSelect);
    }

    AdjustHorizontalScrollbar();
}

/*
 * There currently is no good place to cache java.awt.Dimension field
 * ids. If this method gets called a lot, one such place should be found.
 * -- br 07/18/97.
 */
jobject AwtList::PreferredItemSize(JNIEnv *env)
{
    jobject peer = GetPeer(env);
    jobject dimension = JNU_CallMethodByName(env, NULL, peer, "preferredSize",
                                             "(I)Ljava/awt/Dimension;",
                                             1).l;

    DASSERT(!safe_ExceptionOccurred(env));
    if (dimension == NULL) {
        return NULL;
    }
    /* This size is too big for each item height. */
    (env)->SetIntField(dimension, AwtDimension::heightID, GetFontHeight(env));

    return dimension;
}

// Every time something gets added to the list, we increase the max width
// of items that have ever been added.  If it surpasses the width of the
// listbox, we show the scrollbar.  When things get deleted, we shrink
// the scroll region back down and hide the scrollbar, if needed.
void AwtList::AdjustHorizontalScrollbar()
{
    // The border width is added to the horizontal extent to ensure that we
    // can view all of the text when we move the horz. scrollbar to the end.
    int  cxBorders = GetSystemMetrics( SM_CXBORDER ) * 2;
    RECT rect;
    VERIFY(::GetClientRect(GetListHandle(), &rect));
    LRESULT iHorzExt = SendListMessage(LB_GETHORIZONTALEXTENT, 0, 0L ) - cxBorders;
    if ( (m_nMaxWidth > rect.left)  // if strings wider than listbox
      || (iHorzExt != m_nMaxWidth) ) //   or scrollbar not needed anymore.
    {
        SendListMessage(LB_SETHORIZONTALEXTENT, m_nMaxWidth + cxBorders, 0L);
    }
}

// This function goes through all strings in the list to find the width,
// in pixels, of the longest string in the list.
void AwtList::UpdateMaxItemWidth()
{
    m_nMaxWidth = 0;

    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if (env->EnsureLocalCapacity(2) < 0)
        return;

    HDC hDC = ::GetDC(GetHWnd());

    jobject self = GetPeer(env);
    DASSERT(self);

    /* target is java.awt.List */
    jobject target = env->GetObjectField(self, AwtObject::targetID);
    jobject font = GET_FONT(target, self);

    int nCount = GetCount();
    for ( int i=0; i < nCount; i++ )
    {
        jstring jstr = GetItemString( env, target, i );
        SIZE size = AwtFont::getMFStringSize( hDC, font, jstr );
        if ( size.cx > m_nMaxWidth )
            m_nMaxWidth = size.cx;
        env->DeleteLocalRef( jstr );
    }

    // free up the shared DC and release local refs
    ::ReleaseDC(GetHWnd(), hDC);
    env->DeleteLocalRef( target );
    env->DeleteLocalRef( font );

    // Now adjust the horizontal scrollbar extent
    AdjustHorizontalScrollbar();
}

MsgRouting
AwtList::WmSize(UINT type, int w, int h)
{
    AdjustHorizontalScrollbar();
    return AwtComponent::WmSize(type, w, h);
}

MsgRouting
AwtList::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo)
{
    AwtComponent::DrawListItem((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), drawInfo);
    return mrConsume;
}

MsgRouting
AwtList::OwnerMeasureItem(UINT /*ctrlId*/, MEASUREITEMSTRUCT& measureInfo)
{
    AwtComponent::MeasureListItem((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), measureInfo);
    return mrConsume;
}

MsgRouting
AwtList::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
{
    if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
        retVal = HTCLIENT;
        return mrConsume;
    }
    return AwtComponent::WmNcHitTest(x, y, retVal);
}

MsgRouting
AwtList::WmMouseUp(UINT flags, int x, int y, int button)
{
    MsgRouting result = mrDoDefault;
    // if this list is in the modal blocked window, this message should be consumed,
    // however AwtComponent::WmMouseUp must be called anyway
    if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd())))) {
        result = mrConsume;
    } else {
        if (button == LEFT_BUTTON) {
            WmCommand(0, GetListHandle(), LBN_SELCHANGE);
        }
    }
    MsgRouting compResult = AwtComponent::WmMouseUp(flags, x, y, button);
    return (result == mrConsume) ? result : compResult;
}

MsgRouting
AwtList::WmMouseDown(UINT flags, int x, int y, int button)
{
    MsgRouting mrResult = AwtComponent::WmMouseDown(flags, x, y, button);

    if (::IsWindow(AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(GetHWnd()))))
    {
        return mrConsume;
    }

    /*
     * As we consume WM_LBUTONDOWN the list won't trigger ActionEvent by double click.
     * We trigger it ourselves. (see also 6240202)
     */
    int clickCount = GetClickCount();
    if (button == LEFT_BUTTON && clickCount >= 2 && clickCount % 2 == 0) {
        WmCommand(0, GetListHandle(), LBN_DBLCLK);
    }
    return mrResult;
}

MsgRouting
AwtList::WmCtlColor(HDC hDC, HWND hCtrl, UINT ctlColor, HBRUSH& retBrush)
{
    DASSERT(ctlColor == CTLCOLOR_LISTBOX);
    DASSERT(hCtrl == GetListHandle());
    ::SetBkColor(hDC, GetBackgroundColor());
    ::SetTextColor(hDC, GetColor());
    retBrush = GetBackgroundBrush();
    return mrConsume;
}

BOOL AwtList::IsFocusingMouseMessage(MSG *pMsg)
{
    return pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONDBLCLK;
}

MsgRouting AwtList::HandleEvent(MSG *msg, BOOL synthetic)
{
    if (IsFocusingMouseMessage(msg)) {
        LONG item = static_cast<LONG>(SendListMessage(LB_ITEMFROMPOINT, 0, msg->lParam));
        if (item != LB_ERR) {
            if (isMultiSelect) {
                if (IsItemSelected(item)) {
                    Deselect(item);
                } else {
                    Select(item);
                }
            } else {
                Select(item);
            }
        }
        delete msg;
        return mrConsume;
    }
    if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN) {
        WmNotify(LBN_DBLCLK);
    }
    return AwtComponent::HandleEvent(msg, synthetic);
}

// Fix for 4665745.
// Override WmPrint to catch when the list control (not wrapper) should
// operate WM_PRINT to be compatible with the "smooth scrolling" feature.
MsgRouting AwtList::WmPrint(HDC hDC, LPARAM flags)
{
    if (!isWrapperPrint &&
        (flags & PRF_CLIENT) &&
        (GetStyleEx() & WS_EX_CLIENTEDGE))
    {
        int nOriginalDC = ::SaveDC(hDC);
        DASSERT(nOriginalDC != 0);
        // Save a copy of the DC for WmPrintClient
        VERIFY(::SaveDC(hDC));
        DefWindowProc(WM_PRINT, (WPARAM) hDC,
            (flags & (PRF_CLIENT | PRF_CHECKVISIBLE | PRF_ERASEBKGND)));
        VERIFY(::RestoreDC(hDC, nOriginalDC));

        flags &= ~PRF_CLIENT;
    }

    return AwtComponent::WmPrint(hDC, flags);
}

MsgRouting
AwtList::WmNotify(UINT notifyCode)
{
    if (notifyCode == LBN_SELCHANGE || notifyCode == LBN_DBLCLK) {
        /* Fixed an asserion failure when clicking on an empty List. */
        int nCurrentSelection = SendListMessage(LB_GETCURSEL);
        if (nCurrentSelection != LB_ERR && GetCount() > 0) {
            if (notifyCode == LBN_SELCHANGE) {
                DoCallback("handleListChanged", "(I)V", nCurrentSelection);
            }
            else if (notifyCode == LBN_DBLCLK) {
                DoCallback("handleAction", "(IJI)V", nCurrentSelection,
                           TimeHelper::getMessageTimeUTC(),
                           (jint)AwtComponent::GetJavaModifiers());
            }
        }
    }
    return mrDoDefault;
}

BOOL AwtList::InheritsNativeMouseWheelBehavior() {return true;}

jint AwtList::_GetMaxWidth(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    jint result = 0;
    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList *)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        result = l->GetMaxWidth();
    }
ret:
    env->DeleteGlobalRef(self);

    return result;
}

void AwtList::_UpdateMaxItemWidth(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    jobject self = (jobject)param;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList *)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->UpdateMaxItemWidth();
    }
ret:
    env->DeleteGlobalRef(self);
}

void AwtList::_AddItems(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    AddItemsStruct *ais = (AddItemsStruct *)param;
    jobject self = ais->list;
    jobjectArray items = ais->items;
    jint index = ais->index;
    jint width = ais->width;

    int badAlloc = 0;
    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    JNI_CHECK_NULL_GOTO(items, "null items", ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        int itemCount = env->GetArrayLength(items);
        if (itemCount > 0)
        {
            AwtList* l = (AwtList*)pData;
            l->SendListMessage(WM_SETREDRAW, (WPARAM)FALSE, 0);
            for (jsize i=0; i < itemCount; i++)
            {
                LPTSTR itemPtr = NULL;
                jstring item = (jstring)env->GetObjectArrayElement(items, i);
                JNI_CHECK_NULL_GOTO(item, "null item", next_item);
                itemPtr = (LPTSTR)JNU_GetStringPlatformChars(env, item, 0);
                if (itemPtr == NULL)
                {
                    badAlloc = 1;
                }
                else
                {
                    l->InsertString(index+i, itemPtr);
                    JNU_ReleaseStringPlatformChars(env, item, itemPtr);
                }
                env->DeleteLocalRef(item);
next_item:
                ;
            }
            l->SendListMessage(WM_SETREDRAW, (WPARAM)TRUE, 0);
            l->InvalidateList(NULL, TRUE);
            l->CheckMaxWidth(width);
        }
    }
ret:
    env->DeleteGlobalRef(self);
    env->DeleteGlobalRef(items);

    delete ais;

    if (badAlloc)
    {
        throw std::bad_alloc();
    }
}

void AwtList::_DelItems(void *param)
{        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    DelItemsStruct *dis = (DelItemsStruct *)param;
    jobject self = dis->list;
    jint start = dis->start;
    jint end = dis->end;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        int count = l->GetCount();

        if (start == 0 && end == count)
        {
            l->SendListMessage(LB_RESETCONTENT);
        }
        else
        {
            for (int i = start; i <= end; i++)
            {
                l->SendListMessage(LB_DELETESTRING, start);
            }
        }

        l->UpdateMaxItemWidth();
    }
ret:
    env->DeleteGlobalRef(self);

    delete dis;
}

void AwtList::_Select(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SelectElementStruct *ses = (SelectElementStruct *)param;
    jobject self = ses->list;
    jint index = ses->index;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->Select(index);
    }
ret:
    env->DeleteGlobalRef(self);

    delete ses;
}

void AwtList::_Deselect(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SelectElementStruct *ses = (SelectElementStruct *)param;
    jobject self = ses->list;
    jint index = ses->index;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->Deselect(index);
    }
ret:
    env->DeleteGlobalRef(self);

    delete ses;
}

void AwtList::_MakeVisible(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SelectElementStruct *ses = (SelectElementStruct *)param;
    jobject self = ses->list;
    jint index = ses->index;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        l->SendListMessage(LB_SETTOPINDEX, index);
    }
ret:
    env->DeleteGlobalRef(self);

    delete ses;
}

jboolean AwtList::_IsSelected(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SelectElementStruct *ses = (SelectElementStruct *)param;
    jobject self = ses->list;
    jint index = ses->index;

    jboolean result = JNI_FALSE;
    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        result = l->IsItemSelected(index);
    }
ret:
    env->DeleteGlobalRef(self);

    delete ses;

    return result;
}

void AwtList::_SetMultipleSelections(void *param)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    SetMultipleSelectionsStruct *sms = (SetMultipleSelectionsStruct *)param;
    jobject self = sms->list;
    jboolean on = sms->on;

    AwtList *l = NULL;

    PDATA pData;
    JNI_CHECK_PEER_GOTO(self, ret);
    l = (AwtList*)pData;
    if (::IsWindow(l->GetHWnd()))
    {
        AwtToolkit::GetInstance().SendMessage(WM_AWT_LIST_SETMULTISELECT,
                                              (WPARAM)self, on);
    }
ret:
    env->DeleteGlobalRef(self);

    delete sms;
}

/************************************************************************
 * WListPeer native methods
 *
 * This class seems to have numerous bugs in it, but they are all bugs
 * which were present before conversion to JNI. -br.
 */

extern "C" {

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    getMaxWidth
 * Signature: ()I
 */
JNIEXPORT jint JNICALL
Java_sun_awt_windows_WListPeer_getMaxWidth(JNIEnv *env, jobject self)
{
    TRY;

    jobject selfGlobalRef = env->NewGlobalRef(self);

    return (jint)AwtToolkit::GetInstance().SyncCall(
        (void *(*)(void *))AwtList::_GetMaxWidth,
        (void *)selfGlobalRef);
    // selfGlobalRef is deleted in _GetMaxWidth

    CATCH_BAD_ALLOC_RET(0);
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    updateMaxItemWidth
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_updateMaxItemWidth(JNIEnv *env, jobject self)
{
    TRY;

    jobject selfGlobalRef = env->NewGlobalRef(self);

    AwtToolkit::GetInstance().SyncCall(AwtList::_UpdateMaxItemWidth,
        (void *)selfGlobalRef);
    // selfGlobalRef is deleted in _UpdateMaxItemWidth

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    addItems
 * Signature: ([Ljava/lang/String;II)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_addItems(JNIEnv *env, jobject self,
                                        jobjectArray items, jint index, jint width)
{
    TRY;

    AddItemsStruct *ais = new AddItemsStruct;
    ais->list = env->NewGlobalRef(self);
    ais->items = (jobjectArray)env->NewGlobalRef(items);
    ais->index = index;
    ais->width = width;

    AwtToolkit::GetInstance().SyncCall(AwtList::_AddItems, ais);
    // global refs and ais are deleted in _AddItems()

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    delItems
 * Signature: (II)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_delItems(JNIEnv *env, jobject self,
                                        jint start, jint end)
{
    TRY;

    DelItemsStruct *dis = new DelItemsStruct;
    dis->list = env->NewGlobalRef(self);
    dis->start = start;
    dis->end = end;

    AwtToolkit::GetInstance().SyncCall(AwtList::_DelItems, dis);
    // global ref and dis are deleted in _DelItems

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    select
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_select(JNIEnv *env, jobject self,
                                      jint pos)
{
    TRY;

    SelectElementStruct *ses = new SelectElementStruct;
    ses->list = env->NewGlobalRef(self);
    ses->index = pos;

    AwtToolkit::GetInstance().SyncCall(AwtList::_Select, ses);
    // global ref and ses are deleted in _Select

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    deselect
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_deselect(JNIEnv *env, jobject self,
                                        jint pos)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(self);

    SelectElementStruct *ses = new SelectElementStruct;
    ses->list = env->NewGlobalRef(self);
    ses->index = pos;

    AwtToolkit::GetInstance().SyncCall(AwtList::_Deselect, ses);
    // global ref and ses are deleted in _Deselect

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    makeVisible
 * Signature: (I)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_makeVisible(JNIEnv *env, jobject self,
                                           jint pos)
{
    TRY;

    SelectElementStruct *ses = new SelectElementStruct;
    ses->list = env->NewGlobalRef(self);
    ses->index = pos;

    AwtToolkit::GetInstance().SyncCall(AwtList::_MakeVisible, ses);
    // global ref and ses are deleted in _MakeVisible

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    setMultipleSelections
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_setMultipleSelections(JNIEnv *env, jobject self,
                                                     jboolean on)
{
    TRY;

    SetMultipleSelectionsStruct *sms = new SetMultipleSelectionsStruct;
    sms->list = env->NewGlobalRef(self);
    sms->on = on;

    AwtToolkit::GetInstance().SyncCall(AwtList::_SetMultipleSelections, sms);
    // global ref and sms are deleted in AwtList::_SetMultipleSelections

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    create
 * Signature: (Lsun/awt/windows/WComponentPeer;)V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_WListPeer_create(JNIEnv *env, jobject self,
                                      jobject parent)
{
    TRY;

    PDATA pData;
    JNI_CHECK_PEER_RETURN(parent);
    AwtToolkit::CreateComponent(self, parent,
                                (AwtToolkit::ComponentFactory)AwtList::Create);
    JNI_CHECK_PEER_CREATION_RETURN(self);

    CATCH_BAD_ALLOC;
}

/*
 * Class:     sun_awt_windows_WListPeer
 * Method:    isSelected
 * Signature: (I)Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_WListPeer_isSelected(JNIEnv *env, jobject self,
                                          jint index)
{
    TRY;

    SelectElementStruct *ses = new SelectElementStruct;
    ses->list = env->NewGlobalRef(self);
    ses->index = index;

    return (jboolean)AwtToolkit::GetInstance().SyncCall(
        (void *(*)(void *))AwtList::_IsSelected, ses);
    // global ref and ses are deleted in _IsSelected

    CATCH_BAD_ALLOC_RET(FALSE);
}

} /* extern "C" */

Other Java examples (source code examples)

Here is a short list of links related to this Java awt_List.cpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.